From 0004d903d4cc4d05cf9022bec0f863441744be30 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Fri, 18 Aug 2023 17:30:04 +0200 Subject: [PATCH] radv: fix the per-patch data offset when TES isn't linked with TCS 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 Part-of: --- src/amd/vulkan/nir/radv_nir_lower_abi.c | 14 ++++++++++---- src/amd/vulkan/radv_cmd_buffer.c | 3 ++- src/amd/vulkan/radv_shader.h | 2 ++ src/amd/vulkan/radv_shader_args.c | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/amd/vulkan/nir/radv_nir_lower_abi.c b/src/amd/vulkan/nir/radv_nir_lower_abi.c index cace173..9a11c21 100644 --- a/src/amd/vulkan/nir/radv_nir_lower_abi.c +++ b/src/amd/vulkan/nir/radv_nir_lower_abi.c @@ -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; diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 0529c9f..88232fc 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -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; diff --git a/src/amd/vulkan/radv_shader.h b/src/amd/vulkan/radv_shader.h index 9156f28..9c5114f 100644 --- a/src/amd/vulkan/radv_shader.h +++ b/src/amd/vulkan/radv_shader.h @@ -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 diff --git a/src/amd/vulkan/radv_shader_args.c b/src/amd/vulkan/radv_shader_args.c index 5008bd6..0b1908b 100644 --- a/src/amd/vulkan/radv_shader_args.c +++ b/src/amd/vulkan/radv_shader_args.c @@ -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 -- 2.7.4