diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index ef934819f87..d9f68ba0272 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -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;