intel: Move unlit centroid workaround into the elk compiler
Some checks are pending
macOS-CI / macOS-CI (dri) (push) Waiting to run
macOS-CI / macOS-CI (xlib) (push) Waiting to run

This was only needed on Sandybridge.  We can delete the brw code,
and replace the generic devinfo bit with a helper inside the elk
compiler itself.

Thanks to Iván Briano for noticing we still had dead brw code for this.

Reviewed-by: Ivan Briano <ivan.briano@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33764>
This commit is contained in:
Kenneth Graunke 2025-03-06 13:32:22 -08:00
parent 1dfed59c49
commit cdbedc9eff
6 changed files with 16 additions and 67 deletions

View file

@ -504,8 +504,6 @@ brw_emit_interpolation_setup(brw_shader &s)
}
if (wm_key->persample_interp == INTEL_SOMETIMES) {
assert(!devinfo->needs_unlit_centroid_workaround);
const brw_builder ubld = bld.exec_all().group(16, 0);
bool loaded_flag = false;
@ -556,42 +554,6 @@ brw_emit_interpolation_setup(brw_shader &s)
s.delta_xy[i] = brw_fetch_barycentric_reg(
bld, payload.barycentric_coord_reg[i]);
}
uint32_t centroid_modes = wm_prog_data->barycentric_interp_modes &
(1 << INTEL_BARYCENTRIC_PERSPECTIVE_CENTROID |
1 << INTEL_BARYCENTRIC_NONPERSPECTIVE_CENTROID);
if (devinfo->needs_unlit_centroid_workaround && centroid_modes) {
/* Get the pixel/sample mask into f0 so that we know which
* pixels are lit. Then, for each channel that is unlit,
* replace the centroid data with non-centroid data.
*/
for (unsigned i = 0; i < DIV_ROUND_UP(s.dispatch_width, 16); i++) {
bld.exec_all().group(1, 0)
.MOV(retype(brw_flag_reg(0, i), BRW_TYPE_UW),
retype(brw_vec1_grf(1 + i, 7), BRW_TYPE_UW));
}
for (int i = 0; i < INTEL_BARYCENTRIC_MODE_COUNT; ++i) {
if (!(centroid_modes & (1 << i)))
continue;
const brw_reg centroid_delta_xy = s.delta_xy[i];
const brw_reg &pixel_delta_xy = s.delta_xy[i - 1];
s.delta_xy[i] = bld.vgrf(BRW_TYPE_F, 2);
for (unsigned c = 0; c < 2; c++) {
for (unsigned q = 0; q < s.dispatch_width / 8; q++) {
set_predicate(BRW_PREDICATE_NORMAL,
bld.quarter(q).SEL(
quarter(offset(s.delta_xy[i], bld, c), q),
quarter(offset(centroid_delta_xy, bld, c), q),
quarter(offset(pixel_delta_xy, bld, c), q)));
}
}
}
}
}
@ -664,17 +626,6 @@ brw_emit_repclear_shader(brw_shader &s)
brw_lower_scoreboard(s);
}
/**
* Turn one of the two CENTROID barycentric modes into PIXEL mode.
*/
static enum intel_barycentric_mode
centroid_to_pixel(enum intel_barycentric_mode bary)
{
assert(bary == INTEL_BARYCENTRIC_PERSPECTIVE_CENTROID ||
bary == INTEL_BARYCENTRIC_NONPERSPECTIVE_CENTROID);
return (enum intel_barycentric_mode) ((unsigned) bary - 1);
}
static void
calculate_urb_setup(const struct intel_device_info *devinfo,
const struct brw_wm_prog_key *key,
@ -976,15 +927,10 @@ brw_compute_barycentric_interp_modes(const struct intel_device_info *devinfo,
if (!is_used_in_not_interp_frag_coord(&intrin->def))
continue;
nir_intrinsic_op bary_op = intrin->intrinsic;
enum intel_barycentric_mode bary =
brw_barycentric_mode(key, intrin);
barycentric_interp_modes |= 1 << bary;
if (devinfo->needs_unlit_centroid_workaround &&
bary_op == nir_intrinsic_load_barycentric_centroid)
barycentric_interp_modes |= 1 << centroid_to_pixel(bary);
}
}
}

View file

@ -6415,7 +6415,7 @@ elk_compute_barycentric_interp_modes(const struct intel_device_info *devinfo,
barycentric_interp_modes |= 1 << bary;
if (devinfo->needs_unlit_centroid_workaround &&
if (elk_needs_unlit_centroid_workaround(devinfo) &&
bary_op == nir_intrinsic_load_barycentric_centroid)
barycentric_interp_modes |= 1 << centroid_to_pixel(bary);
}

View file

@ -31,6 +31,7 @@
#include "elk_fs.h"
#include "elk_fs_builder.h"
#include "elk_nir.h"
#include "elk_private.h"
#include "compiler/glsl_types.h"
using namespace elk;
@ -289,7 +290,7 @@ elk_fs_visitor::emit_interpolation_setup_gfx6()
}
if (wm_key->persample_interp == ELK_SOMETIMES) {
assert(!devinfo->needs_unlit_centroid_workaround);
assert(!elk_needs_unlit_centroid_workaround(devinfo));
const fs_builder ubld = bld.exec_all().group(16, 0);
bool loaded_flag = false;
@ -346,7 +347,7 @@ elk_fs_visitor::emit_interpolation_setup_gfx6()
(1 << ELK_BARYCENTRIC_PERSPECTIVE_CENTROID |
1 << ELK_BARYCENTRIC_NONPERSPECTIVE_CENTROID);
if (devinfo->needs_unlit_centroid_workaround && centroid_modes) {
if (elk_needs_unlit_centroid_workaround(devinfo) && centroid_modes) {
/* Get the pixel/sample mask into f0 so that we know which
* pixels are lit. Then, for each channel that is unlit,
* replace the centroid data with non-centroid data.

View file

@ -60,6 +60,18 @@ inline bool elk_simd_any_compiled(const elk_simd_selection_state &state)
return elk_simd_first_compiled(state) >= 0;
}
inline bool
elk_needs_unlit_centroid_workaround(const struct intel_device_info *devinfo)
{
/* Sandybridge doesn't do centroid interpolation correctly on unlit pixels,
* causing incorrect values for derivatives near triangle edges. Enabling
* this flag causes the fragment shader to use non-centroid interpolation
* for unlit pixels, at the expense of two extra fragment shader
* instructions."
*/
return devinfo->ver == 6;
}
bool elk_simd_should_compile(elk_simd_selection_state &state, unsigned simd);
void elk_simd_mark_compiled(elk_simd_selection_state &state, unsigned simd, bool spilled);

View file

@ -172,7 +172,6 @@ static const struct intel_device_info intel_device_info_snb_gt1 = {
.has_hiz_and_separate_stencil = true,
.has_llc = true,
.has_pln = true,
.needs_unlit_centroid_workaround = true,
.num_slices = 1,
.num_subslices = { 1, },
.max_eus_per_subslice = 6,
@ -202,7 +201,6 @@ static const struct intel_device_info intel_device_info_snb_gt2 = {
.has_hiz_and_separate_stencil = true,
.has_llc = true,
.has_pln = true,
.needs_unlit_centroid_workaround = true,
.num_slices = 1,
.num_subslices = { 1, },
.max_eus_per_subslice = 12,

View file

@ -310,14 +310,6 @@ Struct("intel_device_info",
Member("bool", "has_compute_engine", comment="Whether this platform has compute engine"),
Member("bool", "needs_unlit_centroid_workaround", compiler_field=True,
comment=dedent("""\
Some versions of Gen hardware don't do centroid interpolation correctly
on unlit pixels, causing incorrect values for derivatives near triangle
edges. Enabling this flag causes the fragment shader to use
non-centroid interpolation for unlit pixels, at the expense of two extra
fragment shader instructions.""")),
Member("bool", "needs_null_push_constant_tbimr_workaround",
comment=dedent("""\
Whether the platform needs an undocumented workaround for a hardware bug