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 <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24776>
This commit is contained in:
Samuel Pitoiset
2023-08-18 17:30:04 +02:00
committed by Marge Bot
parent d65fe6eff1
commit 0004d903d4
4 changed files with 16 additions and 7 deletions
+10 -4
View 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;
+2 -1
View 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;
+2
View 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
+2 -2
View 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