Repository navigation
Upstream sync 11D: shader recompiler (13 commits) - #511
Merged
Merged
Conversation
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
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. Comment |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
(cherry picked from commit f662afe)
(cherry picked from commit 83d3a71)
ShaderCacheVersion.cmake wrote the source version and the APS5_* switch list into a generated ShaderCacheVersion.hpp that ShaderDiskCache.cpp included. The version hashes every recompiler source, so any content change under core/shader/recompiler rewrote that header and recompiled ShaderDiskCache.cpp next to the file actually edited. The script now writes ShaderCacheVersion.cpp, which defines Generated::SourceVersion and Generated::RecompilerSwitches (a span over the same sorted switch list) with constinit. They are declared in the new ShaderCacheSourceVersion.hpp in the source tree, which ShaderDiskCache.cpp includes; the generated directory is no longer an include directory. The header has a different name from the old generated one so that a build directory that still holds the stale ShaderCacheVersion.hpp next to the generated .cpp cannot pick it up. What is hashed is unchanged: the same manifest (recompiler sources, HostThreadLocal.hpp, submodule commits, compiler, build type, architecture and flags), the same checks and the same rewrite-only- when-different step, so the version still changes exactly when it did. Running the upstream/main script and this one with the same arguments over this tree gives the same version (0x7907101dc4d8c62e) and the same 26 switches, and a second ninja run has no work to do. The value differs from the one main 682ef0c generates (0xdce3a0ce03bf030a) only because this commit edits hashed files, as any recompiler change does. Tested with ninja -d explain -j 4 shader_recompiler_agc_driver, CCACHE_DISABLE=1, after appending a line to IntermediateRepresentation/src/IrType.cpp, three runs on main and then three runs on this commit back to back, with the machine at 100% CPU from other builds. On main ShaderCacheVersion.hpp and ShaderDiskCache.cpp.obj are dirty and the rebuild takes 22.0/23.9/22.2 s. With this change only ShaderCacheVersion.cpp.obj and IrType.cpp.obj are compiled, ShaderDiskCache.cpp is absent from the explain output, and the rebuild takes 12.2/14.7/15.0 s. The shader and recompiler ctest set (26 tests) passes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Co-Authored-By: Codex <noreply@openai.com> (cherry picked from commit 2e461aa)
…ation once per module FPInterpolateF16 and FPInterpolateF32 (v_fma_mixlo_f16, v_fma_mixhi_f16, v_interp_p1ll_f16, v_interp_p1lv_f16, v_interp_p2_f16) were lowered by expanding the f64-based Interpolate emulation inline at every use, about 1200 SPIR-V words each, twice per instruction in wave64 shaders. Interpolate now builds one non-inlined helper function per result width and float mode, created on first use, and each use calls it. The function body is the same instruction sequence the inline expansion produced, so results are unchanged; only the module size changes. agc_fma_mix_once checks that two more uses grow a module by less than the first use with its shared function. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 8847086)
(cherry picked from commit 7b6faf7)
A compute shader with an LOD query was emitted with DerivativeGroupQuadsKHR, which needs both workgroup dimensions even. A guest workgroup of N x 1 lanes failed SPIR-V validation (VUID-StandaloneSpirv-DerivativeGroupQuadsKHR-10151), which agc_driver_waterfall_images hits on every device. GFX10 forms a compute quad from four consecutive lanes, which is DerivativeGroupLinearKHR. The wave64 path no longer reshapes its workgroup to 2 x N, which only made the 2D quads match consecutive lanes. (cherry picked from commit 1ef97e5)
An s_swappc_b64 whose target pair comes from an s_buffer_load of a buffer whose descriptor is loaded from user data now calls the targets that buffer holds: at dispatch the driver reads the buffer, links one copy of each distinct callee after the caller and rewrites the call into a compare chain that s_call_b64s the matching copy. A target that matches no copy, and any other computed call, records an UnlinkedCall fault that the driver reports, instead of failing the shader at compile time. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 9c8fb78)
An s_swappc_b64 whose target is not resolved compiles to a faulting call only at the fallback the table-call linker emits; the linker lists those calls in the request (GuestContext::linkedCallFallbacks), and every other computed call is refused at compile time again, as on main. The new agc_driver_compute_table_calls test runs a linked two-record table on Vulkan in wave32 and wave64, with SCC 0 and 1 reaching the callee, and a record past the table reporting the UnlinkedCall fault. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit 3c1f439)
Read-only packs of encoded cache entries are mapped once at startup from the shader cache prebuilt directory (plus ANYPS5_PREBUILT_SHADER_CACHE, opt out with ANYPS5_NO_PREBUILT_SHADERS). Disk loads try packs and loose prebuilt folders first and fall through to the writable cache and the compiler on a miss. Keys, source version, format and payload checksums are validated exactly as for writable entries, and interval logs report prebuilt hits, misses, rejections and load timings. Depends on the uncached compile entry point only through the offline tool that produces these packs; the loader itself is independent. (cherry picked from commit 24c934a)
ds_ordered_count adds the first active lane's value to a GDS counter and returns the previous value, like ds_append adds the lane count. Waves are not serialized in launch order: each still gets its own range. Ordered swap and multi-dword counts stay refused. DISPATCH_DIRECT and DISPATCH_INDIRECT accept ORDERED_APPEND_ENBL (bit 3) of the initiator. Compute shaders of a shipping title use both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 46a1cc0)
On ds_ordered_count M0 holds the ordered wave ID, not a GDS address as for ds_append: radeonsi and ACO pass the wave ID as the intrinsic's pointer and keep the counter address in offset0. Reading M0 as the base and size skipped the add whenever M0[15:0] was 0, so every wave got the same range. The test now runs the ordered pass with M0 = 0 and M0 = 7. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 3a7e82a)
…upported (cherry picked from commit 84a01a0)
A 2D image_sample_l through a 1D T# now takes the 1D runtime mode, as image_sample_lz already does, instead of failing the runtime image interface. Measured on RDNA2 (gfx1036) with tools/hw-oracle against the same sample with DIM 1D: u inside, on and past the edges, v of 0, 0.5, 1, -0.25 and 3, LOD -1 to 6 on a 5-level R32_FLOAT texture, point, linear and linear-mip filtering, wrap, clamp and border addressing, and HEIGHT or DEPTH 3. All 4725 rows matched: the 1D T# decides the addressing and v is ignored. The execution test samples a 5-level 1D T# with distinct mip contents at LODs -1 to 6, fractional ones included, with u inside, on and past the edges, under point filtering with wrap and clamp and linear filtering with linear mips and wrap, clamp and border addressing. Every result must match the same image_sample_l with DIM 1D bit for bit; point-filtered results must also be the expected texel of the expected level, and linear-mip results the blend of the two levels the LOD selects. (cherry picked from commit e52e140)
RINNECODER
force-pushed
the
sync/upstream-11-shader-recompiler
branch
from
October 15, 2026 07:33
9114ea1 to
a8da517
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cherry-picks (
-x) from63fb0cd92..upstream/main(headd92a8dad3), scope shader recompiler (core/shader, plus the sharedlibSceAgcDriverhunks that drive it). 13 of the 39 listed commits are picked. The other 26 are skipped: 18 are already on main (from the batch-1 U3/U6/U7/U8a ports and #473), 6 depend on series the fork lacks, and 2 only move debt notes. There are no fork-only commits. One commit message was reworded: the GDS ordered-count commit named a title and its ID, and now says "a shipping title".docs/dev/debt/shader.mdhunks were ported intodocs/dev/TechnicalDebt.md. Hunks fordocs/dev/debt/libSceAgcDriver.mdwent into that file, which main has.Cache formats:
ShaderDiskCache::FormatVersionstays at 37 because no picked commit changes the payload layout; the static_asserts are unchanged and the build passes. The source version already changes with every recompiler source. The recompile-request serializer goes from fork version 24 to fork version 25, which addslinkedCallFallbacks. Upstream calls this field version 26, because its own 25 is dithered alpha coverage, which the fork lacks. Fork and upstream request version numbers now differ by one. Any later port of an upstream request field must bump the fork's number and must not reuse upstream's number.Ported
907d1360dfeat(shader): track MODE rounding changes through the control flow graph (newRoundingMode.cpp; debt line ported).99b7c63bbperf(shader): reuse packed f16 operand lanes.09b70d001build(recompiler): generate the shader cache version as a source file (same hash inputs; ShaderDiskCache.cpp no longer rebuilds on every recompiler edit).2bfa0b736refactor(recompiler): emit the v_fma_mixlo/hi and v_interp_*_f16 emulation once per module. Conflicts: the CMake test list keeps main's list and adds onlyagc_fma_mix_once_tests.SpirvEmitterStatekeeps bothbvhIntersectFunctionsand the newinterpolateFunctions.464925a2bfix(build): preserve UTF-8 shader cache source paths.f45630177fix(shader): group compute derivatives by four consecutive lanes.31f1deb65feat(shader): link callees of calls whose target is loaded from a table.FaultReasongainsUnlinkedCallonly, not upstream'sImageTable, which belongs to the image-table series the fork lacks. The<malloc.h>glibc include was not taken.e84e53d10fix(shader): fault only where a table call misses its linked callees. The request serializer change goes in as fork version 25 (see above). TheLinkGraphicsUserDataTailfallback was dropped because main has no user-data tail linking. The serializer tests keep main's fixtures, with the version strings moved to 25 and the fallback round-trip checks added.f31deebcdfeat(recompiler): load prebuilt shader packs before the writable cache. Main'sDecodeEntryhas no mapped-file owner argument, so the pack lookup runs before main's existing loose-file load.b3d676dc1,44b8b7673feat/fix(shader): GDS ordered counts and ordered-append dispatches (sharedPm4.cppdecode included).d46a32c13fix(shader): name the buffer and its V# when a descriptor type is unsupported. The VulkanBufferDescriptorRuntime.cppexecution test does not exist on main and was not taken.9114ea14cfix(shader): read explicit-LOD 2D samples through 1D T#s as measured.Skipped
flatVolumeLineCompatiblein the cache (fix(shader): read 1D T#s through 3D image_sample and image_load accesses boykopovar/AnyPS5#5375, U8a; upstream's format-34 bump is already covered by fork format 36)image_sample_con 1D T#s (fix(shader): compare through 2D image_sample_c on 1D T#s boykopovar/AnyPS5#5456)tablefield and already usesindirectRoot)MayEvaluate, and plans in their arena through the disk cache (perf(shader): keep only evaluable branch conditions in resource plans boykopovar/AnyPS5#5181, U3 with the arena adaptation)docs/dev/debt/libSceAgcDriver.mdbreakAtInstance,patchesPerGroup), which main lacks.CompiledShaderArtifact/RecompileResultsizes differ. For the AGC slice: if stencil artifacts are ported, bump the fork'sFormatVersionpast 37. Do not take upstream's 35.Evidence
agent_build.sh rosetta(x86_64ANYPS5_ROSETTA_LIBS=ON):rosetta_libs rosetta_engine anyps5_agc_replay libSceAgcDriverbuilt.agent_build.sh shader-bridge: built; ctest 4/4 passed.agent_build.sh guest-replay: built; ctest 59/59 passed (excluding the GUIanyps5_metal_presentation_replay).core/shader/recompiler/tests/RequestSerializerTests.cppwas built against the guest-replay recompiler library and exits 0.ShaderMemory.cpp,FmaMixOnce.cpp,ScalarCall.cppandScalarSwappc.cpppass-fsyntax-onlywith the recompiler flags. These tests sit in the Vulkan driver test tree, which the fork's configs do not build.Not run: the
agc_driver_*Vulkan execution tests (they need a Vulkan test device), and game smoke. Rebased onto main after metal: cheap conversion-cache hits and per-draw lookups (-51% worker instructions on the live map) #507 (the rebase was clean). On the rebased branch, guest-replay ctest passed 59/59 (withoutanyps5_metal_presentation_replay), and the rosettaanyps5_agc_replaywas rebuilt.AGC frame replay (x86_64
anyps5_agc_replay), main8f8c56e94vs this branch:--expect-hash 5e5670079f1ae58a(--repeat 4)--expect-png replay-ref.png --max-diff-pixels 8(--repeat 3)The instruction numbers are indicative only. Each comes from a single short run, made without the exclusive replay lock while other replays were running. They are not a performance claim.
No performance claims.
Review findings (chatgpt-codex-connector)
SpirvMemoryInstructions.cpp:1291, where a wave64ds_ordered_countwhose first active lane is in the upper half shuffles from the lower half🤖 Generated with Claude Code
https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj