[Mesa-dev] [PATCH 1/4] intel: Move the draw_x/draw_y to the renderbuffer where it belongs.

Eric Anholt eric at anholt.net
Tue Jun 7 11:47:11 PDT 2011


It was originally located in the region because the tracking of
depth/color buffers was on the regions, and getting back to the irb
would have been tricky.  Now, we're keying off of the renderbuffer in
more places, which means we can move these fields where they belong.

This could fix potential rendering failure with a single texture
having multiple images attached to different renderbuffers across
shareCtx (as far as I can tell, this was the only failure we could
cause, since anything else should trigger intel_render_texture in
between, for example a BindFramebuffer).
---
 src/mesa/drivers/dri/i915/i830_vtbl.c             |   28 +++++++----
 src/mesa/drivers/dri/i915/i915_vtbl.c             |   28 +++++++----
 src/mesa/drivers/dri/i965/brw_misc_state.c        |    2 +-
 src/mesa/drivers/dri/i965/brw_wm_surface_state.c  |    2 +-
 src/mesa/drivers/dri/i965/gen7_misc_state.c       |   19 ++++----
 src/mesa/drivers/dri/i965/gen7_wm_surface_state.c |    2 +-
 src/mesa/drivers/dri/intel/intel_blit.c           |    8 ++--
 src/mesa/drivers/dri/intel/intel_fbo.c            |   53 +++++++++++++++++---
 src/mesa/drivers/dri/intel/intel_fbo.h            |    8 +++-
 src/mesa/drivers/dri/intel/intel_regions.c        |   35 --------------
 src/mesa/drivers/dri/intel/intel_regions.h        |    7 ---
 src/mesa/drivers/dri/intel/intel_tex_copy.c       |    2 +-
 12 files changed, 106 insertions(+), 88 deletions(-)

diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index 19f0807..08ea287 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -609,6 +609,8 @@ i830_set_draw_region(struct intel_context *intel,
    struct gl_context *ctx = &intel->ctx;
    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   struct gl_renderbuffer *drb;
+   struct intel_renderbuffer *idrb = NULL;
    GLuint value;
    struct i830_hw_state *state = &i830->state;
    uint32_t draw_x, draw_y;
@@ -649,6 +651,13 @@ i830_set_draw_region(struct intel_context *intel,
    }
    state->Buffer[I830_DESTREG_DV1] = value;
 
+   drb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+   if (!drb)
+      drb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
+
+   if (drb)
+      idrb = intel_renderbuffer(drb);
+
    /* We set up the drawing rectangle to be offset into the color
     * region's location in the miptree.  If it doesn't match with
     * depth's offsets, we can't render to it.
@@ -660,16 +669,15 @@ i830_set_draw_region(struct intel_context *intel,
     * can't do in general due to tiling)
     */
    FALLBACK(intel, I830_FALLBACK_DRAW_OFFSET,
-	    (depth_region && color_regions[0]) &&
-	    (depth_region->draw_x != color_regions[0]->draw_x ||
-	     depth_region->draw_y != color_regions[0]->draw_y));
-
-   if (color_regions[0]) {
-      draw_x = color_regions[0]->draw_x;
-      draw_y = color_regions[0]->draw_y;
-   } else if (depth_region) {
-      draw_x = depth_region->draw_x;
-      draw_y = depth_region->draw_y;
+	    idrb && irb && (idrb->draw_x != irb->draw_x ||
+			    idrb->draw_y != irb->draw_y));
+
+   if (irb) {
+      draw_x = irb->draw_x;
+      draw_y = irb->draw_y;
+   } else if (idrb) {
+      draw_x = idrb->draw_x;
+      draw_y = idrb->draw_y;
    } else {
       draw_x = 0;
       draw_y = 0;
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index 820feba..baff49b 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -561,6 +561,8 @@ i915_set_draw_region(struct intel_context *intel,
    struct gl_context *ctx = &intel->ctx;
    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
    struct intel_renderbuffer *irb = intel_renderbuffer(rb);
+   struct gl_renderbuffer *drb;
+   struct intel_renderbuffer *idrb = NULL;
    GLuint value;
    struct i915_hw_state *state = &i915->state;
    uint32_t draw_x, draw_y, draw_offset;
@@ -609,6 +611,13 @@ i915_set_draw_region(struct intel_context *intel,
    }
    state->Buffer[I915_DESTREG_DV1] = value;
 
+   drb = ctx->DrawBuffer->Attachment[BUFFER_DEPTH].Renderbuffer;
+   if (!drb)
+      drb = ctx->DrawBuffer->Attachment[BUFFER_STENCIL].Renderbuffer;
+
+   if (drb)
+      idrb = intel_renderbuffer(drb);
+
    /* We set up the drawing rectangle to be offset into the color
     * region's location in the miptree.  If it doesn't match with
     * depth's offsets, we can't render to it.
@@ -620,16 +629,15 @@ i915_set_draw_region(struct intel_context *intel,
     * can't do in general due to tiling)
     */
    FALLBACK(intel, I915_FALLBACK_DRAW_OFFSET,
-	    (depth_region && color_regions[0]) &&
-	    (depth_region->draw_x != color_regions[0]->draw_x ||
-	     depth_region->draw_y != color_regions[0]->draw_y));
-
-   if (color_regions[0]) {
-      draw_x = color_regions[0]->draw_x;
-      draw_y = color_regions[0]->draw_y;
-   } else if (depth_region) {
-      draw_x = depth_region->draw_x;
-      draw_y = depth_region->draw_y;
+	    idrb && irb && (idrb->draw_x != irb->draw_x ||
+			    idrb->draw_y != irb->draw_y));
+
+   if (irb) {
+      draw_x = irb->draw_x;
+      draw_y = irb->draw_y;
+   } else if (idrb) {
+      draw_x = idrb->draw_x;
+      draw_y = idrb->draw_y;
    } else {
       draw_x = 0;
       draw_y = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 3ec9009..31895da 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -264,7 +264,7 @@ static void emit_depthbuffer(struct brw_context *brw)
 	 return;
       }
 
-      offset = intel_region_tile_offsets(region, &tile_x, &tile_y);
+      offset = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
 
       assert(intel->gen < 6 || region->tiling == I915_TILING_Y);
 
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 6c1eba6..d9787eb 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -475,7 +475,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
 	      format << BRW_SURFACE_FORMAT_SHIFT);
 
    /* reloc */
-   surf[1] = (intel_region_tile_offsets(region, &tile_x, &tile_y) +
+   surf[1] = (intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y) +
 	      region->buffer->offset);
 
    surf[2] = ((rb->Width - 1) << BRW_SURFACE_WIDTH_SHIFT |
diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c
index a180b67..6a4f7cb 100644
--- a/src/mesa/drivers/dri/i965/gen7_misc_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c
@@ -36,16 +36,16 @@ gen7_depth_format(struct brw_context *brw)
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    struct intel_renderbuffer *drb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
    struct intel_renderbuffer *srb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
-   struct intel_region *region = NULL;
+   struct intel_renderbuffer *irb;
 
    if (drb)
-      region = drb->region;
+      irb = drb;
    else if (srb)
-      region = srb->region;
+      irb = srb;
    else
       return BRW_DEPTHFORMAT_D32_FLOAT;
 
-   switch (region->cpp) {
+   switch (irb->region->cpp) {
    case 2:
       return BRW_DEPTHFORMAT_D16_UNORM;
    case 4:
@@ -66,15 +66,15 @@ static void emit_depthbuffer(struct brw_context *brw)
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    struct intel_renderbuffer *drb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
    struct intel_renderbuffer *srb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
-   struct intel_region *region = NULL;
+   struct intel_renderbuffer *irb = NULL;
 
    /* _NEW_BUFFERS */
    if (drb)
-      region = drb->region;
+      irb = drb;
    else if (srb)
-      region = srb->region;
+      irb = srb;
 
-   if (region == NULL) {
+   if (irb == NULL) {
       BEGIN_BATCH(7);
       OUT_BATCH(GEN7_3DSTATE_DEPTH_BUFFER << 16 | (7 - 2));
       OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) |
@@ -86,9 +86,10 @@ static void emit_depthbuffer(struct brw_context *brw)
       OUT_BATCH(0);
       ADVANCE_BATCH();
    } else {
+      struct intel_region *region = irb->region;
       uint32_t tile_x, tile_y, offset;
 
-      offset = intel_region_tile_offsets(region, &tile_x, &tile_y);
+      offset = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
 
       assert(region->tiling == I915_TILING_Y);
 
diff --git a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
index d4eb550..7c0b9ef 100644
--- a/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
@@ -273,7 +273,7 @@ gen7_update_renderbuffer_surface(struct brw_context *brw,
 
    surf->ss0.surface_type = BRW_SURFACE_2D;
    /* reloc */
-   surf->ss1.base_addr = intel_region_tile_offsets(region, &tile_x, &tile_y);
+   surf->ss1.base_addr = intel_renderbuffer_tile_offsets(irb, &tile_x, &tile_y);
    surf->ss1.base_addr += region->buffer->offset; /* reloc */
 
    assert(brw->has_surface_tile_offset);
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index 5aac1f6..30be1b9 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -280,10 +280,10 @@ intelClearWithBlit(struct gl_context *ctx, GLbitfield mask)
       write_buffer = intel_region_buffer(intel, irb->region,
 					 all ? INTEL_WRITE_FULL :
 					 INTEL_WRITE_PART);
-      x1 = cx + irb->region->draw_x;
-      y1 = cy + irb->region->draw_y;
-      x2 = cx + cw + irb->region->draw_x;
-      y2 = cy + ch + irb->region->draw_y;
+      x1 = cx + irb->draw_x;
+      y1 = cy + irb->draw_y;
+      x2 = cx + cw + irb->draw_x;
+      y2 = cy + ch + irb->draw_y;
 
       pitch = irb->region->pitch;
       cpp = irb->region->cpp;
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 7434e0e..0a67caa 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -501,8 +501,9 @@ intel_wrap_texture(struct gl_context * ctx, struct gl_texture_image *texImage)
 }
 
 static void
-intel_set_draw_offset_for_image(struct intel_texture_image *intel_image,
-				int zoffset)
+intel_renderbuffer_set_draw_offset(struct intel_renderbuffer *irb,
+				   struct intel_texture_image *intel_image,
+				   int zoffset)
 {
    struct intel_mipmap_tree *mt = intel_image->mt;
    unsigned int dst_x, dst_y;
@@ -514,9 +515,45 @@ intel_set_draw_offset_for_image(struct intel_texture_image *intel_image,
 				  zoffset,
 				  &dst_x, &dst_y);
 
-   mt->region->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp;
-   mt->region->draw_x = dst_x;
-   mt->region->draw_y = dst_y;
+   irb->draw_offset = (dst_y * mt->region->pitch + dst_x) * mt->cpp;
+   irb->draw_x = dst_x;
+   irb->draw_y = dst_y;
+}
+
+/**
+ * Rendering to tiled buffers requires that the base address of the
+ * buffer be aligned to a page boundary.  We generally render to
+ * textures by pointing the surface at the mipmap image level, which
+ * may not be aligned to a tile boundary.
+ *
+ * This function returns an appropriately-aligned base offset
+ * according to the tiling restrictions, plus any required x/y offset
+ * from there.
+ */
+uint32_t
+intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
+				uint32_t *tile_x,
+				uint32_t *tile_y)
+{
+   int cpp = irb->region->cpp;
+   uint32_t pitch = irb->region->pitch * cpp;
+
+   if (irb->region->tiling == I915_TILING_NONE) {
+      *tile_x = 0;
+      *tile_y = 0;
+      return irb->draw_x * cpp + irb->draw_y * pitch;
+   } else if (irb->region->tiling == I915_TILING_X) {
+      *tile_x = irb->draw_x % (512 / cpp);
+      *tile_y = irb->draw_y % 8;
+      return ((irb->draw_y / 8) * (8 * pitch) +
+	      (irb->draw_x - *tile_x) / (512 / cpp) * 4096);
+   } else {
+      assert(irb->region->tiling == I915_TILING_Y);
+      *tile_x = irb->draw_x % (128 / cpp);
+      *tile_y = irb->draw_y % 32;
+      return ((irb->draw_y / 32) * (32 * pitch) +
+	      (irb->draw_x - *tile_x) / (128 / cpp) * 4096);
+   }
 }
 
 /**
@@ -572,12 +609,12 @@ intel_render_texture(struct gl_context * ctx,
        att->Texture->Name, newImage->Width, newImage->Height,
        irb->Base.RefCount);
 
-   intel_set_draw_offset_for_image(intel_image, att->Zoffset);
+   intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
    intel_image->used_as_render_target = GL_TRUE;
 
 #ifndef I915
    if (!brw_context(ctx)->has_surface_tile_offset &&
-       (intel_image->mt->region->draw_offset & 4095) != 0) {
+       (irb->draw_offset & 4095) != 0) {
       /* Original gen4 hardware couldn't draw to a non-tile-aligned
        * destination in a miptree unless you actually setup your
        * renderbuffer as a miptree and used the fragile
@@ -613,7 +650,7 @@ intel_render_texture(struct gl_context * ctx,
 
       intel_miptree_release(intel, &intel_image->mt);
       intel_image->mt = new_mt;
-      intel_set_draw_offset_for_image(intel_image, att->Zoffset);
+      intel_renderbuffer_set_draw_offset(irb, intel_image, att->Zoffset);
 
       intel_region_release(&irb->region);
       intel_region_reference(&irb->region, intel_image->mt->region);
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.h b/src/mesa/drivers/dri/intel/intel_fbo.h
index 212dd9a..739e762 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.h
+++ b/src/mesa/drivers/dri/intel/intel_fbo.h
@@ -44,6 +44,9 @@ struct intel_renderbuffer
 
    /** Only used by depth renderbuffers for which HiZ is enabled. */
    struct intel_region *hiz_region;
+
+   GLuint draw_offset; /**< Offset of drawing address within the region */
+   GLuint draw_x, draw_y; /**< Offset of drawing within the region */
 };
 
 
@@ -125,6 +128,10 @@ intel_fbo_init(struct intel_context *intel);
 extern void
 intel_flip_renderbuffers(struct gl_framebuffer *fb);
 
+uint32_t
+intel_renderbuffer_tile_offsets(struct intel_renderbuffer *irb,
+				uint32_t *tile_x,
+				uint32_t *tile_y);
 
 static INLINE struct intel_region *
 intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
@@ -136,5 +143,4 @@ intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
       return NULL;
 }
 
-
 #endif /* INTEL_FBO_H */
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 0253bbc..a4da1ce 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -524,38 +524,3 @@ intel_region_buffer(struct intel_context *intel,
 
    return region->buffer;
 }
-
-/**
- * Rendering to tiled buffers requires that the base address of the
- * buffer be aligned to a page boundary.  We generally render to
- * textures by pointing the surface at the mipmap image level, which
- * may not be aligned to a tile boundary.
- *
- * This function returns an appropriately-aligned base offset
- * according to the tiling restrictions, plus any required x/y offset
- * from there.
- */
-uint32_t
-intel_region_tile_offsets(struct intel_region *region,
-			  uint32_t *tile_x,
-			  uint32_t *tile_y)
-{
-   uint32_t pitch = region->pitch * region->cpp;
-
-   if (region->tiling == I915_TILING_NONE) {
-      *tile_x = 0;
-      *tile_y = 0;
-      return region->draw_x * region->cpp + region->draw_y * pitch;
-   } else if (region->tiling == I915_TILING_X) {
-      *tile_x = region->draw_x % (512 / region->cpp);
-      *tile_y = region->draw_y % 8;
-      return ((region->draw_y / 8) * (8 * pitch) +
-	      (region->draw_x - *tile_x) / (512 / region->cpp) * 4096);
-   } else {
-      assert(region->tiling == I915_TILING_Y);
-      *tile_x = region->draw_x % (128 / region->cpp);
-      *tile_y = region->draw_y % 32;
-      return ((region->draw_y / 32) * (32 * pitch) +
-	      (region->draw_x - *tile_x) / (128 / region->cpp) * 4096);
-   }
-}
diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h
index a8a300d..91f7121 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.h
+++ b/src/mesa/drivers/dri/intel/intel_regions.h
@@ -62,9 +62,6 @@ struct intel_region
    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 */
-   GLuint draw_x, draw_y; /**< Offset of drawing within the region */
-
    uint32_t tiling; /**< Which tiling mode the region is in */
    struct intel_buffer_object *pbo;     /* zero-copy uploads */
 
@@ -142,10 +139,6 @@ drm_intel_bo *intel_region_buffer(struct intel_context *intel,
 				  struct intel_region *region,
 				  GLuint flag);
 
-uint32_t intel_region_tile_offsets(struct intel_region *region,
-				   uint32_t *tile_x,
-				   uint32_t *tile_y);
-
 void _mesa_copy_rect(GLubyte * dst,
                 GLuint cpp,
                 GLuint dst_pitch,
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 62d4169..eda07a4 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -152,7 +152,7 @@ intel_copy_texsubimage(struct intel_context *intel,
 			     dst_bo,
 			     0,
 			     intelImage->mt->region->tiling,
-			     irb->region->draw_x + x, irb->region->draw_y + y,
+			     irb->draw_x + x, irb->draw_y + y,
 			     image_x + dstx, image_y + dsty,
 			     width, height,
 			     GL_COPY)) {
-- 
1.7.5.3



More information about the mesa-dev mailing list