[Mesa-dev] [PATCH 5/5] anv/cmd_buffer: Enable stencil-only HZ clears

Nanley Chery nanleychery at gmail.com
Mon Oct 10 22:32:44 UTC 2016


The HZ sequence modifies less state than the meta path and requires
less CPU time to be generated.

Signed-off-by: Nanley Chery <nanley.g.chery at intel.com>
---
 src/intel/vulkan/gen8_cmd_buffer.c | 63 ++++++++++++++++++++++++++------------
 1 file changed, 43 insertions(+), 20 deletions(-)

diff --git a/src/intel/vulkan/gen8_cmd_buffer.c b/src/intel/vulkan/gen8_cmd_buffer.c
index 330f7f3..039f08c 100644
--- a/src/intel/vulkan/gen8_cmd_buffer.c
+++ b/src/intel/vulkan/gen8_cmd_buffer.c
@@ -423,6 +423,9 @@ genX(cmd_buffer_emit_hz_op)(struct anv_cmd_buffer *cmd_buffer,
    struct anv_cmd_state *cmd_state = &cmd_buffer->state;
    const uint32_t ds = cmd_state->subpass->depth_stencil_attachment;
    bool full_surf_clear;
+   bool depth_clear;
+   bool stc_clear;
+
 
    /* This variable corresponds to the Pixel Dim column in the table below */
    struct isl_extent2d px_dim;
@@ -430,9 +433,13 @@ genX(cmd_buffer_emit_hz_op)(struct anv_cmd_buffer *cmd_buffer,
    /* Validate that we can perform the HZ operation and that it's necessary. */
    switch (op) {
    case BLORP_HIZ_OP_DEPTH_CLEAR:
-      if (cmd_buffer->state.pass->attachments[ds].load_op !=
-          VK_ATTACHMENT_LOAD_OP_CLEAR)
-         return;
+      /* Also check the load_op to avoid conflicts with meta clears. */
+      stc_clear = (cmd_buffer->state.pass->attachments[ds].stencil_load_op ==
+                  VK_ATTACHMENT_LOAD_OP_CLEAR) && (VK_IMAGE_ASPECT_STENCIL_BIT &
+                  cmd_state->attachments[ds].pending_clear_aspects);
+      depth_clear = (cmd_buffer->state.pass->attachments[ds].load_op ==
+                    VK_ATTACHMENT_LOAD_OP_CLEAR) && (VK_IMAGE_ASPECT_DEPTH_BIT &
+                    cmd_state->attachments[ds].pending_clear_aspects);
 
       /* Section 7.4. of the Vulkan 1.0.27 spec states:
        *
@@ -484,7 +491,7 @@ genX(cmd_buffer_emit_hz_op)(struct anv_cmd_buffer *cmd_buffer,
       px_dim = (struct isl_extent2d) { .w = 8, .h = 4};
 #endif
 
-      if (!full_surf_clear) {
+      if (depth_clear && !full_surf_clear) {
          /* Fast depth clears clear an entire sample block at a time. As a
           * result, the rectangle must be aligned to the pixel dimensions of
           * a sample block for a successful operation.
@@ -496,17 +503,27 @@ genX(cmd_buffer_emit_hz_op)(struct anv_cmd_buffer *cmd_buffer,
           * padded later on in this function.
           */
          if (cmd_state->render_area.offset.x % px_dim.w ||
-             cmd_state->render_area.offset.y % px_dim.h)
-            return;
-         if (cmd_state->render_area.offset.x +
-             cmd_state->render_area.extent.width != iview->extent.width &&
-             cmd_state->render_area.extent.width % px_dim.w)
-            return;
-         if (cmd_state->render_area.offset.y +
-             cmd_state->render_area.extent.height != iview->extent.height &&
-             cmd_state->render_area.extent.height % px_dim.h)
+             cmd_state->render_area.offset.y % px_dim.h ||
+             (cmd_state->render_area.offset.x +
+              cmd_state->render_area.extent.width != iview->extent.width &&
+              cmd_state->render_area.extent.width % px_dim.w) ||
+             (cmd_state->render_area.offset.y +
+              cmd_state->render_area.extent.height != iview->extent.height &&
+              cmd_state->render_area.extent.height % px_dim.h)) {
+            depth_clear = false;
+         }
+      }
+
+      if (!depth_clear) {
+         if (stc_clear) {
+            /* Stencil has no alignment requirements */
+            px_dim = (struct isl_extent2d) { .w = 1, .h = 1};
+         } else {
+            /* Nothing to clear */
             return;
+         }
       }
+
       break;
    case BLORP_HIZ_OP_DEPTH_RESOLVE:
       if (cmd_buffer->state.pass->attachments[ds].store_op !=
@@ -526,10 +543,8 @@ genX(cmd_buffer_emit_hz_op)(struct anv_cmd_buffer *cmd_buffer,
    anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_WM_HZ_OP), hzp) {
       switch (op) {
       case BLORP_HIZ_OP_DEPTH_CLEAR:
-         hzp.StencilBufferClearEnable = VK_IMAGE_ASPECT_STENCIL_BIT &
-                            cmd_state->attachments[ds].pending_clear_aspects;
-         hzp.DepthBufferClearEnable = VK_IMAGE_ASPECT_DEPTH_BIT &
-                            cmd_state->attachments[ds].pending_clear_aspects;
+         hzp.StencilBufferClearEnable = stc_clear;
+         hzp.DepthBufferClearEnable = depth_clear;
          hzp.FullSurfaceDepthandStencilClear = full_surf_clear;
          hzp.StencilClearValue =
             cmd_state->attachments[ds].clear_value.depthStencil.stencil & 0xff;
@@ -581,16 +596,24 @@ genX(cmd_buffer_emit_hz_op)(struct anv_cmd_buffer *cmd_buffer,
 
    anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_WM_HZ_OP), hzp);
 
+   /* Perform clear specific flushing and state updates */
    if (op == BLORP_HIZ_OP_DEPTH_CLEAR) {
-      if (!full_surf_clear) {
+      if (depth_clear && !full_surf_clear) {
          anv_batch_emit(&cmd_buffer->batch, GENX(PIPE_CONTROL), pc) {
             pc.DepthStallEnable = true;
             pc.DepthCacheFlushEnable = true;
          }
       }
 
-      /* Mark aspects as cleared */
-      cmd_state->attachments[ds].pending_clear_aspects = 0;
+      /* Remove cleared aspects from the pending mask */
+      if (stc_clear) {
+         cmd_state->attachments[ds].pending_clear_aspects &=
+            ~VK_IMAGE_ASPECT_STENCIL_BIT;
+      }
+      if (depth_clear) {
+         cmd_state->attachments[ds].pending_clear_aspects &=
+            ~VK_IMAGE_ASPECT_DEPTH_BIT;
+      }
    }
 }
 
-- 
2.10.0



More information about the mesa-dev mailing list