radv: Use NIR IO semantics to determine FS input info.
This commit does two things at once, which cannot be split into two commits because otherwise the driver would regress in-between the two. Change radv_nir_shader_info_pass so that it uses I/O intrinsics instead of I/O variables for determining FS information. Also eliminate gaps between input slots caused by unused input variables. To this end, we use nir_recompute_io_bases after nir_lower_io instead of assigning driver locations before it. As part of this, we can now omit a clip/cull input when only the second one is used. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28506>
This commit is contained in:
@@ -75,10 +75,6 @@ radv_nir_lower_io(struct radv_device *device, nir_shader *nir)
|
||||
{
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
|
||||
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
|
||||
nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, MESA_SHADER_FRAGMENT);
|
||||
}
|
||||
|
||||
if (nir->info.stage == MESA_SHADER_VERTEX) {
|
||||
NIR_PASS(_, nir, nir_lower_io, nir_var_shader_in, type_size_vec4, 0);
|
||||
NIR_PASS(_, nir, nir_lower_io, nir_var_shader_out, type_size_vec4, nir_lower_io_lower_64bit_to_32);
|
||||
@@ -100,6 +96,13 @@ radv_nir_lower_io(struct radv_device *device, nir_shader *nir)
|
||||
*/
|
||||
nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs, nir->info.stage);
|
||||
}
|
||||
|
||||
if (nir->info.stage == MESA_SHADER_FRAGMENT) {
|
||||
/* Recompute FS input intrinsic bases to make sure that there are no gaps
|
||||
* between the FS input slots.
|
||||
*/
|
||||
nir_recompute_io_bases(nir, nir_var_shader_in);
|
||||
}
|
||||
}
|
||||
|
||||
/* IO slot layout for stages that aren't linked. */
|
||||
|
||||
@@ -3515,7 +3515,7 @@ radv_emit_ps_inputs(const struct radv_device *device, struct radeon_cmdbuf *ctx_
|
||||
if (ps->info.ps.has_pcoord)
|
||||
ps_input_cntl[ps_offset++] = S_028644_PT_SPRITE_TEX(1) | S_028644_OFFSET(0x20);
|
||||
|
||||
if (ps->info.ps.input_clips_culls_mask)
|
||||
if (ps->info.ps.input_clips_culls_mask & 0x0f)
|
||||
single_slot_to_ps_input(outinfo, VARYING_SLOT_CLIP_DIST0, ps_input_cntl, &ps_offset, true, false, false, false);
|
||||
|
||||
if (ps->info.ps.input_clips_culls_mask & 0xf0)
|
||||
|
||||
@@ -77,6 +77,55 @@ gather_load_vs_input_info(const nir_shader *nir, const nir_intrinsic_instr *intr
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gather_load_fs_input_info(const nir_shader *nir, const nir_intrinsic_instr *intrin, struct radv_shader_info *info,
|
||||
const struct radv_graphics_state_key *gfx_state)
|
||||
{
|
||||
const nir_io_semantics io_sem = nir_intrinsic_io_semantics(intrin);
|
||||
const unsigned location = io_sem.location;
|
||||
const unsigned mapped_location = nir_intrinsic_base(intrin);
|
||||
const unsigned attrib_count = io_sem.num_slots;
|
||||
const unsigned component = nir_intrinsic_component(intrin);
|
||||
|
||||
switch (location) {
|
||||
case VARYING_SLOT_CLIP_DIST0:
|
||||
info->ps.input_clips_culls_mask |= BITFIELD_RANGE(component, intrin->num_components);
|
||||
break;
|
||||
case VARYING_SLOT_CLIP_DIST1:
|
||||
info->ps.input_clips_culls_mask |= BITFIELD_RANGE(component, intrin->num_components) << 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const uint32_t mapped_mask = BITFIELD_RANGE(mapped_location, attrib_count);
|
||||
const bool per_primitive = nir->info.per_primitive_inputs & BITFIELD64_BIT(location);
|
||||
|
||||
if (intrin->def.bit_size == 16) {
|
||||
info->ps.float16_shaded_mask |= mapped_mask;
|
||||
}
|
||||
|
||||
if (!per_primitive) {
|
||||
if (intrin->intrinsic == nir_intrinsic_load_input) {
|
||||
info->ps.flat_shaded_mask |= mapped_mask;
|
||||
} else if (intrin->intrinsic == nir_intrinsic_load_input_vertex) {
|
||||
if (io_sem.interp_explicit_strict)
|
||||
info->ps.per_vertex_shaded_mask |= mapped_mask;
|
||||
else
|
||||
info->ps.explicit_shaded_mask |= mapped_mask;
|
||||
}
|
||||
}
|
||||
|
||||
if (location >= VARYING_SLOT_VAR0) {
|
||||
const uint32_t var_mask = BITFIELD_RANGE(location - VARYING_SLOT_VAR0, attrib_count);
|
||||
|
||||
if (per_primitive)
|
||||
info->ps.input_per_primitive_mask |= var_mask;
|
||||
else
|
||||
info->ps.input_mask |= var_mask;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gather_intrinsic_load_input_info(const nir_shader *nir, const nir_intrinsic_instr *instr, struct radv_shader_info *info,
|
||||
const struct radv_graphics_state_key *gfx_state,
|
||||
@@ -86,6 +135,9 @@ gather_intrinsic_load_input_info(const nir_shader *nir, const nir_intrinsic_inst
|
||||
case MESA_SHADER_VERTEX:
|
||||
gather_load_vs_input_info(nir, instr, info, gfx_state, stage_key);
|
||||
break;
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
gather_load_fs_input_info(nir, instr, info, gfx_state);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -255,6 +307,8 @@ gather_intrinsic_info(const nir_shader *nir, const nir_intrinsic_instr *instr, s
|
||||
break;
|
||||
}
|
||||
case nir_intrinsic_load_input:
|
||||
case nir_intrinsic_load_interpolated_input:
|
||||
case nir_intrinsic_load_input_vertex:
|
||||
gather_intrinsic_load_input_info(nir, instr, info, gfx_state, stage_key);
|
||||
break;
|
||||
case nir_intrinsic_store_output:
|
||||
@@ -316,28 +370,6 @@ gather_info_block(const nir_shader *nir, const nir_block *block, struct radv_sha
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mark_16bit_ps_input(struct radv_shader_info *info, const struct glsl_type *type, int location)
|
||||
{
|
||||
if (glsl_type_is_scalar(type) || glsl_type_is_vector(type) || glsl_type_is_matrix(type)) {
|
||||
unsigned attrib_count = glsl_count_attribute_slots(type, false);
|
||||
if (glsl_type_is_16bit(type)) {
|
||||
info->ps.float16_shaded_mask |= ((1ull << attrib_count) - 1) << location;
|
||||
}
|
||||
} else if (glsl_type_is_array(type)) {
|
||||
unsigned stride = glsl_count_attribute_slots(glsl_get_array_element(type), false);
|
||||
for (unsigned i = 0; i < glsl_get_length(type); ++i) {
|
||||
mark_16bit_ps_input(info, glsl_get_array_element(type), location + i * stride);
|
||||
}
|
||||
} else {
|
||||
assert(glsl_type_is_struct_or_ifc(type));
|
||||
for (unsigned i = 0; i < glsl_get_length(type); i++) {
|
||||
mark_16bit_ps_input(info, glsl_get_struct_field(type, i), location);
|
||||
location += glsl_count_attribute_slots(glsl_get_struct_field(type, i), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gather_xfb_info(const nir_shader *nir, struct radv_shader_info *info)
|
||||
{
|
||||
@@ -865,18 +897,19 @@ gather_shader_info_fs(const struct radv_device *device, const nir_shader *nir,
|
||||
const struct radv_graphics_state_key *gfx_state, struct radv_shader_info *info)
|
||||
{
|
||||
const struct radv_physical_device *pdev = radv_device_physical(device);
|
||||
uint64_t per_primitive_input_mask = nir->info.inputs_read & nir->info.per_primitive_inputs;
|
||||
unsigned num_per_primitive_inputs = util_bitcount64(per_primitive_input_mask);
|
||||
assert(num_per_primitive_inputs <= nir->num_inputs);
|
||||
const uint64_t per_primitive_input_mask = nir->info.inputs_read & nir->info.per_primitive_inputs;
|
||||
const unsigned num_per_primitive_inputs = util_bitcount64(per_primitive_input_mask);
|
||||
const unsigned num_inputs = util_bitcount64(nir->info.inputs_read);
|
||||
assert(num_per_primitive_inputs <= num_inputs);
|
||||
|
||||
info->ps.num_interp = nir->num_inputs;
|
||||
info->ps.num_interp = num_inputs;
|
||||
info->ps.num_prim_interp = 0;
|
||||
|
||||
if (pdev->info.gfx_level == GFX10_3) {
|
||||
/* GFX10.3 distinguishes NUM_INTERP and NUM_PRIM_INTERP, but
|
||||
* these are counted together in NUM_INTERP on GFX11.
|
||||
*/
|
||||
info->ps.num_interp = nir->num_inputs - num_per_primitive_inputs;
|
||||
info->ps.num_interp = num_inputs - num_per_primitive_inputs;
|
||||
info->ps.num_prim_interp = num_per_primitive_inputs;
|
||||
}
|
||||
|
||||
@@ -940,52 +973,6 @@ gather_shader_info_fs(const struct radv_device *device, const nir_shader *nir,
|
||||
info->ps.writes_mrt0_alpha = gfx_state->ms.alpha_to_coverage_via_mrtz && export_alpha_and_mrtz;
|
||||
}
|
||||
|
||||
nir_foreach_shader_in_variable (var, nir) {
|
||||
const struct glsl_type *type = var->data.per_vertex ? glsl_get_array_element(var->type) : var->type;
|
||||
unsigned attrib_count = glsl_count_attribute_slots(type, false);
|
||||
int idx = var->data.location;
|
||||
|
||||
switch (idx) {
|
||||
case VARYING_SLOT_CLIP_DIST0:
|
||||
if (nir->info.inputs_read & VARYING_BIT_CLIP_DIST0)
|
||||
info->ps.input_clips_culls_mask |= BITFIELD_RANGE(0, attrib_count);
|
||||
if (attrib_count > 4 && (nir->info.inputs_read & VARYING_BIT_CLIP_DIST1))
|
||||
info->ps.input_clips_culls_mask |= BITFIELD_RANGE(4, attrib_count);
|
||||
break;
|
||||
case VARYING_SLOT_CLIP_DIST1:
|
||||
if (nir->info.inputs_read & VARYING_BIT_CLIP_DIST1)
|
||||
info->ps.input_clips_culls_mask |= BITFIELD_RANGE(4, attrib_count);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (var->data.compact) {
|
||||
unsigned component_count = var->data.location_frac + glsl_get_length(var->type);
|
||||
attrib_count = (component_count + 3) / 4;
|
||||
} else {
|
||||
mark_16bit_ps_input(info, type, var->data.driver_location);
|
||||
}
|
||||
|
||||
uint64_t mask = ((1ull << attrib_count) - 1);
|
||||
|
||||
if (!var->data.per_primitive) {
|
||||
if (var->data.interpolation == INTERP_MODE_FLAT)
|
||||
info->ps.flat_shaded_mask |= mask << var->data.driver_location;
|
||||
else if (var->data.interpolation == INTERP_MODE_EXPLICIT)
|
||||
info->ps.explicit_shaded_mask |= mask << var->data.driver_location;
|
||||
else if (var->data.per_vertex)
|
||||
info->ps.per_vertex_shaded_mask |= mask << var->data.driver_location;
|
||||
}
|
||||
|
||||
if (var->data.location >= VARYING_SLOT_VAR0) {
|
||||
if (var->data.per_primitive)
|
||||
info->ps.input_per_primitive_mask |= mask << (var->data.location - VARYING_SLOT_VAR0);
|
||||
else
|
||||
info->ps.input_mask |= mask << (var->data.location - VARYING_SLOT_VAR0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable VRS and use the rates from PS_ITER_SAMPLES if:
|
||||
*
|
||||
* - The fragment shader reads gl_SampleMaskIn because the 16-bit sample coverage mask isn't enough for MSAA8x and
|
||||
|
||||
Reference in New Issue
Block a user