i965: Use BLORP for all HiZ ops
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 6 Jun 2017 00:10:24 +0000 (17:10 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 7 Jun 2017 15:54:54 +0000 (08:54 -0700)
BLORP has been capable of doing gen8-style HiZ ops for a while now.  We
might as well start using it.  The one downside is that this may cause a
bit more state emission since we still re-emit most things for BLORP.

Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
src/mesa/drivers/dri/i965/brw_blorp.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/gen8_depth_state.c

index 568ff6980e88762a3d5573ac05887906be78c4e8..8fb9973d5cf869aa63b182e81e6af8483002ae45 100644 (file)
@@ -993,6 +993,8 @@ intel_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
                unsigned int level, unsigned int start_layer,
                unsigned int num_layers, enum blorp_hiz_op op)
 {
+   assert(intel_miptree_level_has_hiz(mt, level));
+   assert(op != BLORP_HIZ_OP_NONE);
    const char *opname = NULL;
 
    switch (op) {
@@ -1061,23 +1063,16 @@ intel_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
       }
    }
 
-   if (brw->gen >= 8) {
-      for (unsigned a = 0; a < num_layers; a++)
-         gen8_hiz_exec(brw, mt, level, start_layer + a, op);
-   } else {
-      assert(intel_miptree_level_has_hiz(mt, level));
-
-      struct isl_surf isl_tmp[2];
-      struct blorp_surf surf;
-      blorp_surf_for_miptree(brw, &surf, mt, true, (1 << ISL_AUX_USAGE_HIZ),
-                             &level, start_layer, num_layers, isl_tmp);
 
-      struct blorp_batch batch;
-      blorp_batch_init(&brw->blorp, &batch, brw, 0);
-      blorp_hiz_op(&batch, &surf, level, start_layer, num_layers, op);
-      blorp_batch_finish(&batch);
-   }
+   struct isl_surf isl_tmp[2];
+   struct blorp_surf surf;
+   blorp_surf_for_miptree(brw, &surf, mt, true, (1 << ISL_AUX_USAGE_HIZ),
+                          &level, start_layer, num_layers, isl_tmp);
 
+   struct blorp_batch batch;
+   blorp_batch_init(&brw->blorp, &batch, brw, 0);
+   blorp_hiz_op(&batch, &surf, level, start_layer, num_layers, op);
+   blorp_batch_finish(&batch);
 
    /* The following stalls and flushes are only documented to be required for
     * HiZ clear operations.  However, they also seem to be required for the
index 4c5bc3ba75e50798f22398e07a4728bcd6b455d0..6d38cbfaf827b60712e1341d705dc607eb5b1356 100644 (file)
@@ -1634,9 +1634,6 @@ gen8_emit_depth_stencil_hiz(struct brw_context *brw,
                             uint32_t width, uint32_t height,
                             uint32_t tile_x, uint32_t tile_y);
 
-void gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
-                   unsigned int level, unsigned int layer, enum blorp_hiz_op op);
-
 uint32_t get_hw_prim_for_gl_prim(int mode);
 
 void
index e7c7b9a4bd7f75251a680de74ae67cd494a7e1c5..9460ff4b77851d2914b4d5bd60e1ffb5a26b9c00 100644 (file)
@@ -391,147 +391,3 @@ const struct brw_tracked_state gen8_pma_fix = {
    },
    .emit = gen8_emit_pma_stall_workaround
 };
-
-/**
- * Emit packets to perform a depth/HiZ resolve or fast depth/stencil clear.
- *
- * See the "Optimized Depth Buffer Clear and/or Stencil Buffer Clear" section
- * of the hardware documentation for details.
- */
-void
-gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
-              unsigned int level, unsigned int layer, enum blorp_hiz_op op)
-{
-   if (op == BLORP_HIZ_OP_NONE)
-      return;
-
-   /* Disable the PMA stall fix since we're about to do a HiZ operation. */
-   if (brw->gen == 8)
-      gen8_write_pma_stall_bits(brw, 0);
-
-   assert(mt->first_level == 0);
-   assert(mt->logical_depth0 >= 1);
-
-   /* If we're operating on LOD 0, align to 8x4 to meet the alignment
-    * requirements for most HiZ operations.  Otherwise, use the actual size
-    * to allow the hardware to calculate the miplevel offsets correctly.
-    */
-   uint32_t surface_width  = ALIGN(mt->logical_width0,  level == 0 ? 8 : 1);
-   uint32_t surface_height = ALIGN(mt->logical_height0, level == 0 ? 4 : 1);
-
-   /* From the documentation for 3DSTATE_WM_HZ_OP: "3DSTATE_MULTISAMPLE packet
-    * must be used prior to this packet to change the Number of Multisamples.
-    * This packet must not be used to change Number of Multisamples in a
-    * rendering sequence."
-    */
-   if (brw->num_samples != mt->num_samples) {
-      gen8_emit_3dstate_multisample(brw, mt->num_samples);
-      brw->NewGLState |= _NEW_MULTISAMPLE;
-   }
-
-   /* The basic algorithm is:
-    * - If needed, emit 3DSTATE_{DEPTH,HIER_DEPTH,STENCIL}_BUFFER and
-    *   3DSTATE_CLEAR_PARAMS packets to set up the relevant buffers.
-    * - If needed, emit 3DSTATE_DRAWING_RECTANGLE.
-    * - Emit 3DSTATE_WM_HZ_OP with a bit set for the particular operation.
-    * - Do a special PIPE_CONTROL to trigger an implicit rectangle primitive.
-    * - Emit 3DSTATE_WM_HZ_OP with no bits set to return to normal rendering.
-    */
-   emit_depth_packets(brw, mt,
-                      brw_depth_format(brw, mt->format),
-                      BRW_SURFACE_2D,
-                      true, /* depth writes */
-                      NULL, false, /* no stencil for now */
-                      true, /* hiz */
-                      surface_width,
-                      surface_height,
-                      mt->logical_depth0,
-                      level,
-                      layer); /* min_array_element */
-
-   /* Depth buffer clears and HiZ resolves must use an 8x4 aligned rectangle.
-    * Note that intel_miptree_level_enable_hiz disables HiZ for miplevels > 0
-    * which aren't 8x4 aligned, so expanding the size is safe - it'll just
-    * draw into empty padding space.
-    */
-   unsigned rect_width = ALIGN(minify(mt->logical_width0, level), 8);
-   unsigned rect_height = ALIGN(minify(mt->logical_height0, level), 4);
-
-   BEGIN_BATCH(4);
-   OUT_BATCH(_3DSTATE_DRAWING_RECTANGLE << 16 | (4 - 2));
-   OUT_BATCH(0);
-   OUT_BATCH(((rect_width - 1) & 0xffff) | ((rect_height - 1) << 16));
-   OUT_BATCH(0);
-   ADVANCE_BATCH();
-
-   /* Emit 3DSTATE_WM_HZ_OP to override pipeline state for the particular
-    * resolve or clear operation we want to perform.
-    */
-   uint32_t dw1 = 0;
-
-   switch (op) {
-   case BLORP_HIZ_OP_DEPTH_RESOLVE:
-      dw1 |= GEN8_WM_HZ_DEPTH_RESOLVE;
-      break;
-   case BLORP_HIZ_OP_HIZ_RESOLVE:
-      dw1 |= GEN8_WM_HZ_HIZ_RESOLVE;
-      break;
-   case BLORP_HIZ_OP_DEPTH_CLEAR:
-      dw1 |= GEN8_WM_HZ_DEPTH_CLEAR;
-
-      /* The "Clear Rectangle X Max" (and Y Max) fields are exclusive,
-       * rather than inclusive, and limited to 16383.  This means that
-       * for a 16384x16384 render target, we would miss the last row
-       * or column of pixels along the edge.
-       *
-       * To work around this, we have to set the "Full Surface Depth
-       * and Stencil Clear" bit.  We can do this in all cases because
-       * we always clear the full rectangle anyway.  We'll need to
-       * change this if we ever add scissored clear support.
-       */
-      dw1 |= GEN8_WM_HZ_FULL_SURFACE_DEPTH_CLEAR;
-      break;
-   case BLORP_HIZ_OP_NONE:
-      unreachable("Should not get here.");
-   }
-
-   if (mt->num_samples > 0)
-      dw1 |= SET_FIELD(ffs(mt->num_samples) - 1, GEN8_WM_HZ_NUM_SAMPLES);
-
-   BEGIN_BATCH(5);
-   OUT_BATCH(_3DSTATE_WM_HZ_OP << 16 | (5 - 2));
-   OUT_BATCH(dw1);
-   OUT_BATCH(0);
-   OUT_BATCH(SET_FIELD(rect_width, GEN8_WM_HZ_CLEAR_RECTANGLE_X_MAX) |
-             SET_FIELD(rect_height, GEN8_WM_HZ_CLEAR_RECTANGLE_Y_MAX));
-   OUT_BATCH(SET_FIELD(0xFFFF, GEN8_WM_HZ_SAMPLE_MASK));
-   ADVANCE_BATCH();
-
-   /* Emit a PIPE_CONTROL with "Post-Sync Operation" set to "Write Immediate
-    * Data", and no other bits set.  This causes 3DSTATE_WM_HZ_OP's state to
-    * take effect, and spawns a rectangle primitive.
-    */
-   brw_emit_pipe_control_write(brw,
-                               PIPE_CONTROL_WRITE_IMMEDIATE,
-                               brw->workaround_bo, 0, 0, 0);
-
-   /* Emit 3DSTATE_WM_HZ_OP again to disable the state overrides. */
-   BEGIN_BATCH(5);
-   OUT_BATCH(_3DSTATE_WM_HZ_OP << 16 | (5 - 2));
-   OUT_BATCH(0);
-   OUT_BATCH(0);
-   OUT_BATCH(0);
-   OUT_BATCH(0);
-   ADVANCE_BATCH();
-
-   /* Mark this buffer as needing a TC flush, as we've rendered to it. */
-   brw_render_cache_set_add_bo(brw, mt->bo);
-
-   /* We've clobbered all of the depth packets, and the drawing rectangle,
-    * so we need to ensure those packets are re-emitted before the next
-    * primitive.
-    *
-    * Setting _NEW_DEPTH and _NEW_BUFFERS covers it, but is rather overkill.
-    */
-   brw->NewGLState |= _NEW_DEPTH | _NEW_BUFFERS;
-}