Skip to content

fix(shader): preserve pixel helper lanes in EXEC copies - #6291

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
santhoshkumar-dev:codex/fix-pixel-exec-helper-lanes
Oct 18, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
santhoshkumar-dev:codex/fix-pixel-exec-helper-lanes

Conversation

@santhoshkumar-dev

@santhoshkumar-dev santhoshkumar-dev commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What

A pixel shader that enables whole-quad mode, copies EXEC to an SGPR, and restores that copy loses its helper lanes. hostExecWord intersects the saved mask with a Vulkan ballot of active invocations, which excludes those helpers. Subsequent interpolation leaves incorrect coordinates in the helper lanes, so implicit texture sampling selects the wrong mips. OlliOlli World (PPSA02327, #5316) shows maze patterns on characters and terrain, including dashed triangle edges on the Radlandia map.

Pixel-stage EXEC reads now intersect against the whole-quad expansion of the host active-lane mask. This retains the helper bits already present in guest EXEC while still rejecting absent host quads. Other stages retain the existing host-lane mask. There are no title checks, fixed mip levels, sampler overrides, or diagnostic environment switches in this change.

The mask semantics follow the AMD RDNA 2 ISA, section 12.3, S_MOV_B64 and S_WQM_B32/B64, printed page 111. Vulkan permits helper invocations to be inactive for non-quad subgroup operations; see Helper Invocations. Console hardware was not measured.

Tested

Windows 11 Pro build 26200, GCC 15.2 Release, AMD Radeon RX 6700 XT, AMD Vulkan 26.8.1 / Windows display driver 32.0.21045.5002.

  • Windows system-library build passed. Eight focused CTest cases passed with Vulkan required and no skips: shader memory, masked-select optimization, host EXEC lanes, LOD clamps, barycentric emulation, pixel helpers, scalar SOP1, and the new implicit-derivative regression.
  • The regression draws 24 skewed triangles with individually marked mip levels. It saves/restores EXEC after WQM and checks mip selection at every covered pixel for wave32/wave64, native/emulated barycentrics, and expected mip levels 0/1/2. Each of the 12 cases checks 7,817 pixels with zero incorrect selections.
  • Negative control on unmodified main d92a8da: the first case fails with 983 incorrectly sampled pixels. Restoring only this EXEC correction makes all 12 cases pass. The branch was then rebased onto db81992, whose intervening changes add optional draw-program tracing, and the library build and eight tests were rerun.
  • OlliOlli World v01.005.000: the map and tutorial NPCs render cleanly with normal mip selection; the user confirmed both scenes. The game check used d92a8da plus only the EXEC correction, with the shader disk cache disabled and all rendering overrides removed. It ran for 215 seconds and exited normally with code 0. No FPS or audio improvement is claimed.
  • Repository conventions and whitespace checks passed. Linux, other GPU vendors, and a full CTest-suite run were not tested locally.

Before and after screenshots

Original screenshots supplied by the tester. The after images show the EXEC correction with normal automatic mip selection.

Scene Before EXEC correction After EXEC correction
Characters Characters before: texture noise on clothing and boards Characters after: clear clothing and boards
Radlandia map Map before: maze patterns and triangle seams Map after: clean terrain and objects

Original PNGs and screenshot provenance. Camera positions and UI state differ; these images document rendering correctness.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw; no stubs added
  • No notes, investigation files or images added to the repository
  • New third-party code is a submodule built from source: none added
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Unblocks: OlliOlli World PPSA02327 OlliOlli World (PPSA02327) #5316 (texture corruption)
  • GPUs tested: AMD Radeon RX 6700 XT, AMD Vulkan 26.8.1 / display driver 32.0.21045.5002, Windows 11 Pro build 26200
  • AI-assisted: yes (Codex)

Expand the host active-lane mask to whole quads for pixel-stage EXEC value reads so saving and restoring WQM does not drop derivative inputs. Keep the existing host-lane mask in other stages. Add a GPU regression for implicit mip selection after an EXEC save/restore, across wave32/wave64 and native/emulated barycentrics.
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6326 core/libs/prx/libSceAgcDriver/CMakeLists.txt L1860
PR 6341 core/libs/prx/libSceAgcDriver/CMakeLists.txt L1860
PR 6606 core/libs/prx/libSceAgcDriver/CMakeLists.txt L1860
PR 7410 docs/dev/debt/shader.md L80

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.

Pull request Shared files not compared
PR 1341 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 4650 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 4891 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5500 docs/dev/debt/shader.md
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5941 docs/dev/debt/shader.md
PR 6009 docs/dev/debt/shader.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6218 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6234 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6235 docs/dev/debt/shader.md
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6320 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6360 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 6454 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6470 docs/dev/debt/shader.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6486 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6488 docs/dev/debt/shader.md
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6503 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6535 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6613 docs/dev/debt/shader.md
PR 6683 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6701 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6763 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6856 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6937 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6941 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6946 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6947 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6963 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6977 docs/dev/debt/shader.md
PR 6987 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6989 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6995 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7002 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7085 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 7332 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/shader.md
PR 7388 docs/dev/debt/shader.md
PR 7429 docs/dev/debt/shader.md
PR 7615 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7644 core/libs/prx/libSceAgcDriver/CMakeLists.txt

@github-actions github-actions Bot added build shader core/shader docs agc libSceAgc* labels Oct 15, 2026
@zaryabzip

Copy link
Copy Markdown
Contributor

NVIDIA and Intel run, for the "Linux, other GPU vendors, and a full CTest-suite run were not tested locally." line. Windows 11 (26200), RTX 3060 Laptop GPU (NVIDIA 617.42) and Intel UHD Graphics (device 0x9a60), WinLibs GCC 15.2.0 r7 (UCRT), Release, BUILD_TESTING=ON. Head 27b196bee merged onto main 8856f180c (clean); the GPU was picked with ANYPS5_GPU, and the verbose test logs show the selected device.

  • agc_driver_pixel_implicit_derivatives with the PR: passes on both GPUs, incorrect=0 in all 12 cases.
  • With ExecMask.cpp from main and the PR's test:
    • Intel UHD: fails at the first case, emulate0 wave64 mip0 covered=7817 incorrect=983, then AGC graphics: implicit derivatives selected the wrong mip at 983 pixels.
    • RTX 3060: passes, 3 of 3 runs, incorrect=0 in all 12 cases. The test does not detect the old behaviour on this NVIDIA GPU.
  • ctest -R "agc|shader|guest_memory|write_watch" -j4 on the RTX 3060: 592/592 pass with the PR, and 591/591 on main (the new test is the difference). Both skip the same 3 tests (agc_host_import_sparse, agc_driver_sparse_dma_buf_import, agc_driver_stencil_ref_export).

Not run: OlliOlli World, Linux, the suite on the Intel GPU.

AI-assisted: yes (Claude Code)

This was referenced Oct 15, 2026
This was referenced Oct 15, 2026
@adriadam10 adriadam10 self-assigned this Oct 18, 2026
@github-actions github-actions Bot added the unblocks title Names a title ID on the Unblocks line label Oct 18, 2026
@adriadam10
adriadam10 merged commit 18bd700 into boykopovar:main Oct 18, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build docs shader core/shader unblocks title Names a title ID on the Unblocks line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants