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

Author: Marcin Ĺšlusarz <[email protected]>
Date:   Sat Apr 30 13:09:53 2022 +0200

anv: implement draw calls for EXT_mesh_shader

Reviewed-by: Caio Oliveira <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18371>

---

 src/intel/vulkan/genX_cmd_buffer.c | 164 +++++++++++++++++++++++++++++++++++--
 1 file changed, 157 insertions(+), 7 deletions(-)

diff --git a/src/intel/vulkan/genX_cmd_buffer.c 
b/src/intel/vulkan/genX_cmd_buffer.c
index 05855e021b3..cf8f0d66183 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -4570,16 +4570,42 @@ genX(CmdDrawMeshTasksNV)(
    }
 }
 
+void
+genX(CmdDrawMeshTasksEXT)(
+      VkCommandBuffer commandBuffer,
+      uint32_t x,
+      uint32_t y,
+      uint32_t z)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+
+   if (anv_batch_has_error(&cmd_buffer->batch))
+      return;
+
+   /* TODO(mesh): Check if this is not emitting more packets than we need. */
+   genX(cmd_buffer_flush_state)(cmd_buffer);
+
+   if (cmd_buffer->state.conditional_render_enabled)
+      genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
+
+   anv_batch_emit(&cmd_buffer->batch, GENX(3DMESH_3D), m) {
+      m.PredicateEnable = cmd_buffer->state.conditional_render_enabled;
+      m.ThreadGroupCountX = x;
+      m.ThreadGroupCountY = y;
+      m.ThreadGroupCountZ = z;
+   }
+}
+
 #define GFX125_3DMESH_TG_COUNT 0x26F0
 #define GFX125_3DMESH_STARTING_TGID 0x26F4
 #define GFX10_3DPRIM_XP(n) (0x2690 + (n) * 4) /* n = { 0, 1, 2 } */
 
 static void
-mesh_load_indirect_parameters(struct anv_cmd_buffer *cmd_buffer,
-                              struct mi_builder *b,
-                              struct anv_address addr,
-                              bool emit_xp0,
-                              uint32_t xp0)
+mesh_load_indirect_parameters_3dmesh_1d(struct anv_cmd_buffer *cmd_buffer,
+                                        struct mi_builder *b,
+                                        struct anv_address addr,
+                                        bool emit_xp0,
+                                        uint32_t xp0)
 {
    const size_t taskCountOff = offsetof(VkDrawMeshTasksIndirectCommandNV, 
taskCount);
    const size_t firstTaskOff = offsetof(VkDrawMeshTasksIndirectCommandNV, 
firstTask);
@@ -4608,6 +4634,44 @@ emit_indirect_3dmesh_1d(struct anv_batch *batch,
       dw[len - 1] = 0;
 }
 
+static void
+mesh_load_indirect_parameters_3dmesh_3d(struct anv_cmd_buffer *cmd_buffer,
+                                        struct mi_builder *b,
+                                        struct anv_address addr,
+                                        bool emit_xp0,
+                                        uint32_t xp0)
+{
+   const size_t groupCountXOff = offsetof(VkDrawMeshTasksIndirectCommandEXT, 
groupCountX);
+   const size_t groupCountYOff = offsetof(VkDrawMeshTasksIndirectCommandEXT, 
groupCountY);
+   const size_t groupCountZOff = offsetof(VkDrawMeshTasksIndirectCommandEXT, 
groupCountZ);
+
+   mi_store(b, mi_reg32(GFX125_3DMESH_TG_COUNT),
+               mi_mem32(anv_address_add(addr, groupCountXOff)));
+
+   mi_store(b, mi_reg32(GFX10_3DPRIM_XP(1)),
+               mi_mem32(anv_address_add(addr, groupCountYOff)));
+
+   mi_store(b, mi_reg32(GFX10_3DPRIM_XP(2)),
+               mi_mem32(anv_address_add(addr, groupCountZOff)));
+
+   if (emit_xp0)
+      mi_store(b, mi_reg32(GFX10_3DPRIM_XP(0)), mi_imm(xp0));
+}
+
+static void
+emit_indirect_3dmesh_3d(struct anv_batch *batch,
+                        bool predicate_enable,
+                        bool uses_drawid)
+{
+   uint32_t len = GENX(3DMESH_3D_length) + uses_drawid;
+   uint32_t *dw = anv_batch_emitn(batch, len, GENX(3DMESH_3D),
+                   .PredicateEnable           = predicate_enable,
+                   .IndirectParameterEnable   = true,
+                   .ExtendedParameter0Present = uses_drawid);
+   if (uses_drawid)
+      dw[len - 1] = 0;
+}
+
 void
 genX(CmdDrawMeshTasksIndirectNV)(
     VkCommandBuffer                             commandBuffer,
@@ -4639,7 +4703,7 @@ genX(CmdDrawMeshTasksIndirectNV)(
    for (uint32_t i = 0; i < drawCount; i++) {
       struct anv_address draw = anv_address_add(buffer->address, offset);
 
-      mesh_load_indirect_parameters(cmd_buffer, &b, draw, uses_drawid, i);
+      mesh_load_indirect_parameters_3dmesh_1d(cmd_buffer, &b, draw, 
uses_drawid, i);
 
       emit_indirect_3dmesh_1d(&cmd_buffer->batch,
             cmd_state->conditional_render_enabled, uses_drawid);
@@ -4648,6 +4712,46 @@ genX(CmdDrawMeshTasksIndirectNV)(
    }
 }
 
+void
+genX(CmdDrawMeshTasksIndirectEXT)(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    uint32_t                                    drawCount,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
+   const struct brw_task_prog_data *task_prog_data = 
get_task_prog_data(pipeline);
+   const struct brw_mesh_prog_data *mesh_prog_data = 
get_mesh_prog_data(pipeline);
+   struct anv_cmd_state *cmd_state = &cmd_buffer->state;
+
+   if (anv_batch_has_error(&cmd_buffer->batch))
+      return;
+
+   genX(cmd_buffer_flush_state)(cmd_buffer);
+
+   if (cmd_state->conditional_render_enabled)
+      genX(cmd_emit_conditional_render_predicate)(cmd_buffer);
+
+   bool uses_drawid = (task_prog_data && task_prog_data->uses_drawid) ||
+                       mesh_prog_data->uses_drawid;
+   struct mi_builder b;
+   mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
+
+   for (uint32_t i = 0; i < drawCount; i++) {
+      struct anv_address draw = anv_address_add(buffer->address, offset);
+
+      mesh_load_indirect_parameters_3dmesh_3d(cmd_buffer, &b, draw, 
uses_drawid, i);
+
+      emit_indirect_3dmesh_3d(&cmd_buffer->batch,
+            cmd_state->conditional_render_enabled, uses_drawid);
+
+      offset += stride;
+   }
+}
+
 void
 genX(CmdDrawMeshTasksIndirectCountNV)(
     VkCommandBuffer                             commandBuffer,
@@ -4685,13 +4789,59 @@ genX(CmdDrawMeshTasksIndirectCountNV)(
 
       emit_draw_count_predicate_cond(cmd_buffer, &b, i, max);
 
-      mesh_load_indirect_parameters(cmd_buffer, &b, draw, uses_drawid, i);
+      mesh_load_indirect_parameters_3dmesh_1d(cmd_buffer, &b, draw, 
uses_drawid, i);
 
       emit_indirect_3dmesh_1d(&cmd_buffer->batch, true, uses_drawid);
 
       offset += stride;
    }
 }
+
+void
+genX(CmdDrawMeshTasksIndirectCountEXT)(
+    VkCommandBuffer                             commandBuffer,
+    VkBuffer                                    _buffer,
+    VkDeviceSize                                offset,
+    VkBuffer                                    _countBuffer,
+    VkDeviceSize                                countBufferOffset,
+    uint32_t                                    maxDrawCount,
+    uint32_t                                    stride)
+{
+   ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
+   ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
+   ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer);
+   struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline;
+   const struct brw_task_prog_data *task_prog_data = 
get_task_prog_data(pipeline);
+   const struct brw_mesh_prog_data *mesh_prog_data = 
get_mesh_prog_data(pipeline);
+
+   if (anv_batch_has_error(&cmd_buffer->batch))
+      return;
+
+   genX(cmd_buffer_flush_state)(cmd_buffer);
+
+   bool uses_drawid = (task_prog_data && task_prog_data->uses_drawid) ||
+                       mesh_prog_data->uses_drawid;
+
+   struct mi_builder b;
+   mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch);
+
+   struct mi_value max =
+         prepare_for_draw_count_predicate(cmd_buffer, &b,
+                                          count_buffer, countBufferOffset);
+
+   for (uint32_t i = 0; i < maxDrawCount; i++) {
+      struct anv_address draw = anv_address_add(buffer->address, offset);
+
+      emit_draw_count_predicate_cond(cmd_buffer, &b, i, max);
+
+      mesh_load_indirect_parameters_3dmesh_3d(cmd_buffer, &b, draw, 
uses_drawid, i);
+
+      emit_indirect_3dmesh_3d(&cmd_buffer->batch, true, uses_drawid);
+
+      offset += stride;
+   }
+}
+
 #endif /* GFX_VERx10 >= 125 */
 
 void

Reply via email to