summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2006-03-25 16:20:27 +0000
committerBrian Paul <brian.paul@tungstengraphics.com>2006-03-25 16:20:27 +0000
commite1998baef8a7007fcb1ece4ff2ac440a715487c7 (patch)
tree8f6c2e3a9dd0ba9ea426288061aafb3fd6b4f6f3
parent3e980901b0882226d47cc4e733e7fb3757fa9c3b (diff)
Implement rendering to textures for any mipmap level, any cube face, any
3D texture slice. Added draw_offset to intel_region struct.
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c6
-rw-r--r--src/mesa/drivers/dri/i915/intel_blit.c3
-rw-r--r--src/mesa/drivers/dri/i915/intel_fbo.c81
-rw-r--r--src/mesa/drivers/dri/i915/intel_regions.h17
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().
*/