pan/compiler: Replace frag_coord_zw_pan with var_special_pan
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

Just a bit cleaner, and we can unify point size too.

Signed-off-by: Lorenzo Rossi <lorenzo.rossi@collabora.com>
Reviewed-by: Christoph Pillmayer <christoph.pillmayer@arm.com>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/40677>
This commit is contained in:
Lorenzo Rossi 2026-03-27 16:19:52 +01:00 committed by Marge Bot
parent 5be2b03b88
commit c0e0591999
10 changed files with 77 additions and 59 deletions

View file

@ -861,6 +861,7 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
case nir_intrinsic_load_barycentric_coord_at_offset:
case nir_intrinsic_load_var_pan:
case nir_intrinsic_load_var_buf_pan:
case nir_intrinsic_load_var_special_pan:
case nir_intrinsic_load_persp_center_rhw_ir3:
case nir_intrinsic_load_input_attachment_coord:
case nir_intrinsic_interp_deref_at_offset:
@ -874,7 +875,6 @@ visit_intrinsic(nir_intrinsic_instr *instr, struct divergence_state *state)
case nir_intrinsic_load_frag_coord:
case nir_intrinsic_load_frag_coord_z:
case nir_intrinsic_load_frag_coord_w:
case nir_intrinsic_load_frag_coord_zw_pan:
case nir_intrinsic_load_frag_coord_unscaled_ir3:
case nir_intrinsic_load_frag_coord_gmem_ir3:
case nir_intrinsic_load_pixel_coord:

View file

@ -1671,6 +1671,13 @@ load("var_buf_pan", [1, 2], [SRC_TYPE, IO_SEMANTICS], [CAN_ELIMINATE, CAN_REORDE
# src[] = { offset }
load("var_buf_flat_pan", [1], [SRC_TYPE, IO_SEMANTICS], [CAN_ELIMINATE, CAN_REORDER])
# Panfrost-specific intrinsic to load special varyings, can load point coords
# and frag_[zw] at specific barycentric coordinates.
# src[] = { barycoord }
# FLAGS is enum bi_varying_name
intrinsic("load_var_special_pan", src_comp=[2], dest_comp=0, bit_sizes=[32],
indices=[FLAGS], flags=[CAN_ELIMINATE, CAN_REORDER])
# Panfrost-specific intrinsic to load the shader_output special-FAU value on 5th Gen.
intrinsic("load_shader_output_pan", dest_comp=1, src_comp=[], bit_sizes=[32],
indices=[], flags=[CAN_REORDER, CAN_ELIMINATE])
@ -1705,11 +1712,6 @@ store("raw_output_pan", [], [IO_SEMANTICS, BASE])
store("combined_output_pan", [1, 1, 1, 4], [IO_SEMANTICS, COMPONENT, SRC_TYPE, DEST_TYPE])
load("raw_output_pan", [1], [IO_SEMANTICS], [CAN_ELIMINATE, CAN_REORDER])
# Like the frag_coord_zw intrinsic, but takes a barycentric. This is needed for
# noperspective lowering.
# src[] = { barycoord }
intrinsic("load_frag_coord_zw_pan", [2], dest_comp=1, indices=[COMPONENT], flags=[CAN_ELIMINATE, CAN_REORDER], bit_sizes=[32])
# Loads the sampler paramaters <min_lod, max_lod, lod_bias>
# src[] = { sampler_index }
load("sampler_lod_parameters", [1], flags=[CAN_ELIMINATE, CAN_REORDER])

View file

@ -248,7 +248,7 @@ can_sink_instr(nir_instr *instr, nir_move_options options, bool *can_mov_out_of_
case nir_intrinsic_load_frag_coord:
case nir_intrinsic_load_frag_coord_z:
case nir_intrinsic_load_frag_coord_w:
case nir_intrinsic_load_frag_coord_zw_pan:
case nir_intrinsic_load_var_special_pan:
case nir_intrinsic_load_pixel_coord:
*can_mov_out_of_loop = true;
return options & nir_move_load_frag_coord;

View file

@ -143,6 +143,8 @@ panfrost_shader_compile(struct panfrost_screen *screen, const nir_shader *ir,
NIR_PASS(_, s, nir_lower_texcoord_replace_late,
key->fs.sprite_coord_enable,
true /* point coord is sysval */);
/* Lower load_point_coord if present */
NIR_PASS(_, s, pan_nir_lower_var_special_pan);
}
if (key->fs.clip_plane_enable) {

View file

@ -1729,23 +1729,28 @@ bi_emit_atomic_i32_to(bi_builder *b, bi_index dst, bi_index addr, bi_index arg,
}
static void
bi_emit_load_frag_coord_zw_pan(bi_builder *b, nir_intrinsic_instr *instr)
bi_emit_load_var_special_pan(bi_builder *b, nir_intrinsic_instr *instr)
{
bi_index dst = bi_def_index(&instr->def);
unsigned channel = nir_intrinsic_component(instr);
enum bi_varying_name var_name = nir_intrinsic_flags(instr);
nir_intrinsic_instr *bary = nir_src_as_intrinsic(instr->src[0]);
enum bi_sample sample = bi_interp_for_intrinsic(bary->intrinsic);
bi_index src0 = bi_varying_src0_for_barycentric(b, bary);
unsigned nr = instr->num_components;
assert(instr->def.bit_size == 32);
/* .explicit is not supported with frag_z */
if (channel == 2)
if (var_name == BI_VARYING_NAME_FRAG_Z)
assert(sample != BI_SAMPLE_EXPLICIT);
/* TODO: v10 adds BI_UPDATE_NONE and v14 introduces store/retrieve updates
* and the barycentric coordinate special varying */
bi_ld_var_special_to(
b, dst, src0, BI_REGISTER_FORMAT_F32, sample, BI_UPDATE_CLOBBER,
(channel == 2) ? BI_VARYING_NAME_FRAG_Z : BI_VARYING_NAME_FRAG_W,
BI_VECSIZE_NONE);
(enum bi_varying_name) var_name, nr - 1);
bi_emit_cached_split_i32(b, dst, nr);
}
static void
@ -2179,10 +2184,6 @@ bi_emit_intrinsic(bi_builder *b, nir_intrinsic_instr *instr)
bi_mov_i32_to(b, dst, bi_preload(b, 59));
break;
case nir_intrinsic_load_frag_coord_zw_pan:
bi_emit_load_frag_coord_zw_pan(b, instr);
break;
case nir_intrinsic_load_texel_buf_conv_pan:
assert(b->shader->arch >= 9 &&
"conv desc is loaded with the texel_buf_addr on Bifrost");
@ -2269,11 +2270,8 @@ bi_emit_intrinsic(bi_builder *b, nir_intrinsic_instr *instr)
break;
}
case nir_intrinsic_load_point_coord:
bi_ld_var_special_to(b, dst, bi_zero(), BI_REGISTER_FORMAT_F32,
BI_SAMPLE_CENTER, BI_UPDATE_CLOBBER,
BI_VARYING_NAME_POINT, BI_VECSIZE_V2);
bi_emit_cached_split_i32(b, dst, 2);
case nir_intrinsic_load_var_special_pan:
bi_emit_load_var_special_pan(b, instr);
break;
/* It appears vertex_id is zero-based with Bifrost geometry flows, but
@ -6183,7 +6181,7 @@ bifrost_postprocess_nir(nir_shader *nir, unsigned gpu_id)
NIR_PASS(_, nir, nir_lower_var_copies);
NIR_PASS(_, nir, nir_lower_alu);
NIR_PASS(_, nir, nir_lower_frag_coord_to_pixel_coord);
NIR_PASS(_, nir, pan_nir_lower_frag_coord_zw);
NIR_PASS(_, nir, pan_nir_lower_var_special_pan);
}
void bifrost_lower_texture_nir(nir_shader *nir, unsigned gpu_id)

View file

@ -6,7 +6,7 @@ libpanfrost_compiler_files = files(
'pan_compiler.h',
'pan_nir_collect_varyings.c',
'pan_nir_lower_bool_to_bitsize.c',
'pan_nir_lower_frag_coord_zw.c',
'pan_nir_lower_var_special.c',
'pan_nir_lower_framebuffer.c',
'pan_nir_lower_fs_inputs.c',
'pan_nir_lower_fs_outputs.c',

View file

@ -51,7 +51,7 @@ bool pan_nir_lower_vertex_id(nir_shader *shader);
bool pan_nir_lower_image_ms(nir_shader *shader);
bool pan_nir_lower_frag_coord_zw(nir_shader *shader);
bool pan_nir_lower_var_special_pan(nir_shader *shader);
bool pan_nir_lower_noperspective_vs(nir_shader *shader);
bool pan_nir_lower_noperspective_fs(nir_shader *shader);

View file

@ -1,34 +0,0 @@
/*
* Copyright © 2024 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#include "compiler/nir/nir_builder.h"
#include "pan_nir.h"
/* Lowers nir_load_frag_coord_zw to nir_load_frag_coord_zw_pan. */
static bool
lower_frag_coord_zw(nir_builder *b, nir_intrinsic_instr *intrin, void *data)
{
if (intrin->intrinsic != nir_intrinsic_load_frag_coord_z && intrin->intrinsic != nir_intrinsic_load_frag_coord_w)
return false;
b->cursor = nir_before_instr(&intrin->instr);
nir_def *bary = nir_load_barycentric_pixel(b, 32,
.interp_mode = INTERP_MODE_NOPERSPECTIVE
);
unsigned component = intrin->intrinsic == nir_intrinsic_load_frag_coord_z ? 2 : 3;
nir_def *new = nir_load_frag_coord_zw_pan(b, bary, .component = component);
nir_def_replace(&intrin->def, new);
return true;
}
bool
pan_nir_lower_frag_coord_zw(nir_shader *shader)
{
return nir_shader_intrinsics_pass(shader, lower_frag_coord_zw,
nir_metadata_control_flow, NULL);
}

View file

@ -4,6 +4,7 @@
*/
#include "compiler/nir/nir_builder.h"
#include "bi_opcodes.h"
#include "pan_nir.h"
/* Mali only provides instructions to fetch varyings with either flat or
@ -207,7 +208,8 @@ lower_noperspective_fs(nir_builder *b, nir_intrinsic_instr *intrin,
b->cursor = nir_after_instr(&intrin->instr);
nir_def *bary = intrin->src[0].ssa;
nir_def *fragcoord_w = nir_load_frag_coord_zw_pan(b, bary, .component = 3);
nir_def *fragcoord_w =
nir_load_var_special_pan(b, 1, bary, .flags = BI_VARYING_NAME_FRAG_W);
if (intrin->def.bit_size == 16)
fragcoord_w = nir_f2f16(b, fragcoord_w);

View file

@ -0,0 +1,48 @@
/*
* Copyright © 2024,2026 Collabora Ltd.
* SPDX-License-Identifier: MIT
*/
#include "compiler/nir/nir_builder.h"
#include "bi_opcodes.h"
#include "pan_nir.h"
/* Lowers nir_load_frag_coord_zw and point_coord to nir_load_var_special_pan */
static bool
lower_var_special_pan(nir_builder *b, nir_intrinsic_instr *intrin, void *data)
{
enum bi_varying_name var_name;
switch (intrin->intrinsic) {
case nir_intrinsic_load_frag_coord_z:
var_name = BI_VARYING_NAME_FRAG_Z;
break;
case nir_intrinsic_load_frag_coord_w:
var_name = BI_VARYING_NAME_FRAG_W;
break;
case nir_intrinsic_load_point_coord:
var_name = BI_VARYING_NAME_POINT;
break;
default:
return false;
}
b->cursor = nir_before_instr(&intrin->instr);
nir_def *bary = nir_load_barycentric_pixel(b, 32,
.interp_mode = INTERP_MODE_NOPERSPECTIVE
);
nir_def *new = nir_load_var_special_pan(b, intrin->def.num_components, bary,
.flags = var_name);
nir_def_replace(&intrin->def, new);
return true;
}
bool
pan_nir_lower_var_special_pan(nir_shader *shader)
{
return nir_shader_intrinsics_pass(shader, lower_var_special_pan,
nir_metadata_control_flow, NULL);
}