Mesa (main): tu: Use hw binning or sysmem with QUERY_TYPE_PRIMITIVES_GENERATED

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jun 24 14:33:48 UTC 2022


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

Author: Danylo Piliaiev <dpiliaiev at igalia.com>
Date:   Tue Jun 21 12:41:30 2022 +0300

tu: Use hw binning or sysmem with QUERY_TYPE_PRIMITIVES_GENERATED

Without hw binning in gmem primitives generated query result could be
multiplied by tile count, which is not expected by OpenGL users for
GL_PRIMITIVES_GENERATED.

See https://gitlab.khronos.org/vulkan/vulkan/-/issues/3131

Signed-off-by: Danylo Piliaiev <dpiliaiev at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17164>

---

 src/freedreno/vulkan/tu_cmd_buffer.c | 20 ++++++++++++++++++++
 src/freedreno/vulkan/tu_private.h    |  3 +++
 src/freedreno/vulkan/tu_query.c      | 10 ++++++++++
 3 files changed, 33 insertions(+)

diff --git a/src/freedreno/vulkan/tu_cmd_buffer.c b/src/freedreno/vulkan/tu_cmd_buffer.c
index e8619bd4462..ab949110566 100644
--- a/src/freedreno/vulkan/tu_cmd_buffer.c
+++ b/src/freedreno/vulkan/tu_cmd_buffer.c
@@ -572,6 +572,17 @@ use_hw_binning(struct tu_cmd_buffer *cmd)
       return true;
    }
 
+   /* VK_QUERY_TYPE_PRIMITIVES_GENERATED_EXT emulates GL_PRIMITIVES_GENERATED,
+    * which wasn't designed to care about tilers and expects the result not to
+    * be multiplied by tile count.
+    * See https://gitlab.khronos.org/vulkan/vulkan/-/issues/3131
+    */
+   if (cmd->state.has_prim_generated_query_in_rp ||
+       cmd->state.prim_generated_query_running_before_rp) {
+      assert(fb->binning_possible);
+      return true;
+   }
+
    return fb->binning;
 }
 
@@ -604,6 +615,14 @@ use_sysmem_rendering(struct tu_cmd_buffer *cmd,
    if (cmd->state.xfb_used && !cmd->state.framebuffer->binning_possible)
       return true;
 
+   /* QUERY_TYPE_PRIMITIVES_GENERATED is incompatible with non-hw binning
+    * GMEM rendering, see use_hw_binning.
+    */
+   if ((cmd->state.has_prim_generated_query_in_rp ||
+        cmd->state.prim_generated_query_running_before_rp) &&
+       !cmd->state.framebuffer->binning_possible)
+      return true;
+
    if (unlikely(cmd->device->physical_device->instance->debug_flags & TU_DEBUG_GMEM))
       return false;
 
@@ -4963,6 +4982,7 @@ tu_CmdEndRenderPass2(VkCommandBuffer commandBuffer,
    cmd_buffer->state.disable_gmem = false;
    cmd_buffer->state.drawcall_count = 0;
    cmd_buffer->state.drawcall_bandwidth_per_sample_sum = 0;
+   cmd_buffer->state.has_prim_generated_query_in_rp = false;
 
    /* LRZ is not valid next time we use it */
    cmd_buffer->state.lrz.valid = false;
diff --git a/src/freedreno/vulkan/tu_private.h b/src/freedreno/vulkan/tu_private.h
index 554405d2a4d..a78ea48aa95 100644
--- a/src/freedreno/vulkan/tu_private.h
+++ b/src/freedreno/vulkan/tu_private.h
@@ -1250,6 +1250,9 @@ struct tu_cmd_state
     */
    uint32_t drawcall_bandwidth_per_sample_sum;
 
+   bool prim_generated_query_running_before_rp;
+   bool has_prim_generated_query_in_rp;
+
    struct tu_lrz_state lrz;
 
    struct tu_draw_state lrz_and_depth_plane_state;
diff --git a/src/freedreno/vulkan/tu_query.c b/src/freedreno/vulkan/tu_query.c
index 95d9b51b4aa..18b8fec966e 100644
--- a/src/freedreno/vulkan/tu_query.c
+++ b/src/freedreno/vulkan/tu_query.c
@@ -965,6 +965,12 @@ emit_begin_prim_generated_query(struct tu_cmd_buffer *cmdbuf,
    struct tu_cs *cs = cmdbuf->state.pass ? &cmdbuf->draw_cs : &cmdbuf->cs;
    uint64_t begin_iova = primitives_generated_query_iova(pool, query, begin);
 
+   if (cmdbuf->state.pass) {
+      cmdbuf->state.has_prim_generated_query_in_rp = true;
+   } else {
+      cmdbuf->state.prim_generated_query_running_before_rp = true;
+   }
+
    tu6_emit_event_write(cmdbuf, cs, START_PRIMITIVE_CTRS);
    tu6_emit_event_write(cmdbuf, cs, RST_PIX_CNT);
    tu6_emit_event_write(cmdbuf, cs, TILE_FLUSH);
@@ -1297,6 +1303,10 @@ emit_end_prim_generated_query(struct tu_cmd_buffer *cmdbuf,
 {
    struct tu_cs *cs = cmdbuf->state.pass ? &cmdbuf->draw_cs : &cmdbuf->cs;
 
+   if (!cmdbuf->state.pass) {
+      cmdbuf->state.prim_generated_query_running_before_rp = false;
+   }
+
    uint64_t begin_iova = primitives_generated_query_iova(pool, query, begin);
    uint64_t end_iova = primitives_generated_query_iova(pool, query, end);
    uint64_t result_iova = primitives_generated_query_iova(pool, query, result);



More information about the mesa-commit mailing list