summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcin Ślusarz <marcin.slusarz@intel.com>2021-07-16 15:06:44 +0200
committerMarge Bot <emma+marge@anholt.net>2022-02-02 18:17:57 +0000
commitbbde9f244869517b68b633c9a35d7740e007bc22 (patch)
tree1ebca41a71ba4f16a6e1a0348b0bda0770588afb /src
parent18e628135d24112ed57a1a49dd354857ba3346b1 (diff)
anv: Implement indirect dispatch for Mesh pipeline
Signed-off-by: Marcin Ślusarz <marcin.slusarz@intel.com> Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13662>
Diffstat (limited to 'src')
-rw-r--r--src/intel/vulkan/genX_cmd_buffer.c107
-rw-r--r--src/intel/vulkan/genX_pipeline.c4
2 files changed, 106 insertions, 5 deletions
diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c
index c0b6fc4d6a8..24ea3cf1781 100644
--- a/src/intel/vulkan/genX_cmd_buffer.c
+++ b/src/intel/vulkan/genX_cmd_buffer.c
@@ -4924,28 +4924,125 @@ genX(CmdDrawMeshTasksNV)(
}
}
+#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)
+{
+ const size_t taskCountOff = offsetof(VkDrawMeshTasksIndirectCommandNV, taskCount);
+ const size_t firstTaskOff = offsetof(VkDrawMeshTasksIndirectCommandNV, firstTask);
+
+ mi_store(b, mi_reg32(GFX125_3DMESH_TG_COUNT),
+ mi_mem32(anv_address_add(addr, taskCountOff)));
+
+ mi_store(b, mi_reg32(GFX125_3DMESH_STARTING_TGID),
+ mi_mem32(anv_address_add(addr, firstTaskOff)));
+
+ if (emit_xp0)
+ mi_store(b, mi_reg32(GFX10_3DPRIM_XP(0)), mi_imm(xp0));
+}
+
+static void
+emit_indirect_3dmesh_1d(struct anv_batch *batch,
+ bool predicate_enable,
+ bool uses_drawid)
+{
+ uint32_t len = GENX(3DMESH_1D_length) + uses_drawid;
+ anv_batch_emitn(batch, len, GENX(3DMESH_1D),
+ .PredicateEnable = predicate_enable,
+ .IndirectParameterEnable = true,
+ .ExtendedParameter0Present = uses_drawid);
+}
+
void
genX(CmdDrawMeshTasksIndirectNV)(
VkCommandBuffer commandBuffer,
- VkBuffer buffer,
+ VkBuffer _buffer,
VkDeviceSize offset,
uint32_t drawCount,
uint32_t stride)
{
- unreachable("Unimplemented");
+ 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(cmd_buffer, &b, draw, uses_drawid, i);
+
+ emit_indirect_3dmesh_1d(&cmd_buffer->batch,
+ cmd_state->conditional_render_enabled, uses_drawid);
+
+ offset += stride;
+ }
}
void
genX(CmdDrawMeshTasksIndirectCountNV)(
VkCommandBuffer commandBuffer,
- VkBuffer buffer,
+ VkBuffer _buffer,
VkDeviceSize offset,
- VkBuffer countBuffer,
+ VkBuffer _countBuffer,
VkDeviceSize countBufferOffset,
uint32_t maxDrawCount,
uint32_t stride)
{
- unreachable("Unimplemented");
+ 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(cmd_buffer, &b, draw, uses_drawid, i);
+
+ emit_indirect_3dmesh_1d(&cmd_buffer->batch, true, uses_drawid);
+
+ offset += stride;
+ }
}
#endif /* GFX_VERx10 >= 125 */
diff --git a/src/intel/vulkan/genX_pipeline.c b/src/intel/vulkan/genX_pipeline.c
index 8c806e90974..184b62ff236 100644
--- a/src/intel/vulkan/genX_pipeline.c
+++ b/src/intel/vulkan/genX_pipeline.c
@@ -2639,6 +2639,8 @@ emit_task_state(struct anv_graphics_pipeline *pipeline)
* of a buffer with push constants and descriptor set table.
*/
task.EmitInlineParameter = true;
+
+ task.XP0Required = task_prog_data->uses_drawid;
}
/* Recommended values from "Task and Mesh Distribution Programming". */
@@ -2710,6 +2712,8 @@ emit_mesh_state(struct anv_graphics_pipeline *pipeline)
* of a buffer with push constants and descriptor set table.
*/
mesh.EmitInlineParameter = true;
+
+ mesh.XP0Required = mesh_prog_data->uses_drawid;
}
/* Recommended values from "Task and Mesh Distribution Programming". */