radv: fix the per-patch data offset when TES isn't linked with TCS
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 18 Aug 2023 15:30:04 +0000 (17:30 +0200)
committerMarge Bot <emma+marge@anholt.net>
Thu, 24 Aug 2023 06:03:12 +0000 (06:03 +0000)
When TCS and TES aren't linked together and TCS exports unused outputs,
the per-patch data offset needs to be adjusted. This is similar to the
LS-HS vertex stride when VS and TCS aren't linked together.

This fixes a bunch of failures by forcing the driver to use TCS epilogs.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24776>

src/amd/vulkan/nir/radv_nir_lower_abi.c
src/amd/vulkan/radv_cmd_buffer.c
src/amd/vulkan/radv_shader.h
src/amd/vulkan/radv_shader_args.c

index cace173..9a11c21 100644 (file)
@@ -296,13 +296,18 @@ lower_abi_instr(nir_builder *b, nir_instr *instr, void *state)
       break;
    }
    case nir_intrinsic_load_hs_out_patch_data_offset_amd: {
-      nir_def *out_vertices_per_patch;
-      unsigned num_tcs_outputs =
-         stage == MESA_SHADER_TESS_CTRL ? s->info->tcs.num_linked_outputs : s->info->tes.num_linked_inputs;
+      nir_def *num_tcs_outputs, *out_vertices_per_patch;
 
       if (stage == MESA_SHADER_TESS_CTRL) {
+         num_tcs_outputs = nir_imm_int(b, s->info->tcs.num_linked_outputs);
          out_vertices_per_patch = nir_imm_int(b, s->info->tcs.tcs_vertices_out);
       } else {
+         if (s->info->inputs_linked) {
+            num_tcs_outputs = nir_imm_int(b, s->info->tes.num_linked_inputs);
+         } else {
+            num_tcs_outputs = GET_SGPR_FIELD_NIR(s->args->tes_state, TES_STATE_NUM_TCS_OUTPUTS);
+         }
+
          if (s->info->tes.tcs_vertices_out) {
             out_vertices_per_patch = nir_imm_int(b, s->info->tes.tcs_vertices_out);
          } else {
@@ -310,7 +315,8 @@ lower_abi_instr(nir_builder *b, nir_instr *instr, void *state)
          }
       }
 
-      nir_def *per_vertex_output_patch_size = nir_imul_imm(b, out_vertices_per_patch, num_tcs_outputs * 16u);
+      nir_def *per_vertex_output_patch_size =
+         nir_imul(b, out_vertices_per_patch, nir_imul_imm(b, num_tcs_outputs, 16u));
 
       if (s->info->num_tess_patches) {
          unsigned num_patches = s->info->num_tess_patches;
index 0529c9f..88232fc 100644 (file)
@@ -2579,7 +2579,8 @@ radv_emit_patch_control_points(struct radv_cmd_buffer *cmd_buffer)
    assert(num_patches->sgpr_idx != -1 && num_patches->num_sgprs == 1);
 
    const unsigned tes_state = SET_SGPR_FIELD(TES_STATE_NUM_PATCHES, cmd_buffer->state.tess_num_patches) |
-                              SET_SGPR_FIELD(TES_STATE_TCS_VERTICES_OUT, tcs->info.tcs.tcs_vertices_out);
+                              SET_SGPR_FIELD(TES_STATE_TCS_VERTICES_OUT, tcs->info.tcs.tcs_vertices_out) |
+                              SET_SGPR_FIELD(TES_STATE_NUM_TCS_OUTPUTS, tcs->info.tcs.num_linked_outputs);
 
    const struct radv_shader *tes = radv_get_shader(cmd_buffer->state.shaders, MESA_SHADER_TESS_EVAL);
    base_reg = tes->info.user_data_0;
index 9156f28..9c5114f 100644 (file)
@@ -208,6 +208,8 @@ enum radv_ud_index {
 #define TES_STATE_NUM_PATCHES__MASK       0xff
 #define TES_STATE_TCS_VERTICES_OUT__SHIFT 8
 #define TES_STATE_TCS_VERTICES_OUT__MASK  0xff
+#define TES_STATE_NUM_TCS_OUTPUTS__SHIFT  16
+#define TES_STATE_NUM_TCS_OUTPUTS__MASK   0xff
 
 #define PS_STATE_NUM_SAMPLES__SHIFT    0
 #define PS_STATE_NUM_SAMPLES__MASK     0xf
index 5008bd6..0b1908b 100644 (file)
@@ -360,8 +360,8 @@ radv_tcs_needs_state_sgpr(const struct radv_shader_info *info, const struct radv
 static bool
 radv_tes_needs_state_sgpr(const struct radv_shader_info *info)
 {
-   /* When the number of tessellation patches/TCS vertices out is 0, it's loaded from a SGPR. */
-   return !info->num_tess_patches || !info->tes.tcs_vertices_out;
+   /* Some values are loaded from a SGPR when dynamic states are used or when the shader is unlinked. */
+   return !info->num_tess_patches || !info->tes.tcs_vertices_out || !info->inputs_linked;
 }
 
 static bool