Skip to content

Upstream sync 10D: shader recompiler slice (7 commits) - #492

Merged
RINNECODER merged 7 commits into
mainfrom
sync10/shader
Oct 14, 2026
Merged

RINNECODER merged 7 commits into
mainfrom
sync10/shader

Conversation

@RINNECODER

Copy link
Copy Markdown
Owner

Sync 10 slice D: shader recompiler

Cherry-picks (-x) from d8888df9b..upstream/main, scopes shader, recompiler and structurizer. ShaderDiskCache payload layout is unchanged, so FormatVersion is not bumped.

Ported (7)

  • fix(shader): plan a table T# that several image operations share
  • test(shader): check that a queried and sampled table T# is one image
  • test(shader): check uniform table images after the descriptor phis (moves the existing test function; no behaviour change)
  • feat(recompiler): reuse pure IR values recomputed in dominated blocks (new RedundantValueEliminator pass, run after interface preparation; adds agc_redundant_value_elimination_tests)
  • fix(shader): size per-invocation LDS by the append counter's offset
  • fix(shader): record BDA faults in hull programs instead of refusing them (only the refusal removal and the contract test; the Vulkan Tessellation.cpp execution-test hunks conflict with main's version and were not taken)
  • fix(shader): normalize reserved buffer bits before scalar binding (the Vulkan BufferDescriptorRuntime.cpp test does not exist on main and was not taken). The "Scalar buffer descriptors" entry from the earlier scalar-load commit was added to docs/dev/TechnicalDebt.md here, because that entry was missing from main.

Skipped

  • Already on main (code present, equivalent or identical): load the PERSP_SAMPLE and LINEAR_SAMPLE I/J pairs, update per-invocation LDS without atomics, capture image descriptors read from constant buffers at uniform offsets (only an already-present test duplicate remained), read lane 63 of half-wave reductions and its search-order test, structurize refused control flow with reach flags and its test, post-order structurizer fixpoints with the growth budget and its test, take a hull's input stride from its patch term, adjacent BDA dword loads through one span read, 32_AR export alpha from channel 1, split variant compilation into interface and emission steps, emit both registration layouts of a pixel shader, the TStep style rename, ignore unused descriptor fields for scalar buffer loads.
  • User-data tail linking (raw vertex prologs and fragment tails, plus the vertex tail state test): the feature does not exist on main. The driver glue conflicts with the backend-neutral DecodeDrawPrograms in DrawDispatch.cpp and the Metal draw path, so it needs its own port.
  • fix(shader): lower hulls that write one output control point per patch: TessellationLowering.cpp on main lacks the evaluator and record helpers it builds on (they come with agc-scope hull work); two conflicting hunks.
  • perf(shader): map cached SPIR-V from the shader cache files, and fix(shader): map shader cache files on Windows: conflicts in nine files (ShaderDiskCache, VulkanDevice.cpp, tests deleted on main); performance only, Windows part not applicable.
  • fix(shader): share delete access when reading cache entries on Windows: Windows only.
  • Waterfall descriptors (feat(recompiler): plan waterfall loops over per-lane T#s as non-uniform tables boykopovar/AnyPS5#5089) and its follow-ups (plan waterfall loops over per-lane T#s, refuse per-lane tables over masked T#s, no record of empty per-lane tables, preserve per-lane table modes in disk plans, disk format 32), together with its revert (Revert #5089: agc_driver_waterfall_images fails SPIR-V validation on main boykopovar/AnyPS5#5824): upstream reverted it, so both sides are skipped.
  • feat(tools): compile the changed translation units only: tooling, not a recompiler change.
  • agc-scope commits touching core/shader (hull patch index, 2D-array image access on 3D T#, dithered alpha coverage, mesh clip/cull distances): belong to the AGC driver slice.

Evidence

  • x86_64 ANYPS5_ROSETTA_LIBS=ON build (nice -n 10, 4 jobs) of rosetta_libs rosetta_engine succeeded.
  • core/libs/prx/libSceAgcDriver/tests/RedundantValueElimination.cpp built standalone against the recompiler sources (clang++ -O0, the disk cache and SPIR-V optimizer pieces stubbed or left out) and exits 0.
  • ResourceTracker.cpp, ResourceMaterializer.cpp, Recompiler.cpp, SpirvAnalysis.cpp, SpirvBdaRead.cpp, ShaderMemory.cpp and BdaContracts.cpp pass clang++ -std=c++20 -fsyntax-only.
  • Game smoke (tools/smoke.sh <build> 300 --map): main menu <= 65 s, leader select <= 77 s, map generation start <= 98 s, 2069 frames presented, no fault or uncaught exception, shader disk cache 0 load failures and 0 write failures.
  • Not run: the agc_driver_* execution tests (they need a Vulkan test device), the metal shader bridge ctest (that configuration does not compile the recompiler), the Metal shader converter on output of the new value-elimination pass beyond what the smoke exercised.
  • No performance claims.

🤖 Generated with Claude Code

milescoviello and others added 7 commits October 14, 2026 08:34
TryMakeTableImage planned a T# read from a bindless image table only when
its eight scalar reads had no user other than that one GetImageResource.
Descriptor-phi splitting gives each image operation its own copy of the
T# over the same reads, so a table entry that is both queried and sampled
was refused, and GetHandle then rejected the scalar reads.

Accept reads whose every user is a GetImageResource built from exactly
those eight reads; each copy is planned as the same table.

A shipped title stops on such a shader at start-up:
image_get_resinfo and image_sample_lz on one s_buffer_load_dwordx8 T#.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit e015772)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit cd1757e)
boykopovar#757 and boykopovar#758 add their image table checks where this check was, after
verifyBindlessTable, so the pull requests conflicted.

(cherry picked from commit e092d2a)
The front end rebuilds operand flushes, NaN checks and bitcasts for every
use of a register, and nothing merged them when SPIRV-Tools is off. A
dominator-scoped value numbering pass before SPIR-V emission replaces a
pure value with an earlier identical one in the same or a dominating
block. Only operations that are functions of their operands are merged;
loads, stores, atomics, barriers, phis and cross-lane reads are left
alone. A block the entry does not reach throws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit f0f920a)
FunctionLdsDwords bounds every LDS access by its address argument and
gives up on opcodes without a dword count. DataAppend and DataConsume
have neither: their first argument is M0, which only places GDS
counters, and the emitter addresses the LDS counter by the instruction
offset alone. Any pixel or vertex-path program with ds_append or
ds_consume therefore declared the full 8192-dword Function array per
invocation. LLVM 20 llvmpipe needs about 6 s to compile that array in
the new pixel LDS read-modify-write test, which ran past the 5 s
graphics fence on CI. The counter now takes the dword at its offset.

(cherry picked from commit 13cc3a9)
Every hull program with a BDA access was refused with "BDA fault
termination requires a barrier-safe tessellation-control execution
protocol". The refusal predates BdaInvocationsMayStop: a program with
s_barrier no longer stops a faulting invocation; the fault is recorded,
the read returns zero and every invocation reaches the barrier. In a
hull, s_barrier is the only control barrier the backend emits after the
guest code starts, so that rule already covers it, and a hull without
one can stop an invocation without stranding a barrier.

The tessellation test draws hulls that scale their levels by a BDA read,
with and without s_barrier, and requires an unmapped read to report a
tessellation-control fault (not on llvmpipe, which runs hull loads that
the unmapped-address check skips). The contract test now accepts a hull
with s_barrier.

(cherry picked from commit c1e4a0b)
@RINNECODER RINNECODER added the upstream-sync Upstream boykopovar/AnyPS5 intake label Oct 14, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T14:01:40.222629Z c5683a9 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 14, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c8f3541b-b142-4e61-95e9-7a01a3ee6e29
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@RINNECODER
RINNECODER merged commit f5b3863 into main Oct 14, 2026
6 checks passed
@RINNECODER
RINNECODER deleted the sync10/shader branch October 14, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

upstream-sync Upstream boykopovar/AnyPS5 intake

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants