Repository navigation
fix(shader): kill demoted quad-mask pixels when the pixel program returns - #6255
Conversation
…urns A pixel that PA_SC_AA_MASK leaves uncovered is demoted to a helper invocation so the covered pixels keep their derivatives. When the guest exports under an EXEC mask that clears that lane, the colour output is never written. On the Radeon 860M (Windows driver 32.0.13058.8001) such a demoted invocation still writes undefined colour to the target, so agc_driver_quad_pixel_mask fails at its first implicit-LOD sample under a partial mask (2). Killing the uncovered invocations at the return, after every derivative is taken, discards them on every driver. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
jotitadev
left a comment
There was a problem hiding this comment.
NVIDIA run, for the "Not tested: NVIDIA" line.
Ubuntu 26.04 (kernel 7.0.0-38), NVIDIA GeForce RTX 3070, driver 595.99.02, GCC 15.2, Release, BUILD_TESTING=ON, ANYPS5_GPU set to the 3070 (the log shows Selected GPU name=NVIDIA GeForce RTX 3070 vendor=0x10de). Head 79d72b683 merged onto main 44df21632, no conflicts.
agc_driver_quad_pixel_maskpasses on unmodifiedmainand with this PR, 3 of 3 runs with the PR. Both reportquad pixel mask tests passed (demote to helper invocation), so the demote path runs. This driver does not show the Radeon 860M behaviour: the demoted pixels already come out right without the kill. The test cannot act as a negative control on this GPU.- With the PR, the new
OpKillcauses no regression here.agc_driver_sample_mask_draw,agc_driver_sample_mask_depth_stencil,agc_driver_sample_mask_multisampleandagc_shader_quad_mask_no_demotepass in the full run. ctest -R "^agc" -E "agc_display_buffer_dcc|agc_driver_flip|agc_driver_lds_atomics64|display" -j1: 592 of 593 pass, with the same 3 skips asmain. The failure isagc_driver_store_over_untracked, which also fails on unmodifiedmainon this machine: 9 of 10 runs with other builds running, all withthe result did not reach a block the CPU left alone. It is the same test as #6347 and #6383, which report it on Windows. On an idle machine,mainpasses 593 of 593.
Not run: Intel, any title.
GPUs tested: NVIDIA GeForce RTX 3070, driver 595.99.02, Vulkan 1.4.329, Ubuntu 26.04 (kernel 7.0.0-38)
Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.
|
RDNA 3 data point: this fixes RX 7800 XT (
Full CTest with the PR: 1294 of 1298 pass. None of the four failures involve quad masks: AI-assisted: yes (Claude Code). |
|
RDNA 4 and Intel data points: this fixes Windows 11 Pro 26300, WinLibs GCC 15.2.0 r7, Release, every execution test built. Base: Tests:
Unlike the 860M, this driver writes the demoted pixels only with GPL on. The values match the description: every uncovered pixel gets Full CTest on the RX 9070 XT with this PR, #6436 and #6647 together, from an empty AI-assisted: yes (Claude Code) |
What
agc_driver_quad_pixel_mask, added with #6015, fails on AMD Windows:implicit-LOD sample with quad pixel mask 2: pixel (0, 0) channel 2 is 2, expected 0.A pixel that
PA_SC_AA_MASKleaves uncovered is demoted to a helper invocation, so the covered pixels keep their derivatives. The test's sampled program exports under the restored EXEC mask, which clears the uncovered lane, so the recompiled shader never writes that invocation's colour output. On the Radeon 860M the driver still writes something for those demoted invocations. Every uncovered pixel gets undefined colour, not the sampled texel (60df42ff). The value depends only on x, the same in every run:The Vulkan spec says a helper invocation's outputs are discarded, so this looks like driver behaviour. This PR emits one
OpKillfor the uncovered invocations at the program's return. By then every derivative has been taken, so the covered pixels keep their LOD, and the demoted pixels are discarded on every driver. Without demote, the uncovered invocations are already killed at entry and the new branch is never taken.The sample masks entry in
docs/dev/debt/libSceAgcDriver.mdnow mentions the kill and the driver behaviour.Tested
Windows 11 (26300), Radeon 860M (RDNA 3.5,
1002:1114), driver 32.0.13058.8001, WinLibs GCC 15.2.0, Release, onmaind92a8dad3.agc_driver_quad_pixel_mask,agc_driver_sample_mask_draw,agc_driver_sample_mask_depth_stencil,agc_driver_sample_mask_multisample,agc_shader_quad_mask_no_demoteandrequest_serializerpass,--repeat until-fail:3. The quad pixel mask test reportsquad pixel mask tests passed (demote to helper invocation).agc_driver_quad_pixel_maskonmaind92a8dad3fails 3 of 3, with GPL on and off.ctest -R '^agc_' -j 1from an emptytests/shader_cache: one failure,agc_driver_layered_volume_vertex_no_gpl. That's the AMD driver cache inversion of AMD Windows: identical AGC executables invert GPL pass/fail results after relocation #4768, which fails in every full run onmainon this machine.tools/check_conventions.py --base origin/mainpasses;git diff --checkis clean.Fork CI (run): Linux 1229 of 1230 and Windows 1252 of 1253, the one failure in each being the fork-only
conventions_ci_gate. The first Windows attempt also timed out inagc_driver_readonly_resummarize, a write-tracking test with no quad mask that passes in 0.02 s on Linux and locally; it passed on the job rerun.Not tested: any title. @savvaniss ran the quad-mask and sample-mask tests on an RX 9070 XT (RDNA 4), where this fixes
agc_driver_quad_pixel_mask, and on an Intel UHD 770, where the base already passes and nothing changes. @jotitadev ran it on NVIDIA (RTX 3070, Linux).Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)