diff options
author | Marcin Ślusarz <marcin.slusarz@intel.com> | 2021-07-16 15:06:44 +0200 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2022-02-02 18:17:57 +0000 |
commit | bbde9f244869517b68b633c9a35d7740e007bc22 (patch) | |
tree | 1ebca41a71ba4f16a6e1a0348b0bda0770588afb /src | |
parent | 18e628135d24112ed57a1a49dd354857ba3346b1 (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.c | 107 | ||||
-rw-r--r-- | src/intel/vulkan/genX_pipeline.c | 4 |
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". */ |