diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index d8707aac557..2deaa34eeb4 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 (!radv_dgc_can_preprocess(layout)) { + if (!radv_dgc_can_preprocess(layout, pipeline)) { 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 a5b1f54a912..729248c7931 100644 --- a/src/amd/vulkan/radv_device_generated_commands.c +++ b/src/amd/vulkan/radv_device_generated_commands.c @@ -1387,8 +1387,25 @@ 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; } +static bool +radv_dgc_need_push_constants_copy(const struct radv_pipeline *pipeline) +{ + for (unsigned i = 0; i < ARRAY_SIZE(pipeline->shaders); ++i) { + const struct radv_shader *shader = pipeline->shaders[i]; + + if (!shader) + continue; + + const struct radv_userdata_locations *locs = &shader->info.user_sgprs_locs; + if (locs->shader_data[AC_UD_PUSH_CONSTANTS].sgpr_idx >= 0) + return true; + } + + return false; +} + bool -radv_dgc_can_preprocess(const struct radv_indirect_command_layout *layout) +radv_dgc_can_preprocess(const struct radv_indirect_command_layout *layout, struct radv_pipeline *pipeline) { if (!(layout->flags & VK_INDIRECT_COMMANDS_LAYOUT_USAGE_EXPLICIT_PREPROCESS_BIT_NV)) return false; @@ -1410,8 +1427,10 @@ radv_dgc_can_preprocess(const struct radv_indirect_command_layout *layout) 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) + /* Do not preprocess when all push constants can't be inlined because they need to be copied + * to the upload BO. + */ + if (layout->push_constant_mask && radv_dgc_need_push_constants_copy(pipeline)) return false; } @@ -1424,8 +1443,9 @@ radv_CmdPreprocessGeneratedCommandsNV(VkCommandBuffer commandBuffer, { VK_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); VK_FROM_HANDLE(radv_indirect_command_layout, layout, pGeneratedCommandsInfo->indirectCommandsLayout); + VK_FROM_HANDLE(radv_pipeline, pipeline, pGeneratedCommandsInfo->pipeline); - if (!radv_dgc_can_preprocess(layout)) + if (!radv_dgc_can_preprocess(layout, pipeline)) 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 db6cea9daea..e8f63614f22 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -3250,7 +3250,7 @@ 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); +bool radv_dgc_can_preprocess(const struct radv_indirect_command_layout *layout, struct radv_pipeline *pipeline); static inline uint32_t si_conv_prim_to_gs_out(uint32_t topology, bool is_ngg)