brw: Lower sample_pos for non-per-sample shaders in NIR

We generalize the sample_mask_in lowering to handle this too.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41688>
This commit is contained in:
Kenneth Graunke 2026-05-13 20:27:37 -07:00 committed by Marge Bot
parent 58308b7580
commit cb75c9f962
2 changed files with 34 additions and 33 deletions

View file

@ -3409,22 +3409,11 @@ emit_samplepos_setup(nir_to_brw_state &ntb)
brw_shader &s = ntb.s;
assert(s.stage == MESA_SHADER_FRAGMENT);
struct brw_fs_prog_data *fs_prog_data = brw_fs_prog_data(s.prog_data);
assert(brw_fs_prog_data(s.prog_data)->persample_dispatch != INTEL_NEVER);
const brw_builder abld = bld.annotate("compute sample position");
brw_reg pos = abld.vgrf(BRW_TYPE_F, 2);
if (fs_prog_data->persample_dispatch == INTEL_NEVER) {
/* From ARB_sample_shading specification:
* "When rendering to a non-multisample buffer, or if multisample
* rasterization is disabled, gl_SamplePosition will always be
* (0.5, 0.5).
*/
bld.MOV(offset(pos, bld, 0), brw_imm_f(0.5f));
bld.MOV(offset(pos, bld, 1), brw_imm_f(0.5f));
return pos;
}
/* WM will be run in MSDISPMODE_PERSAMPLE. So, only one of SIMD8 or SIMD16
* mode will be enabled.
*
@ -3449,16 +3438,6 @@ emit_samplepos_setup(nir_to_brw_state &ntb)
abld.MUL(offset(pos, abld, i), tmp_f, brw_imm_f(1 / 16.0f));
}
if (fs_prog_data->persample_dispatch == INTEL_SOMETIMES) {
brw_check_dynamic_fs_config(abld, fs_prog_data,
INTEL_FS_CONFIG_PERSAMPLE_DISPATCH);
for (unsigned i = 0; i < 2; i++) {
set_predicate(BRW_PREDICATE_NORMAL,
bld.SEL(offset(pos, abld, i), offset(pos, abld, i),
brw_imm_f(0.5f)));
}
}
return pos;
}

View file

@ -1573,14 +1573,9 @@ brw_nir_lower_fs_config_intel(nir_shader *nir,
nir_metadata_control_flow, &state);
}
static bool
lower_sample_mask_in_instr(nir_builder *b,
nir_intrinsic_instr *intrin,
void *data)
static void
lower_sample_mask_in(nir_builder *b, nir_intrinsic_instr *intrin)
{
if (intrin->intrinsic != nir_intrinsic_load_sample_mask_in)
return false;
b->cursor = nir_before_instr(&intrin->instr);
nir_def *sample_mask_in_reg = nir_load_coverage_mask_intel(b);
@ -1597,14 +1592,41 @@ lower_sample_mask_in_instr(nir_builder *b,
sample_mask_in_msaa, sample_mask_in_reg);
nir_def_replace(&intrin->def, sample_mask_in);
}
return true;
static void
lower_sample_pos(nir_builder *b, nir_intrinsic_instr *intrin)
{
b->cursor = nir_after_instr(&intrin->instr);
nir_def *pos = nir_bcsel(
b,
nir_test_fs_config_intel(b, 1, INTEL_FS_CONFIG_PERSAMPLE_DISPATCH),
&intrin->def, nir_imm_vec2(b, 0.5, 0.5));
nir_def_rewrite_uses_after(&intrin->def, pos);
}
static bool
brw_nir_lower_sample_mask_in(nir_shader *nir)
lower_msaa_config(nir_builder *b, nir_intrinsic_instr *intrin, void *data)
{
return nir_shader_intrinsics_pass(nir, lower_sample_mask_in_instr,
switch (intrin->intrinsic) {
case nir_intrinsic_load_sample_mask_in:
lower_sample_mask_in(b, intrin);
return true;
case nir_intrinsic_load_sample_pos:
case nir_intrinsic_load_sample_pos_or_center:
lower_sample_pos(b, intrin);
return true;
default:
return false;
}
}
static bool
brw_nir_lower_msaa_config(nir_shader *nir)
{
return nir_shader_intrinsics_pass(nir, lower_msaa_config,
nir_metadata_control_flow, NULL);
}
@ -1693,7 +1715,7 @@ brw_nir_lower_fs_inputs(nir_shader *nir,
}
/* Do this after nir_lower_single_sampled */
NIR_PASS(_, nir, brw_nir_lower_sample_mask_in);
NIR_PASS(_, nir, brw_nir_lower_msaa_config);
if (devinfo->ver < 20) {
NIR_PASS(_, nir, nir_shader_intrinsics_pass,