Mesa (master): zink: also create an xfb query for every primitives generated query

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


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

Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date:   Thu Jul 30 14:12:04 2020 -0400

zink: also create an xfb query for every primitives generated query

this query behaves differently when xfb is activated, specifically with
regard to vertex streams. it's super clunky, but we need to actually run
both queries and use results based on whether xfb was active during the
query

Reviewed-by: Erik Faye-Lund <erik.faye-lund at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7195>

---

 src/gallium/drivers/zink/zink_query.c | 60 +++++++++++++++++++++++++++++------
 1 file changed, 50 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/zink/zink_query.c b/src/gallium/drivers/zink/zink_query.c
index 5526a011cd0..bef9c5d04ee 100644
--- a/src/gallium/drivers/zink/zink_query.c
+++ b/src/gallium/drivers/zink/zink_query.c
@@ -17,6 +17,7 @@ struct zink_query {
    enum pipe_query_type type;
 
    VkQueryPool query_pool;
+   VkQueryPool xfb_query_pool;
    unsigned last_checked_query, curr_query, num_queries;
 
    VkQueryType vkqtype;
@@ -34,6 +35,7 @@ struct zink_query {
 
    struct list_head stats_list; /* when active, statistics queries are added to ctx->primitives_generated_queries */
    bool have_gs[4]; /* geometry shaders use GEOMETRY_SHADER_PRIMITIVES_BIT; sized by ctx->batches[] array size */
+   bool have_xfb[4]; /* xfb was active during this query; sized by ctx->batches[] array size */
 
    union pipe_query_result accumulated_result;
 };
@@ -121,8 +123,23 @@ zink_create_query(struct pipe_context *pctx,
       FREE(query);
       return NULL;
    }
+   if (query_type == PIPE_QUERY_PRIMITIVES_GENERATED) {
+      /* if xfb is active, we need to use an xfb query, otherwise we need pipeline statistics */
+      pool_create.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
+      pool_create.queryType = VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT;
+      pool_create.queryCount = query->num_queries;
+
+      status = vkCreateQueryPool(screen->dev, &pool_create, NULL, &query->xfb_query_pool);
+      if (status != VK_SUCCESS) {
+         vkDestroyQueryPool(screen->dev, query->query_pool, NULL);
+         FREE(query);
+         return NULL;
+      }
+   }
    struct zink_batch *batch = zink_batch_no_rp(zink_context(pctx));
    vkCmdResetQueryPool(batch->cmdbuf, query->query_pool, 0, query->num_queries);
+   if (query->type == PIPE_QUERY_PRIMITIVES_GENERATED)
+      vkCmdResetQueryPool(batch->cmdbuf, query->xfb_query_pool, 0, query->num_queries);
    if (query->type == PIPE_QUERY_TIMESTAMP)
       query->active = true;
    return (struct pipe_query *)query;
@@ -133,6 +150,8 @@ destroy_query(struct zink_screen *screen, struct zink_query *query)
 {
    assert(!p_atomic_read(&query->fences));
    vkDestroyQueryPool(screen->dev, query->query_pool, NULL);
+   if (query->type == PIPE_QUERY_PRIMITIVES_GENERATED)
+      vkDestroyQueryPool(screen->dev, query->xfb_query_pool, NULL);
    FREE(query);
 }
 
@@ -197,11 +216,13 @@ get_query_result(struct pipe_context *pctx,
    /* xfb queries return 2 results */
    uint64_t results[NUM_QUERIES * 2];
    memset(results, 0, sizeof(results));
+   uint64_t xfb_results[NUM_QUERIES * 2];
+   memset(xfb_results, 0, sizeof(xfb_results));
    int num_results = query->curr_query - query->last_checked_query;
    int result_size = 1;
       /* these query types emit 2 values */
-   if (query->vkqtype == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT ||
-       query->vkqtype == VK_QUERY_TYPE_PIPELINE_STATISTICS)
+   if (query->type == PIPE_QUERY_PRIMITIVES_GENERATED ||
+       query->type == PIPE_QUERY_PRIMITIVES_EMITTED)
       result_size = 2;
 
    /* verify that we have the expected number of results pending */
@@ -215,6 +236,18 @@ get_query_result(struct pipe_context *pctx,
    if (status != VK_SUCCESS)
       return false;
 
+   if (query->type == PIPE_QUERY_PRIMITIVES_GENERATED) {
+      status = vkGetQueryPoolResults(screen->dev, query->xfb_query_pool,
+                                              query->last_checked_query, num_results,
+                                              sizeof(xfb_results),
+                                              xfb_results,
+                                              2 * sizeof(uint64_t),
+                                              flags | VK_QUERY_RESULT_64_BIT);
+      if (status != VK_SUCCESS)
+         return false;
+
+   }
+
    uint64_t last_val = 0;
    for (int i = 0; i < num_results * result_size; i += result_size) {
       switch (query->type) {
@@ -239,8 +272,11 @@ get_query_result(struct pipe_context *pctx,
          result->u64 += results[i];
          break;
       case PIPE_QUERY_PRIMITIVES_GENERATED:
-         /* if a given draw had a geometry shader, we need to use the second result */
-         result->u32 += ((uint32_t*)results)[i + query->have_gs[i / 2]];
+         if (query->have_xfb[i / 2] || query->index)
+            result->u64 += xfb_results[i + 1];
+         else
+            /* if a given draw had a geometry shader, we need to use the second result */
+            result->u32 += ((uint32_t*)results)[i + query->have_gs[i / 2]];
          break;
       case PIPE_QUERY_PRIMITIVES_EMITTED:
          /* A query pool created with this type will capture 2 integers -
@@ -279,6 +315,8 @@ reset_pool(struct zink_context *ctx, struct zink_batch *batch, struct zink_query
    if (q->type != PIPE_QUERY_TIMESTAMP)
       get_query_result(&ctx->base, (struct pipe_query*)q, false, &q->accumulated_result);
    vkCmdResetQueryPool(batch->cmdbuf, q->query_pool, 0, q->num_queries);
+   if (q->type == PIPE_QUERY_PRIMITIVES_GENERATED)
+      vkCmdResetQueryPool(batch->cmdbuf, q->xfb_query_pool, 0, q->num_queries);
    q->last_checked_query = q->curr_query = 0;
    q->needs_reset = false;
 }
@@ -299,14 +337,15 @@ begin_query(struct zink_context *ctx, struct zink_batch *batch, struct zink_quer
       return;
    if (q->precise)
       flags |= VK_QUERY_CONTROL_PRECISE_BIT;
-   if (q->vkqtype == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT) {
+   if (q->vkqtype == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT || q->type == PIPE_QUERY_PRIMITIVES_GENERATED) {
       zink_screen(ctx->base.screen)->vk_CmdBeginQueryIndexedEXT(batch->cmdbuf,
-                                                                q->query_pool,
+                                                                q->xfb_query_pool ? q->xfb_query_pool : q->query_pool,
                                                                 q->curr_query,
                                                                 flags,
                                                                 q->index);
       q->xfb_running = true;
-   } else
+   }
+   if (q->vkqtype != VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT)
       vkCmdBeginQuery(batch->cmdbuf, q->query_pool, q->curr_query, flags);
    if (!batch->active_queries)
       batch->active_queries = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal);
@@ -340,9 +379,9 @@ end_query(struct zink_context *ctx, struct zink_batch *batch, struct zink_query
    if (is_time_query(q))
       vkCmdWriteTimestamp(batch->cmdbuf, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
                           q->query_pool, q->curr_query);
-   else if (q->vkqtype == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT)
-      screen->vk_CmdEndQueryIndexedEXT(batch->cmdbuf, q->query_pool, q->curr_query, q->index);
-   else
+   else if (q->vkqtype == VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT || q->type == PIPE_QUERY_PRIMITIVES_GENERATED)
+      screen->vk_CmdEndQueryIndexedEXT(batch->cmdbuf, q->xfb_query_pool ? q->xfb_query_pool : q->query_pool, q->curr_query, q->index);
+   if (q->vkqtype != VK_QUERY_TYPE_TRANSFORM_FEEDBACK_STREAM_EXT && !is_time_query(q))
       vkCmdEndQuery(batch->cmdbuf, q->query_pool, q->curr_query);
    if (q->type == PIPE_QUERY_PRIMITIVES_GENERATED)
       list_delinit(&q->stats_list);
@@ -419,6 +458,7 @@ zink_query_update_gs_states(struct zink_context *ctx)
    LIST_FOR_EACH_ENTRY(query, &ctx->primitives_generated_queries, stats_list) {
       assert(query->curr_query - query->last_checked_query < ARRAY_SIZE(query->have_gs));
       query->have_gs[query->curr_query - query->last_checked_query] = !!ctx->gfx_stages[PIPE_SHADER_GEOMETRY];
+      query->have_xfb[query->curr_query - query->last_checked_query] = !!ctx->num_so_targets;
    }
 }
 



More information about the mesa-commit mailing list