tu: Use hw binning or sysmem with QUERY_TYPE_PRIMITIVES_GENERATED
authorDanylo Piliaiev <dpiliaiev@igalia.com>
Tue, 21 Jun 2022 09:41:30 +0000 (12:41 +0300)
committerMarge Bot <emma+marge@anholt.net>
Fri, 24 Jun 2022 14:10:56 +0000 (14:10 +0000)
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@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17164>

src/freedreno/vulkan/tu_cmd_buffer.c
src/freedreno/vulkan/tu_private.h
src/freedreno/vulkan/tu_query.c

index e8619bd..ab94911 100644 (file)
@@ -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;
index 554405d..a78ea48 100644 (file)
@@ -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;
index 95d9b51..18b8fec 100644 (file)
@@ -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);