From 159f22abbebfc75512d97c65f6a85ff04fcc196c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 9 May 2026 19:08:28 -0400 Subject: [PATCH] radeonsi: switch to nir_frag_coord_xy_z_w_separate with w_rcp FYI, ac_nir_lower_ps_early is only used by radeonsi. Reviewed-by: Samuel Pitoiset Acked-by: Pierre-Eric Pelloux-Prayer Part-of: --- .../nir/ac_nir_lower_intrinsics_to_args.c | 6 ------ src/amd/common/nir/ac_nir_lower_ps_early.c | 19 ++++++------------- .../drivers/radeonsi/gfx/si_gfx_screen.c | 1 + src/gallium/drivers/radeonsi/gfx/si_shader.c | 3 --- .../drivers/radeonsi/gfx/si_shader_info.c | 4 +++- .../radeonsi/gfx/si_shader_variant_info.c | 8 +++++++- 6 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/amd/common/nir/ac_nir_lower_intrinsics_to_args.c b/src/amd/common/nir/ac_nir_lower_intrinsics_to_args.c index 33fa9d1f6a3..db8cd7d251d 100644 --- a/src/amd/common/nir/ac_nir_lower_intrinsics_to_args.c +++ b/src/amd/common/nir/ac_nir_lower_intrinsics_to_args.c @@ -195,12 +195,6 @@ lower_intrinsic_to_arg(nir_builder *b, nir_intrinsic_instr *intrin, void *state) case nir_intrinsic_load_pixel_coord: replacement = nir_unpack_32_2x16(b, ac_nir_load_arg(b, s->args, s->args->pos_fixed_pt)); break; - case nir_intrinsic_load_frag_coord: - replacement = nir_vec4(b, ac_nir_load_arg(b, s->args, s->args->frag_pos[0]), - ac_nir_load_arg(b, s->args, s->args->frag_pos[1]), - ac_nir_load_arg(b, s->args, s->args->frag_pos[2]), - ac_nir_load_arg(b, s->args, s->args->frag_pos[3])); - break; case nir_intrinsic_load_frag_coord_xy: replacement = nir_vec2(b, ac_nir_load_arg(b, s->args, s->args->frag_pos[0]), ac_nir_load_arg(b, s->args, s->args->frag_pos[1])); 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 e9624662481..f073cb0e4c9 100644 --- a/src/amd/common/nir/ac_nir_lower_ps_early.c +++ b/src/amd/common/nir/ac_nir_lower_ps_early.c @@ -497,20 +497,15 @@ lower_ps_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin, void *state) return true; } break; - case nir_intrinsic_load_frag_coord: + case nir_intrinsic_load_frag_coord_xy: if (!s->options->optimize_frag_coord) break; /* Compute frag_coord.xy from pixel_coord. */ - if (!s->use_fragcoord && nir_def_components_read(&intrin->def) & 0x3) { + if (!s->use_fragcoord) { nir_def *new_fragcoord_xy = nir_u2f32(b, nir_load_pixel_coord(b)); if (!b->shader->info.fs.pixel_center_integer) new_fragcoord_xy = nir_fadd_imm(b, new_fragcoord_xy, 0.5); - nir_def *fragcoord = nir_build_frag_coord(b, 4); - nir_def_replace(&intrin->def, - nir_vec4(b, nir_channel(b, new_fragcoord_xy, 0), - nir_channel(b, new_fragcoord_xy, 1), - nir_channel(b, fragcoord, 2), - nir_channel(b, fragcoord, 3))); + nir_def_replace(&intrin->def, new_fragcoord_xy); return true; } break; @@ -521,8 +516,7 @@ lower_ps_intrinsic(nir_builder *b, nir_intrinsic_instr *intrin, void *state) * Instead, compute pixel_coord from frag_coord. */ if (s->use_fragcoord) { - nir_def *new_pixel_coord = nir_f2u16(b, nir_build_frag_coord(b, 2)); - nir_def_replace(&intrin->def, new_pixel_coord); + nir_def_replace(&intrin->def, nir_f2u16(b, nir_load_frag_coord_xy(b))); return true; } break; @@ -547,11 +541,10 @@ gather_info(nir_builder *b, nir_intrinsic_instr *intr, void *state) if (nir_intrinsic_io_semantics(intr).location == FRAG_RESULT_DUAL_SRC_BLEND) s->frag_color_is_frag_data0 = true; break; - case nir_intrinsic_load_frag_coord: + case nir_intrinsic_load_frag_coord_xy: assert(intr->def.bit_size == 32); nir_foreach_use(use, &intr->def) { - if (nir_src_use_instr(use)->type == nir_instr_type_alu && - nir_src_components_read(use) & 0x3) { + if (nir_src_use_instr(use)->type == nir_instr_type_alu) { switch (nir_instr_as_alu(nir_src_use_instr(use))->op) { case nir_op_f2i8: case nir_op_f2i16: diff --git a/src/gallium/drivers/radeonsi/gfx/si_gfx_screen.c b/src/gallium/drivers/radeonsi/gfx/si_gfx_screen.c index 161e948f8f3..19424bcdb34 100644 --- a/src/gallium/drivers/radeonsi/gfx/si_gfx_screen.c +++ b/src/gallium/drivers/radeonsi/gfx/si_gfx_screen.c @@ -340,6 +340,7 @@ static void si_init_screen_nir_options(struct si_screen *sscreen) sscreen->info.compiler_info.has_packed_math_16bit ? si_alu_to_scalar_packed_math_filter : NULL; options->max_unroll_iterations = 128; options->max_unroll_iterations_aggressive = 128; + options->frag_coord_form = nir_frag_coord_xy_z_w_separate | nir_frag_coord_use_w_rcp; /* For OpenGL, rounding mode is undefined. We want fast packing with v_cvt_pkrtz_f16, * but if we use it, all f32->f16 conversions have to round towards zero, * because both scalar and vec2 down-conversions have to round equally. diff --git a/src/gallium/drivers/radeonsi/gfx/si_shader.c b/src/gallium/drivers/radeonsi/gfx/si_shader.c index 34ce38e1884..8afb487640d 100644 --- a/src/gallium/drivers/radeonsi/gfx/si_shader.c +++ b/src/gallium/drivers/radeonsi/gfx/si_shader.c @@ -960,9 +960,6 @@ static void si_postprocess_nir(struct si_nir_shader_ctx *ctx) si_init_shader_args(shader, &ctx->args, &nir->info); - if (nir->info.stage == MESA_SHADER_FRAGMENT) - NIR_PASS(progress, nir, nir_lower_fragcoord_wtrans); - NIR_PASS(progress, nir, ac_nir_lower_tex_coords, &(ac_nir_lower_tex_coords_options){ .gfx_level = sel->screen->info.gfx_level, diff --git a/src/gallium/drivers/radeonsi/gfx/si_shader_info.c b/src/gallium/drivers/radeonsi/gfx/si_shader_info.c index c042c9d46ee..cf4ede9ca33 100644 --- a/src/gallium/drivers/radeonsi/gfx/si_shader_info.c +++ b/src/gallium/drivers/radeonsi/gfx/si_shader_info.c @@ -644,7 +644,9 @@ void si_nir_gather_info(struct si_screen *sscreen, struct nir_shader *nir, info->uses_interp_at_sample || nir->info.writes_memory || nir->info.fs.uses_fbfetch_output || nir->info.fs.needs_coarse_quad_helper_invocations || - BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_FRAG_COORD) || + BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_FRAG_COORD_XY) || + BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_FRAG_COORD_Z) || + BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_FRAG_COORD_W_RCP) || BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_POINT_COORD) || BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID) || BITSET_TEST(nir->info.system_values_read, SYSTEM_VALUE_SAMPLE_POS) || diff --git a/src/gallium/drivers/radeonsi/gfx/si_shader_variant_info.c b/src/gallium/drivers/radeonsi/gfx/si_shader_variant_info.c index ab3b885c71f..653c8ffdfe4 100644 --- a/src/gallium/drivers/radeonsi/gfx/si_shader_variant_info.c +++ b/src/gallium/drivers/radeonsi/gfx/si_shader_variant_info.c @@ -161,10 +161,16 @@ void si_get_shader_variant_info(struct si_shader *shader, case nir_intrinsic_load_draw_id: shader->info.uses_sysval_draw_id = true; break; - case nir_intrinsic_load_frag_coord: + case nir_intrinsic_load_frag_coord_xy: case nir_intrinsic_load_sample_pos: frag_coord_mask |= nir_def_components_read(&intr->def); break; + case nir_intrinsic_load_frag_coord_z: + frag_coord_mask |= BITFIELD_BIT(2); + break; + case nir_intrinsic_load_frag_coord_w_rcp: + frag_coord_mask |= BITFIELD_BIT(3); + break; case nir_intrinsic_load_input: case nir_intrinsic_load_input_vertex: case nir_intrinsic_load_per_vertex_input: