From 231009be6570410112628533e92473e5e091b6a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 31 Dec 2024 10:11:23 -0500 Subject: [PATCH] ac/nir: return progress from ac_nir_lower_ps_early MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes the creation of barycentric coordinate variables to on-demand. Everything else is ready to return progress. Reviewed-by: Timur Kristóf Part-of: --- src/amd/common/nir/ac_nir.h | 2 +- src/amd/common/nir/ac_nir_lower_ps_early.c | 184 +++++++++------------ src/gallium/drivers/radeonsi/si_shader.c | 5 +- 3 files changed, 79 insertions(+), 112 deletions(-) diff --git a/src/amd/common/nir/ac_nir.h b/src/amd/common/nir/ac_nir.h index 5f75f84e948..cb3f69a27c7 100644 --- a/src/amd/common/nir/ac_nir.h +++ b/src/amd/common/nir/ac_nir.h @@ -298,7 +298,7 @@ typedef struct { bool kill_samplemask; } ac_nir_lower_ps_early_options; -void +bool ac_nir_lower_ps_early(nir_shader *nir, const ac_nir_lower_ps_early_options *options); typedef struct { diff --git a/src/amd/common/nir/ac_nir_lower_ps_early.c b/src/amd/common/nir/ac_nir_lower_ps_early.c index ceea3749a45..55d0ae49dc3 100644 --- a/src/amd/common/nir/ac_nir_lower_ps_early.c +++ b/src/amd/common/nir/ac_nir_lower_ps_early.c @@ -24,49 +24,65 @@ typedef struct { nir_variable *linear_center; nir_variable *linear_centroid; nir_variable *linear_sample; - bool lower_load_barycentric; bool seen_color0_alpha; } lower_ps_early_state; -static void -create_interp_param(nir_builder *b, lower_ps_early_state *s) +static nir_variable * +get_baryc_var_common(nir_builder *b, bool will_replace, nir_variable **var, const char *var_name) { - if (s->options->force_persp_sample_interp) { - s->persp_center = - nir_local_variable_create(b->impl, glsl_vec_type(2), "persp_center"); + if (will_replace) { + if (!*var) { + *var = nir_local_variable_create(b->impl, glsl_vec_type(2), var_name); + } + return *var; } + return NULL; +} - if (s->options->force_persp_sample_interp || - s->options->force_persp_center_interp) { - s->persp_centroid = - nir_local_variable_create(b->impl, glsl_vec_type(2), "persp_centroid"); +static nir_variable * +get_baryc_var(nir_builder *b, nir_intrinsic_op baryc_op, enum glsl_interp_mode mode, + lower_ps_early_state *s) +{ + switch (baryc_op) { + case nir_intrinsic_load_barycentric_pixel: + if (mode == INTERP_MODE_NOPERSPECTIVE) { + return get_baryc_var_common(b, s->options->force_linear_sample_interp, &s->linear_center, + "linear_center"); + } else { + return get_baryc_var_common(b, s->options->force_persp_sample_interp, &s->persp_center, + "persp_center"); + } + case nir_intrinsic_load_barycentric_centroid: + if (mode == INTERP_MODE_NOPERSPECTIVE) { + return get_baryc_var_common(b, s->options->force_linear_sample_interp || + s->options->force_linear_center_interp, &s->linear_centroid, + "linear_centroid"); + } else { + return get_baryc_var_common(b, s->options->force_persp_sample_interp || + s->options->force_persp_center_interp, &s->persp_centroid, + "persp_centroid"); + } + case nir_intrinsic_load_barycentric_sample: + if (mode == INTERP_MODE_NOPERSPECTIVE) { + return get_baryc_var_common(b, s->options->force_linear_center_interp, &s->linear_sample, + "linear_sample"); + } else { + return get_baryc_var_common(b, s->options->force_persp_center_interp, &s->persp_sample, + "persp_sample"); + } + default: + return NULL; } +} - if (s->options->force_persp_center_interp) { - s->persp_sample = - nir_local_variable_create(b->impl, glsl_vec_type(2), "persp_sample"); - } - - if (s->options->force_linear_sample_interp) { - s->linear_center = - nir_local_variable_create(b->impl, glsl_vec_type(2), "linear_center"); - } - - if (s->options->force_linear_sample_interp || - s->options->force_linear_center_interp) { - s->linear_centroid = - nir_local_variable_create(b->impl, glsl_vec_type(2), "linear_centroid"); - } - - if (s->options->force_linear_center_interp) { - s->linear_sample = - nir_local_variable_create(b->impl, glsl_vec_type(2), "linear_sample"); - } - - s->lower_load_barycentric = - s->persp_center || s->persp_centroid || s->persp_sample || - s->linear_center || s->linear_centroid || s->linear_sample; +static void +set_interp_vars(nir_builder *b, nir_def *new_baryc, nir_variable *baryc1, nir_variable *baryc2) +{ + if (baryc1) + nir_store_var(b, baryc1, new_baryc, 0x3); + if (baryc2) + nir_store_var(b, baryc2, new_baryc, 0x3); } static void @@ -75,83 +91,35 @@ init_interp_param(nir_builder *b, lower_ps_early_state *s) b->cursor = nir_before_cf_list(&b->impl->body); if (s->options->force_persp_sample_interp) { - nir_def *sample = - nir_load_barycentric_sample(b, 32, .interp_mode = INTERP_MODE_SMOOTH); - nir_store_var(b, s->persp_center, sample, 0x3); - nir_store_var(b, s->persp_centroid, sample, 0x3); + set_interp_vars(b, nir_load_barycentric_sample(b, 32, .interp_mode = INTERP_MODE_SMOOTH), + s->persp_center, s->persp_centroid); } if (s->options->force_linear_sample_interp) { - nir_def *sample = - nir_load_barycentric_sample(b, 32, .interp_mode = INTERP_MODE_NOPERSPECTIVE); - nir_store_var(b, s->linear_center, sample, 0x3); - nir_store_var(b, s->linear_centroid, sample, 0x3); + set_interp_vars(b, nir_load_barycentric_sample(b, 32, .interp_mode = INTERP_MODE_NOPERSPECTIVE), + s->linear_center, s->linear_centroid); } if (s->options->force_persp_center_interp) { - nir_def *center = - nir_load_barycentric_pixel(b, 32, .interp_mode = INTERP_MODE_SMOOTH); - nir_store_var(b, s->persp_sample, center, 0x3); - nir_store_var(b, s->persp_centroid, center, 0x3); + set_interp_vars(b, nir_load_barycentric_pixel(b, 32, .interp_mode = INTERP_MODE_SMOOTH), + s->persp_sample, s->persp_centroid); } if (s->options->force_linear_center_interp) { - nir_def *center = - nir_load_barycentric_pixel(b, 32, .interp_mode = INTERP_MODE_NOPERSPECTIVE); - nir_store_var(b, s->linear_sample, center, 0x3); - nir_store_var(b, s->linear_centroid, center, 0x3); + set_interp_vars(b, nir_load_barycentric_pixel(b, 32, .interp_mode = INTERP_MODE_NOPERSPECTIVE), + s->linear_sample, s->linear_centroid); } } static bool rewrite_ps_load_barycentric(nir_builder *b, nir_intrinsic_instr *intrin, lower_ps_early_state *s) { - enum glsl_interp_mode mode = nir_intrinsic_interp_mode(intrin); - nir_variable *var = NULL; - - switch (mode) { - case INTERP_MODE_NONE: - case INTERP_MODE_SMOOTH: - switch (intrin->intrinsic) { - case nir_intrinsic_load_barycentric_pixel: - var = s->persp_center; - break; - case nir_intrinsic_load_barycentric_centroid: - var = s->persp_centroid; - break; - case nir_intrinsic_load_barycentric_sample: - var = s->persp_sample; - break; - default: - break; - } - break; - - case INTERP_MODE_NOPERSPECTIVE: - switch (intrin->intrinsic) { - case nir_intrinsic_load_barycentric_pixel: - var = s->linear_center; - break; - case nir_intrinsic_load_barycentric_centroid: - var = s->linear_centroid; - break; - case nir_intrinsic_load_barycentric_sample: - var = s->linear_sample; - break; - default: - break; - } - break; - - default: - break; - } - - if (!var) + nir_variable *baryc_var = get_baryc_var(b, intrin->intrinsic, + nir_intrinsic_interp_mode(intrin), s); + if (!baryc_var) return false; - nir_def *replacement = nir_load_var(b, var); - nir_def_replace(&intrin->def, replacement); + nir_def_replace(&intrin->def, nir_load_var(b, baryc_var)); return true; } @@ -255,7 +223,8 @@ optimize_lower_ps_outputs(nir_builder *b, nir_intrinsic_instr *intrin, lower_ps_ } } - if (progress && intrin->src[0].ssa != value) { + if (intrin->src[0].ssa != value) { + assert(progress); nir_src_rewrite(&intrin->src[0], value); intrin->num_components = value->num_components; } else { @@ -384,9 +353,7 @@ lower_ps_intrinsic(nir_builder *b, nir_instr *instr, void *state) case nir_intrinsic_load_barycentric_pixel: case nir_intrinsic_load_barycentric_centroid: case nir_intrinsic_load_barycentric_sample: - if (s->lower_load_barycentric) - return rewrite_ps_load_barycentric(b, intrin, s); - break; + return rewrite_ps_load_barycentric(b, intrin, s); case nir_intrinsic_load_sample_mask_in: if (s->options->ps_iter_samples > 1) return lower_ps_load_sample_mask_in(b, intrin, s); @@ -467,7 +434,7 @@ lower_ps_intrinsic(nir_builder *b, nir_instr *instr, void *state) return false; } -void +bool ac_nir_lower_ps_early(nir_shader *nir, const ac_nir_lower_ps_early_options *options) { assert(nir->info.stage == MESA_SHADER_FRAGMENT); @@ -480,16 +447,17 @@ ac_nir_lower_ps_early(nir_shader *nir, const ac_nir_lower_ps_early_options *opti .options = options, }; - create_interp_param(b, &state); + bool progress = nir_shader_instructions_pass(nir, lower_ps_intrinsic, + nir_metadata_control_flow, &state); - nir_shader_instructions_pass(nir, lower_ps_intrinsic, - nir_metadata_control_flow, - &state); + if (state.persp_center || state.persp_centroid || state.persp_sample || + state.linear_center || state.linear_centroid || state.linear_sample) { + /* This must be after lower_ps_intrinsic. */ + init_interp_param(b, &state); - /* This must be after lower_ps_intrinsic. */ - init_interp_param(b, &state); + /* Cleanup local variables, as RADV won't do this. */ + NIR_PASS(_, nir, nir_lower_vars_to_ssa); + } - /* Cleanup local variables, as RADV won't do this. */ - if (state.lower_load_barycentric) - nir_lower_vars_to_ssa(nir); + return progress; } diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c index bb444f60be6..5b982461bb9 100644 --- a/src/gallium/drivers/radeonsi/si_shader.c +++ b/src/gallium/drivers/radeonsi/si_shader.c @@ -2549,7 +2549,7 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ .kill_samplemask = key->ps.part.epilog.kill_samplemask, }; - NIR_PASS_V(nir, ac_nir_lower_ps_early, &early_options); + NIR_PASS(progress, nir, ac_nir_lower_ps_early, &early_options); ac_nir_lower_ps_late_options late_options = { .gfx_level = sel->screen->info.gfx_level, @@ -2577,8 +2577,7 @@ static struct nir_shader *si_get_nir_shader(struct si_shader *shader, struct si_ .alpha_func = COMPARE_FUNC_ALWAYS, .spi_shader_col_format_hint = ~0, }; - NIR_PASS_V(nir, ac_nir_lower_ps_early, &early_options); - progress = true; + NIR_PASS(progress, nir, ac_nir_lower_ps_early, &early_options); } assert(shader->wave_size == 32 || shader->wave_size == 64);