Module: Mesa Branch: main Commit: 0112a245f56d324db10cadd2a92f56ced0bcfbbf URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=0112a245f56d324db10cadd2a92f56ced0bcfbbf
Author: Samuel Pitoiset <samuel.pitoi...@gmail.com> Date: Thu Oct 26 16:36:11 2023 +0200 radv: add a helper to determine if it's possible to preprocess DGC Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25935> --- src/amd/vulkan/radv_cmd_buffer.c | 2 +- src/amd/vulkan/radv_device_generated_commands.c | 58 ++++++++++++++----------- src/amd/vulkan/radv_private.h | 5 ++- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 709de1256f6..d8707aac557 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -9550,7 +9550,7 @@ radv_CmdExecuteGeneratedCommandsNV(VkCommandBuffer commandBuffer, VkBool32 isPre cmd_buffer->state.predicating = true; } - if (!layout->use_preprocess) { + if (!radv_dgc_can_preprocess(layout)) { radv_prepare_dgc(cmd_buffer, pGeneratedCommandsInfo); cmd_buffer->state.flush_bits |= RADV_CMD_FLAG_CS_PARTIAL_FLUSH | RADV_CMD_FLAG_INV_VCACHE | RADV_CMD_FLAG_INV_L2; diff --git a/src/amd/vulkan/radv_device_generated_commands.c b/src/amd/vulkan/radv_device_generated_commands.c index bb8748601ba..7405dcd74a5 100644 --- a/src/amd/vulkan/radv_device_generated_commands.c +++ b/src/amd/vulkan/radv_device_generated_commands.c @@ -1286,6 +1286,7 @@ radv_CreateIndirectCommandsLayoutNV(VkDevice _device, const VkIndirectCommandsLa vk_object_base_init(&device->vk, &layout->base, VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NV); + layout->flags = pCreateInfo->flags; layout->pipeline_bind_point = pCreateInfo->pipelineBindPoint; layout->input_stride = pCreateInfo->pStreamStrides[0]; layout->token_count = pCreateInfo->tokenCount; @@ -1337,30 +1338,6 @@ radv_CreateIndirectCommandsLayoutNV(VkDevice _device, const VkIndirectCommandsLa if (!layout->indexed) layout->binds_index_buffer = false; - layout->use_preprocess = pCreateInfo->flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV; - - /* From the Vulkan spec (1.3.269, chapter 32): - * "The bound descriptor sets and push constants that will be used with indirect command generation for the compute - * piplines must already be specified at the time of preprocessing commands with vkCmdPreprocessGeneratedCommandsNV. - * They must not change until the execution of indirect commands is submitted with vkCmdExecuteGeneratedCommandsNV." - * - * So we can always preprocess compute layouts. - */ - if (layout->pipeline_bind_point != VK_PIPELINE_BIND_POINT_COMPUTE) { - /* We embed the index buffer extent in indirect draw packets, but that isn't available at preprocess time. */ - if (layout->indexed && !layout->binds_index_buffer) - layout->use_preprocess = false; - - /* VBO binding (in particular partial VBO binding) uses some draw state which we don't generate at preprocess time - * yet. */ - if (layout->bind_vbo_mask) - layout->use_preprocess = false; - - /* In preprocess we use the non-overridden push constants from the draw state for now. */ - if (layout->push_constant_mask) - layout->use_preprocess = false; - } - *pIndirectCommandsLayout = radv_indirect_command_layout_to_handle(layout); return VK_SUCCESS; } @@ -1415,6 +1392,37 @@ radv_use_dgc_predication(struct radv_cmd_buffer *cmd_buffer, const VkGeneratedCo return cmd_buffer->qf == RADV_QUEUE_GENERAL && seq_count_buffer && !cmd_buffer->state.predicating; } +bool +radv_dgc_can_preprocess(const struct radv_indirect_command_layout *layout) +{ + if (!(layout->flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV)) + return false; + + /* From the Vulkan spec (1.3.269, chapter 32): + * "The bound descriptor sets and push constants that will be used with indirect command generation for the compute + * piplines must already be specified at the time of preprocessing commands with vkCmdPreprocessGeneratedCommandsNV. + * They must not change until the execution of indirect commands is submitted with vkCmdExecuteGeneratedCommandsNV." + * + * So we can always preprocess compute layouts. + */ + if (layout->pipeline_bind_point != VK_PIPELINE_BIND_POINT_COMPUTE) { + /* We embed the index buffer extent in indirect draw packets, but that isn't available at preprocess time. */ + if (layout->indexed && !layout->binds_index_buffer) + return false; + + /* VBO binding (in particular partial VBO binding) uses some draw state which we don't generate at preprocess time + * yet. */ + if (layout->bind_vbo_mask) + return false; + + /* In preprocess we use the non-overridden push constants from the draw state for now. */ + if (layout->push_constant_mask) + return false; + } + + return true; +} + VKAPI_ATTR void VKAPI_CALL radv_CmdPreprocessGeneratedCommandsNV(VkCommandBuffer commandBuffer, const VkGeneratedCommandsInfoNV *pGeneratedCommandsInfo) @@ -1422,7 +1430,7 @@ radv_CmdPreprocessGeneratedCommandsNV(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); VK_FROM_HANDLE(radv_indirect_command_layout, layout, pGeneratedCommandsInfo->indirectCommandsLayout); - if (!layout->use_preprocess) + if (!radv_dgc_can_preprocess(layout)) return; const bool use_predication = radv_use_dgc_predication(cmd_buffer, pGeneratedCommandsInfo); diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index 69d601c45b4..db6cea9daea 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -3216,6 +3216,7 @@ void radv_sqtt_emit_relocated_shaders(struct radv_cmd_buffer *cmd_buffer, struct struct radv_indirect_command_layout { struct vk_object_base base; + VkIndirectCommandsLayoutUsageFlagsNV flags; VkPipelineBindPoint pipeline_bind_point; uint32_t input_stride; @@ -3240,8 +3241,6 @@ struct radv_indirect_command_layout { uint32_t ibo_type_32; uint32_t ibo_type_8; - bool use_preprocess; - VkIndirectCommandsLayoutTokenNV tokens[0]; }; @@ -3251,6 +3250,8 @@ bool radv_use_dgc_predication(struct radv_cmd_buffer *cmd_buffer, const VkGeneratedCommandsInfoNV *pGeneratedCommandsInfo); void radv_prepare_dgc(struct radv_cmd_buffer *cmd_buffer, const VkGeneratedCommandsInfoNV *pGeneratedCommandsInfo); +bool radv_dgc_can_preprocess(const struct radv_indirect_command_layout *layout); + static inline uint32_t si_conv_prim_to_gs_out(uint32_t topology, bool is_ngg) {