From e1998baef8a7007fcb1ece4ff2ac440a715487c7 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Sat, 25 Mar 2006 16:20:27 +0000 Subject: Implement rendering to textures for any mipmap level, any cube face, any 3D texture slice. Added draw_offset to intel_region struct. --- src/mesa/drivers/dri/i915/i915_vtbl.c | 6 ++- src/mesa/drivers/dri/i915/intel_blit.c | 3 +- src/mesa/drivers/dri/i915/intel_fbo.c | 81 ++++++++++++++++--------------- src/mesa/drivers/dri/i915/intel_regions.h | 17 ++++--- 4 files changed, 58 insertions(+), 49 deletions(-) diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c index be90612bc5..b48566b615 100644 --- a/src/mesa/drivers/dri/i915/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915/i915_vtbl.c @@ -247,12 +247,14 @@ static void i915_emit_state( struct intel_context *intel ) BEGIN_BATCH(I915_DEST_SETUP_SIZE+2, 0); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_CBUFADDR1]); - OUT_RELOC(state->draw_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0); + OUT_RELOC(state->draw_region->buffer, DRM_MM_TT|DRM_MM_WRITE, + state->draw_region->draw_offset); if (state->depth_region) { OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR0]); OUT_BATCH(state->Buffer[I915_DESTREG_DBUFADDR1]); - OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0); + OUT_RELOC(state->depth_region->buffer, DRM_MM_TT|DRM_MM_WRITE, + state->depth_region->draw_offset); } OUT_BATCH(state->Buffer[I915_DESTREG_DV0]); diff --git a/src/mesa/drivers/dri/i915/intel_blit.c b/src/mesa/drivers/dri/i915/intel_blit.c index 271a9eda1f..aefc3b3918 100644 --- a/src/mesa/drivers/dri/i915/intel_blit.c +++ b/src/mesa/drivers/dri/i915/intel_blit.c @@ -420,7 +420,8 @@ void intelClearWithBlit(GLcontext *ctx, GLbitfield mask, GLboolean all, OUT_BATCH( BR13 ); OUT_BATCH( (b.y1 << 16) | b.x1 ); OUT_BATCH( (b.y2 << 16) | b.x2 ); - OUT_RELOC( irb->region->buffer, DRM_MM_TT|DRM_MM_WRITE, 0 ); + OUT_RELOC( irb->region->buffer, DRM_MM_TT|DRM_MM_WRITE, + irb->region->draw_offset ); OUT_BATCH( clearVal ); ADVANCE_BATCH(); clearMask &= ~bufBit; /* turn off bit, for faster loop exit */ diff --git a/src/mesa/drivers/dri/i915/intel_fbo.c b/src/mesa/drivers/dri/i915/intel_fbo.c index 4cf41e1175..dc882dd4cb 100644 --- a/src/mesa/drivers/dri/i915/intel_fbo.c +++ b/src/mesa/drivers/dri/i915/intel_fbo.c @@ -470,8 +470,10 @@ intel_framebuffer_renderbuffer(GLcontext *ctx, GLenum attachment, struct gl_renderbuffer *rb) { + /* _mesa_debug(ctx, "Intel FramebufferRenderbuffer %u %u\n", fb->Name, rb ? rb->Name : 0); + */ intelFlush(ctx); @@ -488,7 +490,7 @@ intel_framebuffer_renderbuffer(GLcontext *ctx, static struct intel_renderbuffer * intel_wrap_texture(GLcontext *ctx, struct gl_texture_image *texImage) { - const GLuint name = ~0; /* XXX OK? */ + const GLuint name = ~0; /* not significant, but distinct for debugging */ struct intel_renderbuffer *irb; /* make an intel_renderbuffer to wrap the texture image */ @@ -553,11 +555,10 @@ intel_renderbuffer_texture(GLcontext *ctx, { struct gl_texture_image *newImage = att->Texture->Image[att->CubeMapFace][att->TextureLevel]; - struct intel_renderbuffer *irb = intel_renderbuffer(att->Renderbuffer); - struct intel_texture_image *intel_image; + GLuint imageOffset; (void) fb; @@ -565,33 +566,45 @@ intel_renderbuffer_texture(GLcontext *ctx, if (!irb) { irb = intel_wrap_texture(ctx, newImage); + if (irb) { + /* bind the wrapper to the attachment point */ + att->Renderbuffer = &irb->Base; + } + else { + /* fallback to software rendering */ + _mesa_problem(ctx, "Render to texture - unsupported hw format"); + _mesa_renderbuffer_texture(ctx, fb, att); + /* XXX FBO: Need to map the buffer (or in intelSpanRenderStart???) */ + return; + } } - if (irb) { - /* hardware rendering to texture */ - irb->Base.RefCount++; - - /* - _mesa_debug(ctx, "Begin render texture (tid %u) tex %u\n", - _glthread_GetID(), att->Texture->Name); - */ - - /* hook into the region */ - /* XXX mipmap level / cube face */ - intel_image = intel_texture_image(newImage); - if (irb->region != intel_image->mt->region) - intel_region_reference(&irb->region, intel_image->mt->region); - - att->Renderbuffer = &irb->Base; + /* + _mesa_debug(ctx, "Begin render texture tex=%u w=%d h=%d refcount=%d\n", + att->Texture->Name, newImage->Width, newImage->Height, + irb->Base.RefCount); + */ - intel_draw_buffer(ctx, fb); - } - else { - /* fallback to software rendering */ - _mesa_problem(ctx, "Render to texture - unsupported hw format"); - _mesa_renderbuffer_texture(ctx, fb, att); - /* XXX FBO: Need to map the buffer (or in intelSpanRenderStart???) */ + /* point the renderbufer's region to the texture image region */ + intel_image = intel_texture_image(newImage); + if (irb->region != intel_image->mt->region) + intel_region_reference(&irb->region, intel_image->mt->region); + + /* compute offset of the particular 2D image within the texture region */ + imageOffset = intel_miptree_image_offset(intel_image->mt, + att->CubeMapFace, + att->TextureLevel); + if (att->Texture->Target == GL_TEXTURE_3D) { + GLuint imgStride = intel_miptree_depth_image_stride(intel_image->mt, + att->CubeMapFace, + att->TextureLevel); + imageOffset += imgStride * att->Zoffset; } + /* store that offset in the region */ + intel_image->mt->region->draw_offset = imageOffset; + + /* update drawing region, etc */ + intel_draw_buffer(ctx, fb); } @@ -612,21 +625,11 @@ intel_finish_render_texture(GLcontext *ctx, */ if (irb) { - /* hardware */ + /* just release the region */ intel_region_release(intel, &irb->region); - - irb->Base.RefCount--; - - /* - _mesa_debug(ctx, "intel_finish_render_texture, refcount=%d\n", - irb->Base.RefCount); - */ - - /* should never hit zero here */ - assert(irb->Base.RefCount > 0); } - else { - /* software */ + else if (att->Renderbuffer) { + /* software fallback */ _mesa_finish_render_texture(ctx, att); /* XXX FBO: Need to unmap the buffer (or in intelSpanRenderStart???) */ } diff --git a/src/mesa/drivers/dri/i915/intel_regions.h b/src/mesa/drivers/dri/i915/intel_regions.h index 3b33bca775..c8173ae67f 100644 --- a/src/mesa/drivers/dri/i915/intel_regions.h +++ b/src/mesa/drivers/dri/i915/intel_regions.h @@ -41,15 +41,18 @@ struct intel_context; * - Blitter commands for copying 2D regions between buffers. (really???) */ struct intel_region { - GLuint buffer; /* buffer manager's buffer ID */ - GLuint refcount; - GLuint cpp; /* bytes per pixel */ - GLuint pitch; /* in pixels */ - GLuint height; /* in pixels */ - GLubyte *map; /* only non-NULL when region is actually mapped */ - GLuint map_refcount; + GLuint buffer; /**< buffer manager's buffer ID */ + GLuint refcount; /**< Reference count for region */ + GLuint cpp; /**< bytes per pixel */ + GLuint pitch; /**< in pixels */ + GLuint height; /**< in pixels */ + GLubyte *map; /**< only non-NULL when region is actually mapped */ + GLuint map_refcount; /**< Reference count for mapping */ + + GLuint draw_offset; /**< Offset of drawing address within the region */ }; + /* Allocate a refcounted region. Pointers to regions should only be * copied by calling intel_reference_region(). */ -- cgit v1.2.3