intel/brw: fixup wm_prog_data_barycentric_modes()

Always select sample barycentric when persample dispatch is unknown at
compile time and let the payload adjustments feed the expected value
based on dispatch.

Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Cc: mesa-stable
Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27803>
(cherry picked from commit 1bbe2d9833)
This commit is contained in:
Lionel Landwerlin 2024-04-18 09:54:11 +03:00 committed by Eric Engestrom
parent 0a174bb629
commit 7ed240c627
5 changed files with 47 additions and 10 deletions

View file

@ -1704,7 +1704,7 @@
"description": "intel/brw: fixup wm_prog_data_barycentric_modes()",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -1290,8 +1290,34 @@ wm_prog_data_barycentric_modes(const struct brw_wm_prog_data *prog_data,
* "MSDISPMODE_PERSAMPLE is required in order to select Perspective
* Sample or Non-perspective Sample barycentric coordinates."
*/
modes &= ~(BITFIELD_BIT(BRW_BARYCENTRIC_PERSPECTIVE_SAMPLE) |
BITFIELD_BIT(BRW_BARYCENTRIC_NONPERSPECTIVE_SAMPLE));
uint32_t sample_bits = (BITFIELD_BIT(BRW_BARYCENTRIC_PERSPECTIVE_SAMPLE) |
BITFIELD_BIT(BRW_BARYCENTRIC_NONPERSPECTIVE_SAMPLE));
uint32_t requested_sample = modes & sample_bits;
modes &= ~sample_bits;
/*
* If the shader requested some sample modes and we have to disable
* them, make sure we add back the pixel variant back to not mess up the
* thread payload.
*
* Why does this works out? Because of the ordering in the thread payload :
*
* R7:10 Perspective Centroid Barycentric
* R11:14 Perspective Sample Barycentric
* R15:18 Linear Pixel Location Barycentric
*
* In the backend when persample dispatch is dynamic, we always select
* the sample barycentric and turn off the pixel location (even if
* requested through intrinsics). That way when we dynamically select
* pixel or sample dispatch, the barycentric always match, since the
* pixel location barycentric register offset will align with the sample
* barycentric.
*/
if (requested_sample) {
if (requested_sample & BITFIELD_BIT(BRW_BARYCENTRIC_PERSPECTIVE_SAMPLE))
modes |= BITFIELD_BIT(BRW_BARYCENTRIC_PERSPECTIVE_PIXEL);
if (requested_sample & BITFIELD_BIT(BRW_BARYCENTRIC_NONPERSPECTIVE_SAMPLE))
modes |= BITFIELD_BIT(BRW_BARYCENTRIC_NONPERSPECTIVE_PIXEL);
}
}
return modes;

View file

@ -1195,7 +1195,8 @@ fs_visitor::import_uniforms(fs_visitor *v)
}
enum brw_barycentric_mode
brw_barycentric_mode(nir_intrinsic_instr *intr)
brw_barycentric_mode(const struct brw_wm_prog_key *key,
nir_intrinsic_instr *intr)
{
const glsl_interp_mode mode =
(enum glsl_interp_mode) nir_intrinsic_interp_mode(intr);
@ -1207,7 +1208,13 @@ brw_barycentric_mode(nir_intrinsic_instr *intr)
switch (intr->intrinsic) {
case nir_intrinsic_load_barycentric_pixel:
case nir_intrinsic_load_barycentric_at_offset:
bary = BRW_BARYCENTRIC_PERSPECTIVE_PIXEL;
/* When per sample interpolation is dynamic, assume sample
* interpolation. We'll dynamically remap things so that the FS thread
* payload is not affected.
*/
bary = key->persample_interp == BRW_SOMETIMES ?
BRW_BARYCENTRIC_PERSPECTIVE_SAMPLE :
BRW_BARYCENTRIC_PERSPECTIVE_PIXEL;
break;
case nir_intrinsic_load_barycentric_centroid:
bary = BRW_BARYCENTRIC_PERSPECTIVE_CENTROID;
@ -7340,6 +7347,7 @@ is_used_in_not_interp_frag_coord(nir_def *def)
*/
static unsigned
brw_compute_barycentric_interp_modes(const struct intel_device_info *devinfo,
const struct brw_wm_prog_key *key,
const nir_shader *shader)
{
unsigned barycentric_interp_modes = 0;
@ -7368,7 +7376,7 @@ brw_compute_barycentric_interp_modes(const struct intel_device_info *devinfo,
nir_intrinsic_op bary_op = intrin->intrinsic;
enum brw_barycentric_mode bary =
brw_barycentric_mode(intrin);
brw_barycentric_mode(key, intrin);
barycentric_interp_modes |= 1 << bary;
@ -7577,7 +7585,7 @@ brw_nir_populate_wm_prog_data(nir_shader *shader,
prog_data->inner_coverage = shader->info.fs.inner_coverage;
prog_data->barycentric_interp_modes =
brw_compute_barycentric_interp_modes(devinfo, shader);
brw_compute_barycentric_interp_modes(devinfo, key, shader);
/* From the BDW PRM documentation for 3DSTATE_WM:
*

View file

@ -611,7 +611,8 @@ fs_reg setup_imm_b(const brw::fs_builder &bld,
fs_reg setup_imm_ub(const brw::fs_builder &bld,
uint8_t v);
enum brw_barycentric_mode brw_barycentric_mode(nir_intrinsic_instr *intr);
enum brw_barycentric_mode brw_barycentric_mode(const struct brw_wm_prog_key *key,
nir_intrinsic_instr *intr);
uint32_t brw_fb_write_msg_control(const fs_inst *inst,
const struct brw_wm_prog_data *prog_data);

View file

@ -4289,7 +4289,8 @@ fs_nir_emit_fs_intrinsic(nir_to_brw_state &ntb,
case nir_intrinsic_load_barycentric_centroid:
case nir_intrinsic_load_barycentric_sample: {
/* Use the delta_xy values computed from the payload */
enum brw_barycentric_mode bary = brw_barycentric_mode(instr);
enum brw_barycentric_mode bary = brw_barycentric_mode(
reinterpret_cast<const brw_wm_prog_key *>(s.key), instr);
const fs_reg srcs[] = { offset(s.delta_xy[bary], bld, 0),
offset(s.delta_xy[bary], bld, 1) };
bld.LOAD_PAYLOAD(dest, srcs, ARRAY_SIZE(srcs), 0);
@ -4384,7 +4385,8 @@ fs_nir_emit_fs_intrinsic(nir_to_brw_state &ntb,
dst_xy = retype(get_nir_src(ntb, instr->src[0]), BRW_REGISTER_TYPE_F);
} else {
/* Use the delta_xy values computed from the payload */
enum brw_barycentric_mode bary = brw_barycentric_mode(bary_intrinsic);
enum brw_barycentric_mode bary = brw_barycentric_mode(
reinterpret_cast<const brw_wm_prog_key *>(s.key), bary_intrinsic);
dst_xy = s.delta_xy[bary];
}