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

Author: Samuel Pitoiset <samuel.pitoi...@gmail.com>
Date:   Fri Oct 27 10:54:14 2023 +0200

radv: enable DGC preprocessing when all push constants are inlined

It's not possible when they aren't all inlined because they need to be
copied to the upload BO and the DGC shader also copies the ones that
come from the indirect layout.

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 | 28 +++++++++++++++++++++----
 src/amd/vulkan/radv_private.h                   |  2 +-
 3 files changed, 26 insertions(+), 6 deletions(-)

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)

Reply via email to