Mesa (master): v3dv: fix occlusion query inheritance in secondary command buffers

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Nov 2 11:13:01 UTC 2020


Module: Mesa
Branch: master
Commit: 7d6609e70d50795a582f549264e1a3359ed42ddc
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7d6609e70d50795a582f549264e1a3359ed42ddc

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Fri Oct 30 09:12:38 2020 +0100

v3dv: fix occlusion query inheritance in secondary command buffers

If a secondary command buffer has occlusion query inheritance then
draw calls recorded in it should update an active occlusion query
counter started in the primary command buffer.

If executing the secondary in a primary required to emit jobs and
not just a branch instruction, then we might need to create a new
job for the primary as well, and in that case we would lose the
occlusion query state, so we need to re-emit it at that point so
any additional draw calls recorded into the secondary that is being
executed continue to update the counter.

Fixes:
dEQP-VK.query_pool.concurrent_queries.secondary_command_buffer

Reviewed-by: Alejandro Piñeiro <apinheiro at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7373>

---

 src/broadcom/vulkan/v3dv_cmd_buffer.c | 34 ++++++++++++++++++++++++----------
 src/broadcom/vulkan/v3dv_private.h    |  5 +++++
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index 2081207c8c7..1f12c73bab5 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -820,6 +820,12 @@ v3dv_job_init(struct v3dv_job *job,
        */
       cmd_buffer->state.dirty = ~0;
 
+      /* Honor inheritance of occlussion queries in secondaries if requested */
+      if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY &&
+          cmd_buffer->state.inheritance.occlusion_query_enable) {
+         cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_OCCLUSION_QUERY;
+      }
+
       /* Keep track of the first subpass that we are recording in this new job.
        * We will use this when we emit the RCL to decide how to emit our loads
        * and stores.
@@ -1069,10 +1075,15 @@ cmd_buffer_begin_render_pass_secondary(
    cmd_buffer->state.framebuffer =
       v3dv_framebuffer_from_handle(inheritance_info->framebuffer);
 
+   assert(inheritance_info->subpass < cmd_buffer->state.pass->subpass_count);
+   cmd_buffer->state.subpass_idx = inheritance_info->subpass;
+
+   cmd_buffer->state.inheritance.occlusion_query_enable =
+      inheritance_info->occlusionQueryEnable;
+
    /* Secondaries that execute inside a render pass won't start subpasses
     * so we want to create a job for them here.
     */
-   assert(inheritance_info->subpass < cmd_buffer->state.pass->subpass_count);
    struct v3dv_job *job =
       v3dv_cmd_buffer_start_job(cmd_buffer, inheritance_info->subpass,
                                 V3DV_JOB_TYPE_GPU_CL_SECONDARY);
@@ -1081,8 +1092,6 @@ cmd_buffer_begin_render_pass_secondary(
       return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
 
-   cmd_buffer->state.subpass_idx = inheritance_info->subpass;
-
    /* Secondary command buffers don't know about the render area, but our
     * scissor setup accounts for it, so let's make sure we make it large
     * enough that it doesn't actually constrain any rendering. This should
@@ -1131,12 +1140,6 @@ v3dv_BeginCommandBuffer(VkCommandBuffer commandBuffer,
          if (result != VK_SUCCESS)
             return result;
       }
-
-      /* If the primary may have an active occlusion query we need to honor
-       * that in the secondary.
-       */
-      if (pBeginInfo->pInheritanceInfo->occlusionQueryEnable)
-         cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_OCCLUSION_QUERY;
    }
 
    cmd_buffer->status = V3DV_CMD_BUFFER_STATUS_RECORDING;
@@ -2543,7 +2546,12 @@ cmd_buffer_execute_inside_pass(struct v3dv_cmd_buffer *primary,
 {
    assert(primary->state.job);
 
-   if (primary->state.dirty & V3DV_CMD_DIRTY_OCCLUSION_QUERY)
+   /* Emit occlusion query state if needed so the draw calls inside our
+    * secondaries update the counters.
+    */
+   bool has_occlusion_query =
+      primary->state.dirty & V3DV_CMD_DIRTY_OCCLUSION_QUERY;
+   if (has_occlusion_query)
       emit_occlusion_query(primary);
 
    /* FIXME: if our primary job tiling doesn't enable MSSA but any of the
@@ -2592,6 +2600,12 @@ cmd_buffer_execute_inside_pass(struct v3dv_cmd_buffer *primary,
                   cmd_buffer_subpass_split_for_barrier(primary,
                                                        needs_bcl_barrier);
                v3dv_return_if_oom(primary, NULL);
+
+               /* Since we have created a new primary we need to re-emit
+                * occlusion query state.
+                */
+               if (has_occlusion_query)
+                  emit_occlusion_query(primary);
             }
 
             /* Make sure our primary job has all required BO references */
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 2017941e023..e6e2b5d5db9 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -983,6 +983,11 @@ struct v3dv_cmd_buffer_state {
    bool has_barrier;
    bool has_bcl_barrier;
 
+   /* Secondary command buffer state */
+   struct {
+      bool occlusion_query_enable;
+   } inheritance;
+
    /* Command buffer state saved during a meta operation */
    struct {
       uint32_t subpass_idx;



More information about the mesa-commit mailing list