pan/earlyzs: Default to FORCE_EARLY for ZS update on v11+

This rule changed with v11 and is needed for
"dEQP-VK.fragment_operations.early_fragment.discard_early_fragment_tests_stencil"
to pass.

Signed-off-by: Mary Guillemard <mary.guillemard@collabora.com>
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34032>
This commit is contained in:
Mary Guillemard 2025-04-14 12:42:00 +02:00
parent 168cf64d70
commit 0bcd8f08a9
2 changed files with 19 additions and 6 deletions

View file

@ -46,7 +46,8 @@ best_early_mode(bool zs_always_passes, bool force_early)
static struct pan_earlyzs_state
analyze(const struct pan_shader_info *s, bool writes_zs_or_oq,
bool alpha_to_coverage, bool zs_always_passes,
enum pan_earlyzs_zs_tilebuf_read zs_read)
enum pan_earlyzs_zs_tilebuf_read zs_read,
bool should_force_early_update)
{
/* If the shader writes depth or stencil, all depth/stencil tests must
* be deferred until the value is known after the ZS_EMIT instruction,
@ -63,7 +64,8 @@ analyze(const struct pan_shader_info *s, bool writes_zs_or_oq,
bool shader_writes_zs = (s->fs.writes_depth || s->fs.writes_stencil);
bool late_update = shader_writes_zs || alpha_to_coverage;
bool late_kill = shader_writes_zs;
bool force_early_update = s->fs.early_fragment_tests;
bool force_early_update =
s->fs.early_fragment_tests || should_force_early_update;
bool force_early_kill = s->fs.early_fragment_tests;
/* Late coverage updates are required if the coverage mask depends on
@ -134,6 +136,9 @@ analyze(const struct pan_shader_info *s, bool writes_zs_or_oq,
struct pan_earlyzs_lut
pan_earlyzs_analyze(const struct pan_shader_info *s, unsigned arch)
{
/* On v11+, update operation cannot be weak early */
bool should_force_early_update = arch >= 11;
struct pan_earlyzs_lut lut;
for (unsigned v0 = 0; v0 < 2; ++v0) {
@ -148,7 +153,7 @@ pan_earlyzs_analyze(const struct pan_shader_info *s, unsigned arch)
zs_read = PAN_EARLYZS_ZS_TILEBUF_READ_NO_OPT;
lut.states[v0][v1][v2][v3] =
analyze(s, v0, v1, v2, zs_read);
analyze(s, v0, v1, v2, zs_read, should_force_early_update);
}
}
}

View file

@ -45,6 +45,7 @@
#define API_EARLY BITFIELD_BIT(8)
#define SHADER_READS_ZS BITFIELD_BIT(9)
#define ARCH_HAS_READONLY_ZS_OPT BITFIELD_BIT(10)
#define ARCH_HAS_STATE_TRACK_OPT BITFIELD_BIT(11)
static void
test(enum pan_earlyzs expected_update, enum pan_earlyzs expected_kill,
@ -59,6 +60,13 @@ test(enum pan_earlyzs expected_update, enum pan_earlyzs expected_kill,
info.fs.early_fragment_tests = !!(flags & API_EARLY);
info.writes_global = !!(flags & SIDEFX);
unsigned arch = 9;
if (flags & ARCH_HAS_STATE_TRACK_OPT)
arch = 11;
else if (flags & ARCH_HAS_READONLY_ZS_OPT)
arch = 10;
if (flags & SHADER_READS_ZS) {
if (flags & (WRITES_Z | WRITES_S))
zs_read = PAN_EARLYZS_ZS_TILEBUF_READ_NO_OPT;
@ -67,9 +75,8 @@ test(enum pan_earlyzs expected_update, enum pan_earlyzs expected_kill,
}
struct pan_earlyzs_state result = pan_earlyzs_get(
pan_earlyzs_analyze(&info, flags & ARCH_HAS_READONLY_ZS_OPT ? 10 : 9),
!!(flags & ZS_WRITEMASK), !!(flags & ALPHA2COV),
!!(flags & ZS_ALWAYS_PASSES), zs_read);
pan_earlyzs_analyze(&info, arch), !!(flags & ZS_WRITEMASK),
!!(flags & ALPHA2COV), !!(flags & ZS_ALWAYS_PASSES), zs_read);
ASSERT_EQ(result.update, expected_update);
ASSERT_EQ(result.kill, expected_kill);
@ -170,6 +177,7 @@ TEST(EarlyZS, ShaderReadZS)
TEST(EarlyZS, NoSideFXNoShaderZSAlt)
{
CASE(WEAK_EARLY, WEAK_EARLY, ZS_ALWAYS_PASSES);
CASE(FORCE_EARLY, WEAK_EARLY, ZS_ALWAYS_PASSES | ARCH_HAS_STATE_TRACK_OPT);
CASE(FORCE_LATE, WEAK_EARLY,
ZS_ALWAYS_PASSES | ALPHA2COV | DISCARD | WRITES_COV);
CASE(WEAK_EARLY, WEAK_EARLY, ZS_ALWAYS_PASSES | ZS_WRITEMASK);