Mesa (main): v3dv: implement interaction of queries with multiview

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jul 27 07:45:58 UTC 2021


Module: Mesa
Branch: main
Commit: c19dcec60474ef4eaf7a46ad11ce29fe2140eac2
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c19dcec60474ef4eaf7a46ad11ce29fe2140eac2

Author: Iago Toral Quiroga <itoral at igalia.com>
Date:   Fri Jul 23 14:49:05 2021 +0200

v3dv: implement interaction of queries with multiview

When multiview is enabled, queries must begin and end in the
same subpass and N consecutive queries are implicitly used,
where N is the number of views enabled in the subpass.
Implementations decide how results are split across queries.

In our case, only one query is really used, but we still need
to flag all N queries as available by the time we flag the one
we use so that the application doesn't receive unexpected errors
when trying to retrieve values from them.

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

---

 src/broadcom/vulkan/v3dv_cmd_buffer.c | 36 ++++++++++++++++++++++++++++++++++-
 src/broadcom/vulkan/v3dv_private.h    |  6 ++++++
 src/broadcom/vulkan/v3dv_queue.c      | 20 ++++++++++++-------
 3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/src/broadcom/vulkan/v3dv_cmd_buffer.c b/src/broadcom/vulkan/v3dv_cmd_buffer.c
index 194ddc07b99..c52c9093814 100644
--- a/src/broadcom/vulkan/v3dv_cmd_buffer.c
+++ b/src/broadcom/vulkan/v3dv_cmd_buffer.c
@@ -3061,6 +3061,27 @@ v3dv_cmd_buffer_end_query(struct v3dv_cmd_buffer *cmd_buffer,
 
       info->pool = pool;
       info->query = query;
+
+      /* From the Vulkan spec:
+       *
+       *   "If queries are used while executing a render pass instance that has
+       *    multiview enabled, the query uses N consecutive query indices in
+       *    the query pool (starting at query) where N is the number of bits set
+       *    in the view mask in the subpass the query is used in. How the
+       *    numerical results of the query are distributed among the queries is
+       *    implementation-dependent."
+       *
+       * In our case, only the first query is used but this means we still need
+       * to flag the other queries as available so we don't emit errors when
+       * the applications attempt to retrive values from them.
+       */
+      struct v3dv_render_pass *pass = cmd_buffer->state.pass;
+      if (!pass->multiview_enabled) {
+         info->count = 1;
+      } else {
+         struct v3dv_subpass *subpass = &pass->subpasses[state->subpass_idx];
+         info->count = util_bitcount(subpass->view_mask);
+      }
    } else {
       /* Otherwise, schedule the CPU job immediately */
       struct v3dv_job *job =
@@ -3071,6 +3092,10 @@ v3dv_cmd_buffer_end_query(struct v3dv_cmd_buffer *cmd_buffer,
 
       job->cpu.query_end.pool = pool;
       job->cpu.query_end.query = query;
+
+      /* Multiview queries cannot cross subpass boundaries */
+      job->cpu.query_end.count = 1;
+
       list_addtail(&job->list_link, &cmd_buffer->jobs);
    }
 
@@ -3249,7 +3274,8 @@ v3dv_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
    /* If this is called inside a render pass we need to finish the current
     * job here...
     */
-   if (cmd_buffer->state.pass)
+   struct v3dv_render_pass *pass = cmd_buffer->state.pass;
+   if (pass)
       v3dv_cmd_buffer_finish_job(cmd_buffer);
 
    struct v3dv_job *job =
@@ -3261,6 +3287,14 @@ v3dv_CmdWriteTimestamp(VkCommandBuffer commandBuffer,
    job->cpu.query_timestamp.pool = query_pool;
    job->cpu.query_timestamp.query = query;
 
+   if (!pass || !pass->multiview_enabled) {
+      job->cpu.query_timestamp.count = 1;
+   } else {
+      struct v3dv_subpass *subpass =
+         &pass->subpasses[cmd_buffer->state.subpass_idx];
+      job->cpu.query_timestamp.count = util_bitcount(subpass->view_mask);
+   }
+
    list_addtail(&job->list_link, &cmd_buffer->jobs);
    cmd_buffer->state.job = NULL;
 
diff --git a/src/broadcom/vulkan/v3dv_private.h b/src/broadcom/vulkan/v3dv_private.h
index 650fcec36db..26585ec72de 100644
--- a/src/broadcom/vulkan/v3dv_private.h
+++ b/src/broadcom/vulkan/v3dv_private.h
@@ -896,6 +896,9 @@ struct v3dv_reset_query_cpu_job_info {
 struct v3dv_end_query_cpu_job_info {
    struct v3dv_query_pool *pool;
    uint32_t query;
+
+   /* This is one unless multiview is used */
+   uint32_t count;
 };
 
 struct v3dv_copy_query_results_cpu_job_info {
@@ -947,6 +950,9 @@ struct v3dv_csd_indirect_cpu_job_info {
 struct v3dv_timestamp_query_cpu_job_info {
    struct v3dv_query_pool *pool;
    uint32_t query;
+
+   /* This is one unless multiview is used */
+   uint32_t count;
 };
 
 struct v3dv_job {
diff --git a/src/broadcom/vulkan/v3dv_queue.c b/src/broadcom/vulkan/v3dv_queue.c
index 11a2585ee6e..dfa14f39c67 100644
--- a/src/broadcom/vulkan/v3dv_queue.c
+++ b/src/broadcom/vulkan/v3dv_queue.c
@@ -198,9 +198,11 @@ static VkResult
 handle_end_query_cpu_job(struct v3dv_job *job)
 {
    struct v3dv_end_query_cpu_job_info *info = &job->cpu.query_end;
-   assert(info->query < info->pool->query_count);
-   struct v3dv_query *query = &info->pool->queries[info->query];
-   query->maybe_available = true;
+   for (uint32_t i = 0; i < info->count; i++) {
+      assert(info->query + i < info->pool->query_count);
+      struct v3dv_query *query = &info->pool->queries[info->query + i];
+      query->maybe_available = true;
+   }
 
    return VK_SUCCESS;
 }
@@ -452,10 +454,14 @@ handle_timestamp_query_cpu_job(struct v3dv_job *job)
    /* Compute timestamp */
    struct timespec t;
    clock_gettime(CLOCK_MONOTONIC, &t);
-   assert(info->query < info->pool->query_count);
-   struct v3dv_query *query = &info->pool->queries[info->query];
-   query->maybe_available = true;
-   query->value = t.tv_sec * 1000000000ull + t.tv_nsec;
+
+   for (uint32_t i = 0; i < info->count; i++) {
+      assert(info->query + i < info->pool->query_count);
+      struct v3dv_query *query = &info->pool->queries[info->query + i];
+      query->maybe_available = true;
+      if (i == 0)
+         query->value = t.tv_sec * 1000000000ull + t.tv_nsec;
+   }
 
    return VK_SUCCESS;
 }



More information about the mesa-commit mailing list