radeonsi: get SPI_PS_INPUT_ENA from shader variant NIR for ACO
All PS lowering that changes, adds, or removes system values based on the shader key is done first, which is done in ac_nir_lower_ps_early and other passes, so now we just need to gather them. This should improve performance for ACO due to fewer VGPRs needed for optimized shader variants of PS. Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32910>
This commit is contained in:
@@ -2261,8 +2261,7 @@ static bool run_pre_link_optimization_passes(struct si_nir_shader_ctx *ctx)
|
||||
* The driver takes into account these things if they suddenly disappear
|
||||
* from the shader code:
|
||||
* - Register usage and code size decrease (obvious)
|
||||
* - Eliminated PS system values are disabled by LLVM
|
||||
* (FragCoord, FrontFace, barycentrics)
|
||||
* - Eliminated PS system values are disabled
|
||||
* - VS/TES/GS param exports are eliminated if they are undef.
|
||||
* The param space for eliminated outputs is also not allocated.
|
||||
* - VS/TCS/TES/GS/PS input loads are eliminated (VS relies on DCE in LLVM)
|
||||
@@ -2742,78 +2741,60 @@ static void si_fixup_spi_ps_input_config(struct si_shader *shader)
|
||||
}
|
||||
|
||||
static void
|
||||
si_set_spi_ps_input_config(struct si_shader *shader)
|
||||
si_get_shader_variant_info(struct si_shader *shader, nir_shader *nir)
|
||||
{
|
||||
const struct si_shader_selector *sel = shader->selector;
|
||||
const struct si_shader_info *info = &sel->info;
|
||||
const union si_shader_key *key = &shader->key;
|
||||
nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
|
||||
assert(shader->selector->info.base.use_aco_amd == nir->info.use_aco_amd);
|
||||
const BITSET_WORD *sysvals = nir->info.system_values_read;
|
||||
|
||||
/* TODO: This should be determined from the final NIR instead of the input NIR,
|
||||
* otherwise LLVM will have a performance advantage here because it determines
|
||||
* VGPR inputs for each shader variant after LLVM optimizations.
|
||||
*/
|
||||
uint8_t frag_coord_mask = info->reads_frag_coord_mask | info->reads_sample_pos_mask;
|
||||
/* ACO needs spi_ps_input_ena before si_init_shader_args. */
|
||||
if (nir->info.use_aco_amd) {
|
||||
/* Find out which frag coord components are used. */
|
||||
uint8_t frag_coord_mask = 0;
|
||||
|
||||
shader->config.spi_ps_input_ena =
|
||||
S_0286CC_PERSP_CENTER_ENA(info->uses_persp_center) |
|
||||
S_0286CC_PERSP_CENTROID_ENA(info->uses_persp_centroid) |
|
||||
S_0286CC_PERSP_SAMPLE_ENA(info->uses_persp_sample) |
|
||||
S_0286CC_LINEAR_CENTER_ENA(info->uses_linear_center) |
|
||||
S_0286CC_LINEAR_CENTROID_ENA(info->uses_linear_centroid) |
|
||||
S_0286CC_LINEAR_SAMPLE_ENA(info->uses_linear_sample) |
|
||||
S_0286CC_POS_X_FLOAT_ENA(!!(frag_coord_mask & 0x1) &&
|
||||
!key->ps.part.prolog.get_frag_coord_from_pixel_coord) |
|
||||
S_0286CC_POS_Y_FLOAT_ENA(!!(frag_coord_mask & 0x2) &&
|
||||
!key->ps.part.prolog.get_frag_coord_from_pixel_coord) |
|
||||
S_0286CC_POS_Z_FLOAT_ENA(!!(frag_coord_mask & 0x4)) |
|
||||
S_0286CC_POS_W_FLOAT_ENA(!!(frag_coord_mask & 0x8)) |
|
||||
S_0286CC_FRONT_FACE_ENA(info->uses_frontface && !key->ps.opt.force_front_face_input) |
|
||||
S_0286CC_SAMPLE_COVERAGE_ENA(info->reads_samplemask) |
|
||||
S_0286CC_ANCILLARY_ENA(info->uses_sampleid || info->uses_layer_id) |
|
||||
S_0286CC_POS_FIXED_PT_ENA(key->ps.part.prolog.get_frag_coord_from_pixel_coord);
|
||||
if (BITSET_TEST(sysvals, SYSTEM_VALUE_FRAG_COORD)) {
|
||||
nir_foreach_block(block, nir_shader_get_entrypoint(nir)) {
|
||||
nir_foreach_instr(instr, block) {
|
||||
if (instr->type == nir_instr_type_intrinsic) {
|
||||
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
|
||||
if (intr->intrinsic == nir_intrinsic_load_frag_coord ||
|
||||
intr->intrinsic == nir_intrinsic_load_sample_pos)
|
||||
frag_coord_mask |= nir_def_components_read(&intr->def);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key->ps.part.prolog.color_two_side)
|
||||
shader->config.spi_ps_input_ena |= S_0286CC_FRONT_FACE_ENA(1);
|
||||
shader->config.spi_ps_input_ena =
|
||||
S_0286CC_PERSP_SAMPLE_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_BARYCENTRIC_PERSP_SAMPLE)) |
|
||||
S_0286CC_PERSP_CENTER_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_BARYCENTRIC_PERSP_PIXEL)) |
|
||||
S_0286CC_PERSP_CENTROID_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_BARYCENTRIC_PERSP_CENTROID)) |
|
||||
S_0286CC_LINEAR_SAMPLE_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_BARYCENTRIC_LINEAR_SAMPLE)) |
|
||||
S_0286CC_LINEAR_CENTER_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_BARYCENTRIC_LINEAR_PIXEL)) |
|
||||
S_0286CC_LINEAR_CENTROID_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_BARYCENTRIC_LINEAR_CENTROID)) |
|
||||
S_0286CC_POS_X_FLOAT_ENA(!!(frag_coord_mask & 0x1)) |
|
||||
S_0286CC_POS_Y_FLOAT_ENA(!!(frag_coord_mask & 0x2)) |
|
||||
S_0286CC_POS_Z_FLOAT_ENA(!!(frag_coord_mask & 0x4)) |
|
||||
S_0286CC_POS_W_FLOAT_ENA(!!(frag_coord_mask & 0x8)) |
|
||||
S_0286CC_FRONT_FACE_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_FRONT_FACE) |
|
||||
BITSET_TEST(sysvals, SYSTEM_VALUE_FRONT_FACE_FSIGN)) |
|
||||
S_0286CC_ANCILLARY_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_SAMPLE_ID) |
|
||||
BITSET_TEST(sysvals, SYSTEM_VALUE_LAYER_ID)) |
|
||||
S_0286CC_SAMPLE_COVERAGE_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_SAMPLE_MASK_IN)) |
|
||||
S_0286CC_POS_FIXED_PT_ENA(BITSET_TEST(sysvals, SYSTEM_VALUE_PIXEL_COORD));
|
||||
|
||||
/* INTERP_MODE_COLOR, same as SMOOTH if flat shading is disabled. */
|
||||
if (info->uses_interp_color && !key->ps.part.prolog.flatshade_colors) {
|
||||
shader->config.spi_ps_input_ena |=
|
||||
S_0286CC_PERSP_SAMPLE_ENA(info->uses_persp_sample_color) |
|
||||
S_0286CC_PERSP_CENTER_ENA(info->uses_persp_center_color) |
|
||||
S_0286CC_PERSP_CENTROID_ENA(info->uses_persp_centroid_color);
|
||||
}
|
||||
|
||||
/* nir_lower_poly_line_smooth use nir_load_sample_mask_in */
|
||||
if (key->ps.mono.poly_line_smoothing)
|
||||
shader->config.spi_ps_input_ena |= S_0286CC_SAMPLE_COVERAGE_ENA(1);
|
||||
|
||||
/* nir_lower_point_smooth use nir_load_point_coord_maybe_flipped which is lowered
|
||||
* to nir_load_barycentric_pixel and nir_load_interpolated_input.
|
||||
*/
|
||||
if (key->ps.mono.point_smoothing)
|
||||
shader->config.spi_ps_input_ena |= S_0286CC_PERSP_CENTER_ENA(1);
|
||||
|
||||
/* See fetch_framebuffer() for used args when fbfetch output. */
|
||||
if (info->base.fs.uses_fbfetch_output) {
|
||||
shader->config.spi_ps_input_ena |= S_0286CC_POS_FIXED_PT_ENA(1);
|
||||
|
||||
if (key->ps.mono.fbfetch_layered || key->ps.mono.fbfetch_msaa)
|
||||
shader->config.spi_ps_input_ena |= S_0286CC_ANCILLARY_ENA(1);
|
||||
}
|
||||
|
||||
if (shader->is_monolithic) {
|
||||
si_set_spi_ps_input_config_for_separate_prolog(shader);
|
||||
si_fixup_spi_ps_input_config(shader);
|
||||
shader->config.spi_ps_input_addr = shader->config.spi_ps_input_ena;
|
||||
} else {
|
||||
/* Part mode will call si_fixup_spi_ps_input_config() when combining multi
|
||||
* shader part in si_shader_select_ps_parts().
|
||||
*
|
||||
* Reserve register locations for VGPR inputs the PS prolog may need.
|
||||
*/
|
||||
shader->config.spi_ps_input_addr =
|
||||
shader->config.spi_ps_input_ena |
|
||||
SI_SPI_PS_INPUT_ADDR_FOR_PROLOG;
|
||||
if (shader->is_monolithic) {
|
||||
si_fixup_spi_ps_input_config(shader);
|
||||
shader->config.spi_ps_input_addr = shader->config.spi_ps_input_ena;
|
||||
} else {
|
||||
/* Part mode will call si_fixup_spi_ps_input_config() when combining multi
|
||||
* shader part in si_shader_select_ps_parts().
|
||||
*
|
||||
* Reserve register locations for VGPR inputs the PS prolog may need.
|
||||
*/
|
||||
shader->config.spi_ps_input_addr = shader->config.spi_ps_input_ena |
|
||||
SI_SPI_PS_INPUT_ADDR_FOR_PROLOG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2862,6 +2843,8 @@ static void get_nir_shaders(struct si_shader *shader, struct si_linked_shaders *
|
||||
if (shader->is_monolithic)
|
||||
NIR_PASS_V(linked->consumer.nir, nir_recompute_io_bases, nir_var_shader_in);
|
||||
|
||||
si_get_shader_variant_info(shader, linked->consumer.nir);
|
||||
|
||||
struct si_shader_info info;
|
||||
si_nir_scan_shader(shader->selector->screen, linked->consumer.nir, &info,
|
||||
shader->is_monolithic);
|
||||
@@ -3025,10 +3008,6 @@ bool si_compile_shader(struct si_screen *sscreen, struct ac_llvm_compiler *compi
|
||||
|
||||
determine_shader_variant_info(sscreen, shader);
|
||||
|
||||
/* ACO need spi_ps_input in advance to init args and used in compiler. */
|
||||
if (sel->stage == MESA_SHADER_FRAGMENT && sel->info.base.use_aco_amd)
|
||||
si_set_spi_ps_input_config(shader);
|
||||
|
||||
struct si_linked_shaders linked;
|
||||
get_nir_shaders(shader, &linked);
|
||||
nir_shader *nir = linked.consumer.nir;
|
||||
|
||||
Reference in New Issue
Block a user