mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-06-18 04:18:23 +02:00
ac/nir/tess: Emit tess factor stores based on new intrinsics.
This allows the TCS to read the primitive mode and whether TES reads the tess factors, from an SGPR arg, which lets it decide how to store them at runtime. For linked shaders, the conditions will be constant and NIR optimizations can delete the dead CF. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Marek Olšák <marek.olsak@amd.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28408>
This commit is contained in:
parent
476a42c02c
commit
508f293b14
4 changed files with 46 additions and 16 deletions
|
|
@ -123,7 +123,6 @@ void
|
|||
ac_nir_lower_hs_outputs_to_mem(nir_shader *shader,
|
||||
ac_nir_map_io_driver_location map,
|
||||
enum amd_gfx_level gfx_level,
|
||||
bool tes_reads_tessfactors,
|
||||
uint64_t tes_inputs_read,
|
||||
uint64_t tes_patch_inputs_read,
|
||||
unsigned num_reserved_tcs_outputs,
|
||||
|
|
|
|||
|
|
@ -122,9 +122,6 @@ typedef struct {
|
|||
uint64_t tes_inputs_read;
|
||||
uint64_t tes_patch_inputs_read;
|
||||
|
||||
/* Whether TES reads the tess factors. */
|
||||
bool tes_reads_tessfactors;
|
||||
|
||||
unsigned tcs_num_reserved_outputs;
|
||||
unsigned tcs_num_reserved_patch_outputs;
|
||||
|
||||
|
|
@ -599,6 +596,21 @@ hs_store_dynamic_control_word_gfx6(nir_builder *b)
|
|||
nir_pop_if(b, rel_patch_id_zero);
|
||||
}
|
||||
|
||||
static nir_def *
|
||||
hs_resize_tess_factor(nir_builder *b, nir_def *tf, unsigned comps)
|
||||
{
|
||||
if (!comps)
|
||||
return NULL;
|
||||
else if (!tf)
|
||||
return nir_imm_zero(b, comps, 32);
|
||||
else if (comps > tf->num_components)
|
||||
return nir_pad_vector_imm_int(b, tf, 0, comps);
|
||||
else if (comps < tf->num_components)
|
||||
return nir_trim_vector(b, tf, comps);
|
||||
else
|
||||
return tf;
|
||||
}
|
||||
|
||||
static void
|
||||
hs_store_tess_factors_for_tessellator(nir_builder *b, enum amd_gfx_level gfx_level,
|
||||
enum tess_primitive_mode prim_mode,
|
||||
|
|
@ -617,21 +629,24 @@ hs_store_tess_factors_for_tessellator(nir_builder *b, enum amd_gfx_level gfx_lev
|
|||
nir_def *tess_factors_offset =
|
||||
nir_imul_imm(b, rel_patch_id, (inner_comps + outer_comps) * 4u);
|
||||
|
||||
nir_def *tf_outer = hs_resize_tess_factor(b, tessfactors.outer, outer_comps);
|
||||
nir_def *tf_inner = hs_resize_tess_factor(b, tessfactors.inner, inner_comps);
|
||||
|
||||
/* Store tess factors for the tessellator */
|
||||
if (prim_mode == TESS_PRIMITIVE_ISOLINES) {
|
||||
/* LINES reversal */
|
||||
nir_def *t = nir_vec2(b, nir_channel(b, tessfactors.outer, 1), nir_channel(b, tessfactors.outer, 0));
|
||||
nir_def *t = nir_vec2(b, nir_channel(b, tf_outer, 1), nir_channel(b, tf_outer, 0));
|
||||
nir_store_buffer_amd(b, t, tessfactor_ring, tess_factors_offset, tess_factors_base, zero,
|
||||
.base = tess_factors_const_offset, .access = ACCESS_COHERENT);
|
||||
} else if (prim_mode == TESS_PRIMITIVE_TRIANGLES) {
|
||||
nir_def *t = nir_vec4(b, nir_channel(b, tessfactors.outer, 0), nir_channel(b, tessfactors.outer, 1),
|
||||
nir_channel(b, tessfactors.outer, 2), nir_channel(b, tessfactors.inner, 0));
|
||||
nir_def *t = nir_vec4(b, nir_channel(b, tf_outer, 0), nir_channel(b, tf_outer, 1),
|
||||
nir_channel(b, tf_outer, 2), nir_channel(b, tf_inner, 0));
|
||||
nir_store_buffer_amd(b, t, tessfactor_ring, tess_factors_offset, tess_factors_base, zero,
|
||||
.base = tess_factors_const_offset, .access = ACCESS_COHERENT);
|
||||
} else {
|
||||
nir_store_buffer_amd(b, tessfactors.outer, tessfactor_ring, tess_factors_offset, tess_factors_base, zero,
|
||||
nir_store_buffer_amd(b, tf_outer, tessfactor_ring, tess_factors_offset, tess_factors_base, zero,
|
||||
.base = tess_factors_const_offset, .access = ACCESS_COHERENT);
|
||||
nir_store_buffer_amd(b, tessfactors.inner, tessfactor_ring, tess_factors_offset, tess_factors_base, zero,
|
||||
nir_store_buffer_amd(b, tf_inner, tessfactor_ring, tess_factors_offset, tess_factors_base, zero,
|
||||
.base = tess_factors_const_offset + 4u * outer_comps, .access = ACCESS_COHERENT);
|
||||
}
|
||||
}
|
||||
|
|
@ -719,10 +734,30 @@ hs_finale(nir_shader *shader,
|
|||
if (st->gfx_level <= GFX8)
|
||||
hs_store_dynamic_control_word_gfx6(b);
|
||||
|
||||
hs_store_tess_factors_for_tessellator(b, st->gfx_level, b->shader->info.tess._primitive_mode, tessfactors);
|
||||
nir_def *prim_mode = nir_load_tcs_primitive_mode_amd(b);
|
||||
nir_if *if_triangles = nir_push_if(b, nir_ieq_imm(b, prim_mode, TESS_PRIMITIVE_TRIANGLES));
|
||||
{
|
||||
hs_store_tess_factors_for_tessellator(b, st->gfx_level, TESS_PRIMITIVE_TRIANGLES, tessfactors);
|
||||
}
|
||||
nir_push_else(b, if_triangles);
|
||||
{
|
||||
nir_if *if_isolines = nir_push_if(b, nir_ieq_imm(b, prim_mode, TESS_PRIMITIVE_ISOLINES));
|
||||
{
|
||||
hs_store_tess_factors_for_tessellator(b, st->gfx_level, TESS_PRIMITIVE_ISOLINES, tessfactors);
|
||||
}
|
||||
nir_push_else(b, if_isolines);
|
||||
{
|
||||
hs_store_tess_factors_for_tessellator(b, st->gfx_level, TESS_PRIMITIVE_QUADS, tessfactors);
|
||||
}
|
||||
nir_pop_if(b, if_isolines);
|
||||
}
|
||||
nir_pop_if(b, if_triangles);
|
||||
|
||||
if (st->tes_reads_tessfactors)
|
||||
nir_if *if_tes_reads_tf = nir_push_if(b, nir_load_tcs_tess_levels_to_tes_amd(b));
|
||||
{
|
||||
hs_store_tess_factors_for_tes(b, tessfactors, st);
|
||||
}
|
||||
nir_pop_if(b, if_tes_reads_tf);
|
||||
}
|
||||
|
||||
if (if_invocation_id_zero) {
|
||||
|
|
@ -851,7 +886,6 @@ void
|
|||
ac_nir_lower_hs_outputs_to_mem(nir_shader *shader,
|
||||
ac_nir_map_io_driver_location map,
|
||||
enum amd_gfx_level gfx_level,
|
||||
bool tes_reads_tessfactors,
|
||||
uint64_t tes_inputs_read,
|
||||
uint64_t tes_patch_inputs_read,
|
||||
unsigned num_reserved_tcs_outputs,
|
||||
|
|
@ -866,7 +900,6 @@ ac_nir_lower_hs_outputs_to_mem(nir_shader *shader,
|
|||
|
||||
lower_tess_io_state state = {
|
||||
.gfx_level = gfx_level,
|
||||
.tes_reads_tessfactors = tes_reads_tessfactors,
|
||||
.tes_inputs_read = tes_inputs_read,
|
||||
.tes_patch_inputs_read = tes_patch_inputs_read,
|
||||
.tcs_num_reserved_outputs = num_reserved_tcs_outputs,
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ radv_nir_lower_io_to_mem(struct radv_device *device, struct radv_shader_stage *s
|
|||
} else if (nir->info.stage == MESA_SHADER_TESS_CTRL) {
|
||||
NIR_PASS_V(nir, ac_nir_lower_hs_inputs_to_mem, map_input, info->vs.tcs_in_out_eq);
|
||||
NIR_PASS_V(nir, ac_nir_lower_hs_outputs_to_mem, map_output, device->physical_device->rad_info.gfx_level,
|
||||
info->tcs.tes_reads_tess_factors, info->tcs.tes_inputs_read, info->tcs.tes_patch_inputs_read,
|
||||
info->tcs.tes_inputs_read, info->tcs.tes_patch_inputs_read,
|
||||
info->tcs.num_linked_outputs, info->tcs.num_linked_patch_outputs, info->wave_size, false, false,
|
||||
!info->has_epilog, info->has_epilog);
|
||||
|
||||
|
|
|
|||
|
|
@ -1823,8 +1823,6 @@ static bool si_lower_io_to_mem(struct si_shader *shader, nir_shader *nir,
|
|||
|
||||
NIR_PASS_V(nir, ac_nir_lower_hs_outputs_to_mem, si_map_io_driver_location,
|
||||
sel->screen->info.gfx_level,
|
||||
/* Used by hs_emit_write_tess_factors() when monolithic shader. */
|
||||
key->ge.part.tcs.epilog.tes_reads_tess_factors,
|
||||
~0ULL, ~0ULL, /* no TES inputs filter */
|
||||
util_last_bit64(sel->info.outputs_written_before_tes_gs),
|
||||
util_last_bit64(sel->info.patch_outputs_written),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue