diff --git a/src/panfrost/lib/pan_earlyzs.c b/src/panfrost/lib/pan_earlyzs.c index d00c9100e69..6647409c2c3 100644 --- a/src/panfrost/lib/pan_earlyzs.c +++ b/src/panfrost/lib/pan_earlyzs.c @@ -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); } } } diff --git a/src/panfrost/lib/tests/test-earlyzs.cpp b/src/panfrost/lib/tests/test-earlyzs.cpp index 81c01381439..703dbc8ae8b 100644 --- a/src/panfrost/lib/tests/test-earlyzs.cpp +++ b/src/panfrost/lib/tests/test-earlyzs.cpp @@ -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);