intel: Move the draw_x/draw_y to the renderbuffer where it belongs.
authorEric Anholt <eric@anholt.net>
Tue, 31 May 2011 21:27:18 +0000 (14:27 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 13 Jun 2011 22:56:36 +0000 (15:56 -0700)
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).

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Chad Versace <chad@chad-versace.us>
12 files changed:
src/mesa/drivers/dri/i915/i830_vtbl.c
src/mesa/drivers/dri/i915/i915_vtbl.c
src/mesa/drivers/dri/i965/brw_misc_state.c
src/mesa/drivers/dri/i965/brw_wm_surface_state.c
src/mesa/drivers/dri/i965/gen7_misc_state.c
src/mesa/drivers/dri/i965/gen7_wm_surface_state.c
src/mesa/drivers/dri/intel/intel_blit.c
src/mesa/drivers/dri/intel/intel_fbo.c
src/mesa/drivers/dri/intel/intel_fbo.h
src/mesa/drivers/dri/intel/intel_regions.c
src/mesa/drivers/dri/intel/intel_regions.h
src/mesa/drivers/dri/intel/intel_tex_copy.c

index 19f0807759941b3477226165f7fbba700fb2ff78..08ea2870aa07739fdd0f39800778d3d0f811b323 100644 (file)
@@ -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;
index 820feba04ba6dda0ec1158ae203a34e67b6853e2..baff49bb2f5a846f5ae5759633e6551b661bdff4 100644 (file)
@@ -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;
index 3d0983e68798343c14865a996b8ca94215dbff27..2b5ec8ac6770e94312c1abf1a843e39bf7c0b09e 100644 (file)
@@ -322,7 +322,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(depth_irb, &tile_x, &tile_y);
 
       assert(intel->gen < 6 || region->tiling == I915_TILING_Y);
       assert(!hiz_region || region->tiling == I915_TILING_Y);
index f560bc3fa66e776b9d96f6d460b6c63e63516a48..ac8005dc6c272f3b782dd3c34a054f4dc9103389 100644 (file)
@@ -477,7 +477,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 |
index dd0ccd271939bffc14ec9af5d2d1baeff66fbe72..7544f961da9332d8df56a938f5ba2c7de4525eeb 100644 (file)
@@ -113,7 +113,7 @@ static void emit_depthbuffer(struct brw_context *brw)
       struct intel_region *region = drb->region;
       uint32_t tile_x, tile_y, offset;
 
-      offset = intel_region_tile_offsets(region, &tile_x, &tile_y);
+      offset = intel_renderbuffer_tile_offsets(drb, &tile_x, &tile_y);
 
       assert(region->tiling == I915_TILING_Y);
 
index 00b562f2176051a44d0bafbe9e726c84df429da4..9994b67bfc5af8e6f8840983e437c9b155f7c0dc 100644 (file)
@@ -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);
index 5aac1f6fa246ef333f1ca0dda54ea1632b5b3845..30be1b9382f802b558fa58e20fb0e4c372eb0fde 100644 (file)
@@ -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;
index 65f35e1b487751891152e18a62c3983ad2b2d7c6..3e7e0b9a248fe3c82be108ca83ff5c1539cf1a75 100644 (file)
@@ -513,8 +513,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;
@@ -526,9 +527,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);
+   }
 }
 
 /**
@@ -584,12 +621,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
@@ -625,7 +662,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);
index e9929b095ff5ec3a2f41f36a1463c5be27ca01e6..509f5887225ac066054ac2f6782169289464edbd 100644 (file)
@@ -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 */
 };
 
 
@@ -130,6 +133,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)
@@ -141,5 +148,4 @@ intel_get_rb_region(struct gl_framebuffer *fb, GLuint attIndex)
       return NULL;
 }
 
-
 #endif /* INTEL_FBO_H */
index 0253bbc2aa07155ed6aa5721b1bffb2b19bfc609..a4da1ce4fa5857ab48a4aa59fb7c886c5134667d 100644 (file)
@@ -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);
-   }
-}
index a8a300d863cf36929aa87de6371bf0a6afd2c82a..91f7121436e885af89b4a295df71898d85c3faa6 100644 (file)
@@ -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,
index 62d4169acd1e72c4f8de91d789cfdc4e4fd01505..eda07a43deefaa9864aaec90347ea5c4c48adf51 100644 (file)
@@ -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)) {