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

Author: Mike Blumenkrantz <[email protected]>
Date:   Mon Aug 17 15:08:47 2020 -0400

zink: add a get_query_result_resource hook

this is messy due to how we have to accumulate all the query results
in some cases

future patches will break things up into utility functions for reuse

Acked-by: Erik Faye-Lund <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8944>

---

 src/gallium/drivers/zink/zink_query.c | 104 ++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)

diff --git a/src/gallium/drivers/zink/zink_query.c 
b/src/gallium/drivers/zink/zink_query.c
index f4652432428..a682eabb5c1 100644
--- a/src/gallium/drivers/zink/zink_query.c
+++ b/src/gallium/drivers/zink/zink_query.c
@@ -538,6 +538,109 @@ zink_render_condition(struct pipe_context *pctx,
    pipe_resource_reference(&pres, NULL);
 }
 
+static void
+zink_get_query_result_resource(struct pipe_context *pctx,
+                               struct pipe_query *pquery,
+                               bool wait,
+                               enum pipe_query_value_type result_type,
+                               int index,
+                               struct pipe_resource *pres,
+                               unsigned offset)
+{
+   struct zink_context *ctx = zink_context(pctx);
+   struct zink_screen *screen = zink_screen(pctx->screen);
+   struct zink_query *query = (struct zink_query*)pquery;
+   struct zink_resource *res = zink_resource(pres);
+   unsigned result_size = result_type <= PIPE_QUERY_TYPE_U32 ? 
sizeof(uint32_t) : sizeof(uint64_t);
+   VkQueryResultFlagBits size_flags = result_type <= PIPE_QUERY_TYPE_U32 ? 0 : 
VK_QUERY_RESULT_64_BIT;
+   unsigned num_queries = query->curr_query - query->last_start;
+   unsigned query_id = query->last_start;
+
+   if (index == -1) {
+      uint64_t u64[2] = {0};
+      /* TODO: this is awful. when we hook up valid regions for resources, we 
can at least check
+       * whether the preceding area has valid data and clobber it with a 
direct copy here for a
+       * big perf win
+       *
+       * VK_QUERY_RESULT_WITH_AVAILABILITY_BIT always writes result data at 
the specified offset,
+       * so we have to do a manual read
+       */
+      if (vkGetQueryPoolResults(screen->dev, query->query_pool, query_id, 1, 2 
* result_size, u64,
+                                0, size_flags | 
VK_QUERY_RESULT_WITH_AVAILABILITY_BIT | VK_QUERY_RESULT_PARTIAL_BIT) != 
VK_SUCCESS) {
+         debug_printf("zink: getting query result failed\n");
+         return;
+      }
+      struct pipe_transfer *transfer = NULL;
+      void *map = pipe_buffer_map_range(pctx, pres, offset, result_size, 
PIPE_MAP_WRITE, &transfer);
+      if (!transfer) {
+         debug_printf("zink: mapping result buffer failed\n");
+         return;
+      }
+      if (result_type <= PIPE_QUERY_TYPE_U32) {
+         uint32_t *u32_map = map;
+         uint32_t *u32_u64 = (void*)u64;
+         u32_map[0] = u32_u64[1];
+      } else {
+         uint64_t *u64_map = map;
+         u64_map[0] = u64[1];
+      }
+      pipe_buffer_unmap(pctx, transfer);
+      return;
+   }
+
+   unsigned fences = p_atomic_read(&query->fences);
+   if (!is_time_query(query) && (!fences || wait)) {
+      /* result happens to be ready or we're waiting */
+      if (num_queries == 1 && query->type != PIPE_QUERY_PRIMITIVES_GENERATED &&
+                              query->type != PIPE_QUERY_PRIMITIVES_EMITTED &&
+                              /* FIXME: I don't know why, but occlusion is 
broken here */
+                              query->type != PIPE_QUERY_OCCLUSION_PREDICATE &&
+                              query->type != 
PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE) {
+         struct zink_batch *batch = zink_batch_no_rp(ctx);
+         /* if it's a single query that doesn't need special handling, we can 
copy it and be done */
+         zink_batch_reference_resource_rw(batch, res, true);
+         zink_resource_buffer_barrier(batch->cmdbuf, res, 
VK_ACCESS_TRANSFER_WRITE_BIT, 0);
+         vkCmdCopyQueryPoolResults(batch->cmdbuf, query->query_pool, query_id, 
1, res->buffer,
+                                   offset, 0, size_flags);
+         /* this is required for compute batch sync and will be removed later 
*/
+         if (batch->batch_id != ZINK_COMPUTE_BATCH_ID)
+            pctx->flush(pctx, NULL, PIPE_FLUSH_HINT_FINISH);
+         return;
+      }
+   }
+   if (zink_curr_batch(ctx)->batch_id == query->batch_id)
+      pctx->flush(pctx, NULL, PIPE_FLUSH_HINT_FINISH);
+   /* unfortunately, there's no way to accumulate results from multiple 
queries on the gpu without either
+    * clobbering all but the last result or writing the results sequentially, 
so we have to manually write the result
+    */
+   union pipe_query_result result;
+   bool success = get_query_result(&ctx->base, pquery, wait, &result);
+   if (!success) {
+      debug_printf("zink: getting query result failed");
+      return;
+   }
+
+   struct pipe_transfer *transfer = NULL;
+   void *map = pipe_buffer_map_range(pctx, pres, offset, result_size, 
PIPE_MAP_WRITE, &transfer);
+   if (!transfer) {
+      debug_printf("zink: mapping result buffer failed");
+      return;
+   }
+   if (result_type <= PIPE_QUERY_TYPE_U32) {
+      uint32_t *u32 = map;
+      uint32_t limit;
+      if (result_type == PIPE_QUERY_TYPE_I32)
+         limit = INT_MAX;
+      else
+         limit = UINT_MAX;
+      u32[0] = MIN2(limit, result.u64);
+   } else {
+      uint64_t *u64 = map;
+      u64[0] = result.u64;
+   }
+   pipe_buffer_unmap(pctx, transfer);
+}
+
 static uint64_t
 zink_get_timestamp(struct pipe_context *pctx)
 {
@@ -564,6 +667,7 @@ zink_context_query_init(struct pipe_context *pctx)
    pctx->begin_query = zink_begin_query;
    pctx->end_query = zink_end_query;
    pctx->get_query_result = zink_get_query_result;
+   pctx->get_query_result_resource = zink_get_query_result_resource;
    pctx->set_active_query_state = zink_set_active_query_state;
    pctx->render_condition = zink_render_condition;
    pctx->get_timestamp = zink_get_timestamp;

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to