i965: Share the draw x/y offset masking code between main/blorp and all gens.
authorEric Anholt <eric@anholt.net>
Tue, 7 Aug 2012 23:53:24 +0000 (16:53 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 16 Oct 2012 20:13:44 +0000 (13:13 -0700)
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.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/drivers/dri/i965/brw_blorp.h
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_misc_state.c
src/mesa/drivers/dri/i965/gen6_blorp.cpp
src/mesa/drivers/dri/i965/gen7_blorp.cpp
src/mesa/drivers/dri/i965/gen7_misc_state.c

index 0ad7c1b61cfdbe88b7c6600e738c6843dff420f3..79a3f3ae79f80d4bcd9cb74390b89e179e209c9b 100644 (file)
@@ -324,10 +324,6 @@ private:
 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);
index 3dac6339b48ccd4628aeb688c05aae1a4b5f0d9b..16bcb9cecc754f8064a60f218c8840f1572553ce 100644 (file)
@@ -1127,6 +1127,14 @@ bool brwCreateContext(int api,
                       unsigned *error,
                      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
  */
index 6dfa08e01af2f074c2b94239a793fc08750f2ed9..be8dcc45274b7517f708ca713416c29198daecea 100644 (file)
@@ -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.
     */
index 60c3ff1674eb5f31ec4f16c1b21ef89d8c2d4d85..13dbd30d71f1ec6230f667bf0a92e23fa1953029 100644 (file)
                              * 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 */
    {
index eeeeabe2c642a5a002e4a41218330f4a94677a3a..317527396e357dbb65ad38daf8c61361fe3aa0ed 100644 (file)
@@ -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 */
    {
index 1d22448459f42e1429ba8c8edf8a2d937470052f..337143c58cf54e281582025afb7999bcead9e7bc 100644 (file)
@@ -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));