[Mesa-dev] [PATCH 4/5] i965: Share the draw x/y offset masking code between main/blorp and all gens.

Eric Anholt eric at anholt.net
Fri Oct 12 15:30:37 PDT 2012


This code is twisty, and the comment before most of the blocks was actually
giving me the opposite impression from its intention: We want to apply as much
of our offset as possible through coarse tile-aligned adjustment, since we can
do so independently per buffer, and apply the minimum we can through
fine-grained drawing offset x/y, since it has to agree between all buffers.
---
 src/mesa/drivers/dri/i965/brw_blorp.h       |    4 -
 src/mesa/drivers/dri/i965/brw_context.h     |    8 ++
 src/mesa/drivers/dri/i965/brw_misc_state.c  |  111 +++++++++++++++++----------
 src/mesa/drivers/dri/i965/gen6_blorp.cpp    |   28 +------
 src/mesa/drivers/dri/i965/gen7_blorp.cpp    |    5 +-
 src/mesa/drivers/dri/i965/gen7_misc_state.c |   41 ++--------
 6 files changed, 89 insertions(+), 108 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_blorp.h b/src/mesa/drivers/dri/i965/brw_blorp.h
index 0ad7c1b..79a3f3a 100644
--- a/src/mesa/drivers/dri/i965/brw_blorp.h
+++ b/src/mesa/drivers/dri/i965/brw_blorp.h
@@ -325,10 +325,6 @@ void
 gen6_blorp_init(struct brw_context *brw);
 
 void
-gen6_blorp_compute_tile_masks(const brw_blorp_params *params,
-                              uint32_t *tile_mask_x, uint32_t *tile_mask_y);
-
-void
 gen6_blorp_emit_batch_head(struct brw_context *brw,
                            const brw_blorp_params *params);
 
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 3dac633..16bcb9c 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -1128,6 +1128,14 @@ bool brwCreateContext(int api,
 		      void *sharedContextPrivate);
 
 /*======================================================================
+ * brw_misc_state.c
+ */
+void brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt,
+                                     struct intel_mipmap_tree *stencil_mt,
+                                     uint32_t *out_tile_mask_x,
+                                     uint32_t *out_tile_mask_y);
+
+/*======================================================================
  * brw_queryobj.c
  */
 void brw_init_queryobj_functions(struct dd_function_table *functions);
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 6dfa08e..be8dcc4 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -253,6 +253,70 @@ brw_depthbuffer_format(struct brw_context *brw)
    }
 }
 
+/**
+ * Returns the mask of how many bits of x and y must be handled through the
+ * depthbuffer's draw offset x and y fields.
+ *
+ * The draw offset x/y field of the depthbuffer packet is unfortunately shared
+ * between the depth, hiz, and stencil buffers.  Because it can be hard to get
+ * all 3 to agree on this value, we want to do as much drawing offset
+ * adjustment as possible by moving the base offset of the 3 buffers, which is
+ * restricted to tile boundaries.
+ *
+ * For each buffer, the remainder must be applied through the x/y draw offset.
+ * This returns the worst-case mask of the low bits that have to go into the
+ * packet.  If the 3 buffers don't agree on the drawing offset ANDed with this
+ * mask, then we're in trouble.
+ */
+void
+brw_get_depthstencil_tile_masks(struct intel_mipmap_tree *depth_mt,
+                                struct intel_mipmap_tree *stencil_mt,
+                                uint32_t *out_tile_mask_x,
+                                uint32_t *out_tile_mask_y)
+{
+   uint32_t tile_mask_x = 0, tile_mask_y = 0;
+
+   if (depth_mt) {
+      intel_region_get_tile_masks(depth_mt->region,
+                                  &tile_mask_x, &tile_mask_y, false);
+
+      struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_mt;
+      if (hiz_mt) {
+         uint32_t hiz_tile_mask_x, hiz_tile_mask_y;
+         intel_region_get_tile_masks(hiz_mt->region,
+                                     &hiz_tile_mask_x, &hiz_tile_mask_y, false);
+
+         /* Each HiZ row represents 2 rows of pixels */
+         hiz_tile_mask_y = hiz_tile_mask_y << 1 | 1;
+
+         tile_mask_x |= hiz_tile_mask_x;
+         tile_mask_y |= hiz_tile_mask_y;
+      }
+   }
+
+   if (stencil_mt) {
+      if (stencil_mt->stencil_mt)
+	 stencil_mt = stencil_mt->stencil_mt;
+
+      if (stencil_mt->format == MESA_FORMAT_S8) {
+         /* Separate stencil buffer uses 64x64 tiles. */
+         tile_mask_x |= 63;
+         tile_mask_y |= 63;
+      } else {
+         uint32_t stencil_tile_mask_x, stencil_tile_mask_y;
+         intel_region_get_tile_masks(stencil_mt->region,
+                                     &stencil_tile_mask_x,
+                                     &stencil_tile_mask_y, false);
+
+         tile_mask_x |= stencil_tile_mask_x;
+         tile_mask_y |= stencil_tile_mask_y;
+      }
+   }
+
+   *out_tile_mask_x = tile_mask_x;
+   *out_tile_mask_y = tile_mask_y;
+}
+
 static void emit_depthbuffer(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
@@ -261,6 +325,7 @@ static void emit_depthbuffer(struct brw_context *brw)
    /* _NEW_BUFFERS */
    struct intel_renderbuffer *depth_irb = intel_get_renderbuffer(fb, BUFFER_DEPTH);
    struct intel_renderbuffer *stencil_irb = intel_get_renderbuffer(fb, BUFFER_STENCIL);
+   struct intel_mipmap_tree *depth_mt = NULL;
    struct intel_mipmap_tree *stencil_mt = NULL;
    struct intel_region *hiz_region = NULL;
    unsigned int len;
@@ -272,39 +337,11 @@ static void emit_depthbuffer(struct brw_context *brw)
     */
    uint32_t draw_x = 0, draw_y = 0;
 
-   /* Masks used to determine how much of the draw_x and draw_y offsets should
-    * be performed using the fine adjustment of "depth coordinate offset X/Y"
-    * (dw5 of 3DSTATE_DEPTH_BUFFER).  Any remaining coarse adjustment will be
-    * performed by changing the base addresses of the buffers.
-    *
-    * Since the HiZ, depth, and stencil buffers all use the same "depth
-    * coordinate offset X/Y" values, we need to make sure that the coarse
-    * adjustment will be possible to apply to all three buffers.  Since coarse
-    * adjustment can only be applied in multiples of the tile size, we will OR
-    * together the tile masks of all the buffers to determine which offsets to
-    * perform as fine adjustments.
-    */
-   uint32_t tile_mask_x = 0, tile_mask_y = 0;
-
-   if (depth_irb) {
-      intel_region_get_tile_masks(depth_irb->mt->region,
-                                  &tile_mask_x, &tile_mask_y, false);
-   }
-
    if (depth_irb &&
        depth_irb->mt &&
        depth_irb->mt->hiz_mt) {
+      depth_mt = depth_irb->mt;
       hiz_region = depth_irb->mt->hiz_mt->region;
-
-      uint32_t hiz_tile_mask_x, hiz_tile_mask_y;
-      intel_region_get_tile_masks(hiz_region,
-                                  &hiz_tile_mask_x, &hiz_tile_mask_y, false);
-
-      /* Each HiZ row represents 2 rows of pixels */
-      hiz_tile_mask_y = hiz_tile_mask_y << 1 | 1;
-
-      tile_mask_x |= hiz_tile_mask_x;
-      tile_mask_y |= hiz_tile_mask_y;
    }
 
    /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both
@@ -323,21 +360,13 @@ static void emit_depthbuffer(struct brw_context *brw)
 
       if (stencil_mt->format == MESA_FORMAT_S8) {
 	 separate_stencil = true;
-
-         /* Separate stencil buffer uses 64x64 tiles. */
-         tile_mask_x |= 63;
-         tile_mask_y |= 63;
-      } else {
-         uint32_t stencil_tile_mask_x, stencil_tile_mask_y;
-         intel_region_get_tile_masks(stencil_mt->region,
-                                     &stencil_tile_mask_x,
-                                     &stencil_tile_mask_y, false);
-
-         tile_mask_x |= stencil_tile_mask_x;
-         tile_mask_y |= stencil_tile_mask_y;
       }
    }
 
+   uint32_t tile_mask_x, tile_mask_y;
+   brw_get_depthstencil_tile_masks(depth_mt, stencil_mt,
+                                   &tile_mask_x, &tile_mask_y);
+
    /* If there's a packed depth/stencil bound to stencil only, we need to
     * emit the packed depth/stencil buffer packet.
     */
diff --git a/src/mesa/drivers/dri/i965/gen6_blorp.cpp b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
index 60c3ff1..13dbd30 100644
--- a/src/mesa/drivers/dri/i965/gen6_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen6_blorp.cpp
@@ -45,31 +45,6 @@
                              * sizeof(float))
 /** \} */
 
-
-/**
- * Compute masks to determine how much of draw_x and draw_y should be
- * performed using the fine adjustment of "depth coordinate offset X/Y"
- * (dw5 of 3DSTATE_DEPTH_BUFFER).  See the emit_depthbuffer() function for
- * details.
- */
-void
-gen6_blorp_compute_tile_masks(const brw_blorp_params *params,
-                              uint32_t *tile_mask_x, uint32_t *tile_mask_y)
-{
-   uint32_t depth_mask_x, depth_mask_y, hiz_mask_x, hiz_mask_y;
-   intel_region_get_tile_masks(params->depth.mt->region,
-                               &depth_mask_x, &depth_mask_y, false);
-   intel_region_get_tile_masks(params->depth.mt->hiz_mt->region,
-                               &hiz_mask_x, &hiz_mask_y, false);
-
-   /* Each HiZ row represents 2 rows of pixels */
-   hiz_mask_y = hiz_mask_y << 1 | 1;
-
-   *tile_mask_x = depth_mask_x | hiz_mask_x;
-   *tile_mask_y = depth_mask_y | hiz_mask_y;
-}
-
-
 void
 gen6_blorp_emit_batch_head(struct brw_context *brw,
                            const brw_blorp_params *params)
@@ -834,7 +809,8 @@ gen6_blorp_emit_depth_stencil_config(struct brw_context *brw,
    uint32_t draw_y = params->depth.y_offset;
    uint32_t tile_mask_x, tile_mask_y;
 
-   gen6_blorp_compute_tile_masks(params, &tile_mask_x, &tile_mask_y);
+   brw_get_depthstencil_tile_masks(params->depth.mt, NULL,
+                                   &tile_mask_x, &tile_mask_y);
 
    /* 3DSTATE_DEPTH_BUFFER */
    {
diff --git a/src/mesa/drivers/dri/i965/gen7_blorp.cpp b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
index eeeeabe..3175273 100644
--- a/src/mesa/drivers/dri/i965/gen7_blorp.cpp
+++ b/src/mesa/drivers/dri/i965/gen7_blorp.cpp
@@ -582,7 +582,10 @@ gen7_blorp_emit_depth_stencil_config(struct brw_context *brw,
    uint32_t draw_y = params->depth.y_offset;
    uint32_t tile_mask_x, tile_mask_y;
 
-   gen6_blorp_compute_tile_masks(params, &tile_mask_x, &tile_mask_y);
+   if (params->depth.mt) {
+      brw_get_depthstencil_tile_masks(params->depth.mt, NULL,
+                                      &tile_mask_x, &tile_mask_y);
+   }
 
    /* 3DSTATE_DEPTH_BUFFER */
    {
diff --git a/src/mesa/drivers/dri/i965/gen7_misc_state.c b/src/mesa/drivers/dri/i965/gen7_misc_state.c
index 1d22448..337143c 100644
--- a/src/mesa/drivers/dri/i965/gen7_misc_state.c
+++ b/src/mesa/drivers/dri/i965/gen7_misc_state.c
@@ -48,55 +48,24 @@ static void emit_depthbuffer(struct brw_context *brw)
     */
    uint32_t draw_x = 0, draw_y = 0;
 
-   /* Masks used to determine how much of the draw_x and draw_y offsets should
-    * be performed using the fine adjustment of "depth coordinate offset X/Y"
-    * (dw5 of 3DSTATE_DEPTH_BUFFER).  Any remaining coarse adjustment will be
-    * performed by changing the base addresses of the buffers.
-    *
-    * Since the HiZ, depth, and stencil buffers all use the same "depth
-    * coordinate offset X/Y" values, we need to make sure that the coarse
-    * adjustment will be possible to apply to all three buffers.  Since coarse
-    * adjustment can only be applied in multiples of the tile size, we will OR
-    * together the tile masks of all the buffers to determine which offsets to
-    * perform as fine adjustments.
-    */
-   uint32_t tile_mask_x = 0, tile_mask_y = 0;
-
    if (drb)
       depth_mt = drb->mt;
 
-   if (depth_mt) {
+   if (depth_mt)
       hiz_mt = depth_mt->hiz_mt;
 
-      intel_region_get_tile_masks(depth_mt->region,
-                                  &tile_mask_x, &tile_mask_y, false);
-
-      if (hiz_mt) {
-         uint32_t hiz_tile_mask_x, hiz_tile_mask_y;
-         intel_region_get_tile_masks(hiz_mt->region,
-                                     &hiz_tile_mask_x, &hiz_tile_mask_y,
-                                     false);
-
-         /* Each HiZ row represents 2 rows of pixels */
-         hiz_tile_mask_y = hiz_tile_mask_y << 1 | 1;
-
-         tile_mask_x |= hiz_tile_mask_x;
-         tile_mask_y |= hiz_tile_mask_y;
-      }
-   }
-
    if (srb) {
       stencil_mt = srb->mt;
       if (stencil_mt->stencil_mt)
 	 stencil_mt = stencil_mt->stencil_mt;
 
       assert(stencil_mt->format == MESA_FORMAT_S8);
-
-      /* Stencil buffer uses 64x64 tiles. */
-      tile_mask_x |= 63;
-      tile_mask_y |= 63;
    }
 
+   uint32_t tile_mask_x, tile_mask_y;
+   brw_get_depthstencil_tile_masks(depth_mt, stencil_mt,
+                                   &tile_mask_x, &tile_mask_y);
+
    /* Gen7 doesn't support packed depth/stencil */
    assert(stencil_mt == NULL || depth_mt != stencil_mt);
    assert(!depth_mt || !_mesa_is_format_packed_depth_stencil(depth_mt->format));
-- 
1.7.10.4



More information about the mesa-dev mailing list