Skip to content

perf(recompiler): leave the descriptor-range comparison out of direct buffer loads when the device zeroes past the range - #7484

Merged
oneandonlydean merged 7 commits into
boykopovar:mainfrom
AlxcBTW:pr/robust-loads
Oct 27, 2026
Merged

oneandonlydean merged 7 commits into
boykopovar:mainfrom
AlxcBTW:pr/robust-loads

Conversation

@AlxcBTW

@AlxcBTW AlxcBTW commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

What

A direct (non-BDA) buffer load in readBuffer (SpirvRuntimeBuffer.cpp) has two zero conditions: the guest V# bound (byteAddress().inBounds, passed in as enable) and the descriptor range, which the shader compares with the OpArrayLength of the storage-buffer block (EmitMemoryElementInBounds). With robustBufferAccess2 the load is already a select (GuardedElementIndex points a refused load at element 0xfffffffe, where the device returns zero), but the OpArrayLength still reads the descriptor and the compare and the selects cost time on every load.

The recompiler now leaves the descriptor-range comparison out of a direct buffer load when all of this holds:

  • the device has robustBufferAccess2 enabled (State::robustBufferAccess2: the device reports the feature and robustBufferAccess is enabled; since fix(agc): give AMD's proprietary driver robustBufferAccess2 again #8267 main no longer switches it off on AMD's proprietary driver, and this PR no longer refers to that check) and reports robustStorageBufferAccessSizeAlignment == 1 (queried through VkPhysicalDeviceRobustness2PropertiesEXT);
  • APS5_NO_EXACT_ROBUST_LOADS is not set (like the other APS5_NO_* switches: set at all means off);
  • the load is one that can be a select (LoadsSelectable, the same condition the select form has today).

Then the load still selects on the guest V# bound (enable), and the device produces the zero past the descriptor range. For a buffer that can be misaligned the high word keeps its comparison with the length (!unaligned || next < length; unaligned is a specialization constant, so an aligned pipeline folds the term and the OpArrayLength away). Where the device lacks the feature or the alignment is not 1, or the switch is set, the checked form is emitted as before. Stores, atomics, the coherent 64-bit load, GDS, LDS, scratch and BDA loads are not touched.

The flag travels as SpirvTarget::exactRobustLoads into SpirvTargetOptions and the emitter state and is part of the shader cache key (CacheKey.hpp). ShaderResources::wholeDwordRange rounds the descriptor range of a guest buffer and of a draw snapshot down to whole dwords when the flag is on (ranges of 4 bytes or more; Context::exactRobustLoads). The entry "Guest memory load guards" in docs/dev/debt/shader.md says so, and docs/dev/ENVIRONMENT.md has a row for APS5_NO_EXACT_ROBUST_LOADS.

Why the result is the same bytes:

  1. The shader's own range check and the device's check use the same descriptor range, so the equivalence is range for range: the shader zeroed a word past floor(range / 4), and the device returns zero for a 32-bit load that leaves the range. The guest V# bound stays in the shader and selects the same fallback index, so the guest sees the same zero for raw, structured and swizzled loads as before.
  2. Vulkan (robustBufferAccess2, "Shader Out-of-Bounds Memory Access"): a storage-buffer load past the descriptor range rounded up to robustStorageBufferAccessSizeAlignment returns zero, and an access is out of bounds if any part of it is. With an alignment of 1 there is no padding in which the device could return memory contents, which is why the path needs the alignment to be 1. The bound is the descriptor range (VkDescriptorBufferInfo::range), not the size of the VkBuffer.
  3. A partial last word is outside for the shader (floor) and, with alignment 1, outside for the device ("any part"); the host rounding of the range down to a multiple of 4 makes both agree even for an implementation that treats it differently. It removes no word a direct access can reach: every direct access (word load, word store, byte store through the u8 block, 64-bit access through the u64 block) is already gated by floor(range / 4).
  4. A misaligned base reads two words. The shader zeroed the whole value when the second word was past the length, but the device would return the low word; that is why the high word's comparison stays (exact either way).
  5. Residual, not provable from the SPIR-V: the hardware treatment of a 32-bit load that straddles the end of a descriptor range of 1 to 3 bytes. It cannot occur for ranges of 4 bytes or more after the rounding, since all direct accesses are dword aligned relative to the descriptor offset.

Limits: equivalence to console behaviour is not measured on console hardware. The shader-side comparison of both variants on a device ("verify") is not in this PR; the argument above and the interpreter test below are.

Tested

  • Linux (Ubuntu, Mesa lavapipe), fork CI after the merges of main (the last is 16259fa, base 0c6a5bd), at 5095da6 (the PR head 16259fa plus the CI scaffolding commit; run 39678131804, ctest regex guarded_memory_loads|shader_disk_cache|recompiler|spirv): 20 of 20 passed, none skipped, among them agc_guarded_memory_loads (0.05 s), agc_shader_disk_cache (2.05 s) and agc_shader_disk_cache_large_file. This is a narrower set than the 712 tests of the earlier run (the whole agc_* and shader_* set) at the pre-merge head, which are not repeated here. Not run on Windows.
  • agc_guarded_memory_loads has a new case, "exact robust loads read what the checked variant reads": the SPIR-V interpreter of that test runs the checked and the exact module of a raw 32-bit buffer load over 432 combinations (active or not, offsets 0 to 4092, 32 to 128 records, base misalignment 0 to 3, valid and invalid V#) and requires the same effective reads, where an index at or past the 16-word array counts as the device's zero. It also checks that an exact request without robustBufferAccess2 leaves the plain variant unchanged.
  • agc_shader_disk_cache has a new key case, "exact robust loads": the flag changes the cache key.
  • Windows 11, NVIDIA GeForce RTX 5070 Laptop GPU, driver 617.42, Minecraft Dungeons II (PPSA16064). Measured on a lab stack, not on this PR's head against main: both arms ran the same libs (a lab stack of unrelated lab changes plus this change, lab/libs-robust2), arm a without the switch and arm b with it on (the lab switch for this change), so the change is the only difference between the arms. The device reports robustBufferAccess2 true and robustStorageBufferAccessSizeAlignment 1. All rows APS5_TEXTURE_CACHE_MIB=3072, APS5_NO_PAD_INPUT=1, APS5_PROFILE_GPU=1, and the same lab-only settings in both arms (a refresh lever and the depth clear HLE). The counters of the b rows say the change was taken: every direct load was compiled without the descriptor-range check (65536 without, 0 with).
row scene arm FPS frame p50 ms frame p99 ms GPU busy per present ms
r2-t-a-1 title a 9.38 106.1 121.1 67.04
r2-t-a-2 title a 9.17 108.2 128.3 67.19
r2-t-a-3 title a 9.07 109.1 130.5 67.19
r2-t-a-4 title a 8.90 111.6 134.3 67.29
r2-t-b-1 title b 9.18 108.3 124.4 64.86
r2-t-b-2 title b 9.23 107.4 123.7 64.97
r2-t-b-3 title b 9.43 105.4 121.5 64.89
r2-t-b-4 title b 9.02 109.9 133.8 65.13
r2-g-a-1 gameplay a 6.90 142.9 205.1 58.48
r2-g-a-2 gameplay a 8.25 119.3 161.1 56.62
r2-g-b-1 gameplay b 8.55 115.5 141.8 53.37
r2-g-b-2 gameplay b 7.90 127.6 157.4 53.39

At the title the GPU busy time per present is 67.04 to 67.29 ms without the change and 64.86 to 65.13 ms with it in every row, about 2.2 ms less. That is the only figure I claim. Mean FPS at the title is 9.13 without and 9.21 with it, inside the spread of the rows: the title is CPU bound on this machine (frame p50 105 to 112 ms against 65 ms of GPU busy time), so a shorter GPU time barely moves the frame rate. The gameplay rows are memory noisy (31 GiB, two rows per arm): GPU busy 58.5 and 56.6 ms without, 53.4 and 53.4 ms with, which agrees in direction but I claim nothing from it. Pictures were not compared. Traces are on the lab machine and I can attach them on request.

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 (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none (PPSA16064 speed; no Game bring-up discussion yet)
  • GPUs tested: Mesa lavapipe, Ubuntu (all GPU tests); NVIDIA GeForce RTX 5070 Laptop GPU, driver 617.42, Windows 11 26200 (game rows only, GPU tests not run there)
  • AI-assisted: yes

… buffer loads when the device zeroes past the range

With robustBufferAccess2 and a robustStorageBufferAccessSizeAlignment of 1, the device
returns zero for a storage buffer load past the descriptor range, so the shader's own
OpArrayLength comparison against the same range is redundant. The guest V# bound check
stays. A guest buffer's and a draw snapshot's descriptor range of 4 bytes or more is
rounded down to whole dwords so both zeros agree. APS5_NO_EXACT_ROBUST_LOADS keeps the
comparison. The flag is part of the shader cache key.
@github-actions

github-actions Bot commented Oct 18, 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 7922 docs/dev/debt/shader.md L197-198
PR 10846 docs/dev/debt/shader.md L197-198

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 1395 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 1896 docs/dev/ENVIRONMENT.md
PR 2434 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5021 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
docs/dev/debt/shader.md
PR 5371 docs/dev/debt/shader.md
PR 5609 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/Recompiler.hpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/Recompiler.hpp
PR 6192 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6194 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6223 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6235 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/shader.md
PR 6280 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 6412 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderAddressResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvRuntimeBuffer.cpp
docs/dev/debt/shader.md
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6488 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
docs/dev/debt/shader.md
PR 6924 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.cpp
docs/dev/ENVIRONMENT.md
docs/dev/debt/shader.md
PR 6960 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6970 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.hpp
PR 6977 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7201 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
PR 7275 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 7369 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7410 core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/shader.md
PR 7457 docs/dev/ENVIRONMENT.md
PR 7604 docs/dev/ENVIRONMENT.md
PR 7642 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderAddressResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvRuntimeBuffer.cpp
docs/dev/ENVIRONMENT.md
PR 7684 core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
docs/dev/debt/shader.md
PR 8004 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
docs/dev/ENVIRONMENT.md
docs/dev/debt/shader.md
PR 8246 docs/dev/ENVIRONMENT.md
PR 8484 docs/dev/ENVIRONMENT.md
PR 8542 docs/dev/ENVIRONMENT.md
PR 8963 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderAddressResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 9012 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 9129 docs/dev/ENVIRONMENT.md
PR 9176 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 9248 docs/dev/ENVIRONMENT.md
PR 9287 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 9289 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 9345 docs/dev/ENVIRONMENT.md
PR 9356 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
docs/dev/ENVIRONMENT.md
PR 9387 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
docs/dev/ENVIRONMENT.md
docs/dev/debt/shader.md
PR 9431 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9432 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9508 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderAddressResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvRuntimeBuffer.cpp
docs/dev/ENVIRONMENT.md
PR 9592 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9672 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9673 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9674 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9675 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9676 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 9748 core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/debt/shader.md
PR 9842 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9852 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/ENVIRONMENT.md
PR 9891 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9897 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
core/shader/recompiler/Recompiler.hpp
PR 10043 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 10193 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderAddressResources.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvRuntimeBuffer.cpp
docs/dev/ENVIRONMENT.md
PR 10233 docs/dev/debt/shader.md
PR 10435 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10442 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
docs/dev/ENVIRONMENT.md
PR 10757 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/ENVIRONMENT.md
PR 11207 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md

@LeandroLP23

Copy link
Copy Markdown
Contributor

AMD on Windows: the tests this PR names pass on an RDNA 3.5 GPU.

Radeon 860M (RDNA 3.5, driver 32.0.13058.8001), Windows 11 26300, WinLibs GCC 15.2.0 r7, Release. main 6efb7261b with this PR (fd1714a65) merged, together with #7296, #7446, #7377, #7445, #6708, #6748, #6785, #6706, #6613, #7449, #7391, #7489, #7514. They were built once, so the result is for the combination; each merge was clean.

  • agc_guarded_memory_loads, agc_shader_disk_cache: pass, 3 runs of 3.
  • Every agc_* test on the combined build: 713 of 716 pass. The 3 that fail, agc_driver_host_import_lifetime, agc_driver_quad_pixel_mask and agc_driver_layered_volume_vertex_no_gpl, fail the same way on unchanged main here, so none comes from these PRs.

AI-assisted

@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 18, 2026
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 18, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 18, 2026
@github-actions github-actions Bot added perf Performance change perf numbers missing perf pull request without a before and after summary line unblocks title Names a title ID on the Unblocks line labels Oct 18, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@blawesom

Copy link
Copy Markdown
Contributor

Rebase handoff — rebased onto current main (both commits, authorship unchanged). The GPU-stages target-option conflicts resolved: main's float32FlushToZero/depthRangeRemap fields kept alongside your exactRobustLoads (including its robustBufferAccess2 conjunction), and main's newer sub-range snapshot descriptor (snapshot.offset/snapshot.bytes) kept with your wholeDwordRange rounding applied to it — worth your eye, since the rounding now covers main's sub-range rather than the whole-buffer form you wrote against. No FormatVersion bump (the flag is cache-key-only, matching main's treatment of robustBufferAccess2).

Verified on Linux (CachyOS, kernel 7.2.9, GCC 16.2.1, Ninja, Release, BUILD_TESTING=ON, AMD RX 9070 XT / RADV): builds; conventions pass; full suite green apart from the four known main regressions (#5444 Mesa, #7584 BDA, #7766, #7784), none from this PR.

To pick it up:

git fetch https://github.com/blawesom/AnyPS5 rebase/7484
git checkout <your branch>
git merge --ff-only FETCH_HEAD

Head is 1048ac448.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks @blawesom. I checked 1048ac448 against the current head 2d9224813: every file's added and removed lines are the same as before, tests and docs included, so the conflicts were resolved purely by keeping main's side around the PR's lines. On the rounding: main already used the sub-range snapshot descriptor (snapshot.offset, snapshot.bytes) when this PR was written, so wholeDwordRange covers the same range as before. It only trims range to whole dwords and leaves the offset alone.

@AlxcBTW since this is a rebase rather than a fast-forward, git merge --ff-only FETCH_HEAD will refuse on your branch. git fetch https://github.com/blawesom/AnyPS5 rebase/7484 && git reset --hard FETCH_HEAD, then a force-push, picks it up.

@github-actions

Copy link
Copy Markdown

This pull request is labeled perf, so it needs the summary line of a capture on main and one with the change, from the same title, scene and machine, as the Performance report form asks. Please paste both aps5-summary.jsonl lines, attach the two traces and add the output of tools/trace_digest.py.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 21, 2026
@CPritch

CPritch commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Ran this on GTA V (PPSA04263 01.010.002), Linux 7.2.8-zen1-2-zen, NVIDIA GeForce RTX 5060 Laptop GPU, NVIDIA 615.71.09 (robustBufferAccess2 true, robustStorageBufferAccessSizeAlignment 1), Graphics Mode Performance, the Story prologue after Resume Story, with no input.
main 0c6a5bd (the main this head is based on) against main + #7484 at 16259fa, same machine and session, two runs each in the order A B A B, window frames 3400:700, APS5_TRACE_EVENTS=4194304, APS5_NO_EXACT_ROBUST_LOADS not set. Each side was warmed until it stopped building pipelines, and no timed run built one.

Frame p50: main 77.1, 77.6 ms, with #7484 75.4, 75.9 ms (-1.7 ms, -2.2 %). GPU busy per present: 62.4, 62.3 -> 60.4, 59.8 ms, 2.3 ms less, close to the 2.2 ms in the description.
p99: main 107.7, 108.2 ms, with #7484 108.0, 116.6 ms. The second run's slowest 1 % of frames was slower; what those frames hold was not examined.
Not tested: other scenes, Fidelity mode, other GPUs, Windows. Pictures were not compared.
AI-assisted: yes

Summary lines (main, then the PR):

{"commit":"0c6a5bd5938f","dirty":false,"env":{"APS5_DUMP_FRAMES":"107","APS5_DUMP_FRAMES_EVERY":"30","APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_FRAMES":"3400:700"},"gpu":"NVIDIA GeForce RTX 5060 Laptop GPU","driver":"NVIDIA 615.71.09","os":"Linux 7.2.8-zen1-2-zen","cpu":"AMD Ryzen AI 9 465 w/ Radeon 880M","cpu_threads":20,"memory_mib":31391,"title_id":"PPSA04263","title":"Grand Theft Auto V","content_version":"01.010.002","resolution":"3840x2160","window":{"spec":"frames 3400:700","first_present":3400,"ms":55279.426},"presents":700,"frame_ms":{"p50":77.145,"p90":87.526,"p99":107.714,"max":132.857},"gpu_busy_ms_per_present":62.388,"worker_busy_pct":{"queue worker 0x0":98.147},"top_phases_ms_per_frame":{"Driver.Packet":73.997,"Graphics.Draw":57.414,"Graphics.Draw.draw_and_resource_release":54.136,"Driver.Packet.draw":48.364,"Driver.Draw":48.172,"VideoOut.Flip":25.340,"Driver.Present":25.300,"VideoOut.Flip.present":25.266},"trace_dropped":false,"trace":"aps5-trace-0c6a5bd5938f-3.json.gz"}
{"commit":"0c6a5bd5938f","dirty":false,"env":{"APS5_DUMP_FRAMES":"107","APS5_DUMP_FRAMES_EVERY":"30","APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_FRAMES":"3400:700"},"gpu":"NVIDIA GeForce RTX 5060 Laptop GPU","driver":"NVIDIA 615.71.09","os":"Linux 7.2.8-zen1-2-zen","cpu":"AMD Ryzen AI 9 465 w/ Radeon 880M","cpu_threads":20,"memory_mib":31391,"title_id":"PPSA04263","title":"Grand Theft Auto V","content_version":"01.010.002","resolution":"3840x2160","window":{"spec":"frames 3400:700","first_present":3400,"ms":55336.963},"presents":700,"frame_ms":{"p50":77.573,"p90":87.211,"p99":108.223,"max":115.274},"gpu_busy_ms_per_present":62.299,"worker_busy_pct":{"queue worker 0x0":98.116},"top_phases_ms_per_frame":{"Driver.Packet":74.057,"Graphics.Draw":57.074,"Graphics.Draw.draw_and_resource_release":53.831,"Driver.Packet.draw":48.645,"Driver.Draw":48.452,"VideoOut.Flip":25.278,"Driver.Present":25.233,"VideoOut.Flip.present":25.204},"trace_dropped":false,"trace":"aps5-trace-0c6a5bd5938f-3.json.gz"}
{"commit":"7e2edf15ebe0","dirty":false,"env":{"APS5_DUMP_FRAMES":"107","APS5_DUMP_FRAMES_EVERY":"30","APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_FRAMES":"3400:700"},"gpu":"NVIDIA GeForce RTX 5060 Laptop GPU","driver":"NVIDIA 615.71.09","os":"Linux 7.2.8-zen1-2-zen","cpu":"AMD Ryzen AI 9 465 w/ Radeon 880M","cpu_threads":20,"memory_mib":31391,"title_id":"PPSA04263","title":"Grand Theft Auto V","content_version":"01.010.002","resolution":"3840x2160","window":{"spec":"frames 3400:700","first_present":3400,"ms":54104.652},"presents":700,"frame_ms":{"p50":75.393,"p90":86.689,"p99":107.956,"max":123.118},"gpu_busy_ms_per_present":60.367,"worker_busy_pct":{"queue worker 0x0":98.074},"top_phases_ms_per_frame":{"Driver.Packet":72.337,"Graphics.Draw":56.099,"Graphics.Draw.draw_and_resource_release":52.853,"Driver.Packet.draw":48.050,"Driver.Draw":47.837,"VideoOut.Flip":24.462,"Driver.Present":24.421,"VideoOut.Flip.present":24.386},"trace_dropped":false,"trace":"aps5-trace-7e2edf15ebe0-3.json.gz"}
{"commit":"7e2edf15ebe0","dirty":false,"env":{"APS5_DUMP_FRAMES":"107","APS5_DUMP_FRAMES_EVERY":"30","APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_EVENTS":"4194304","APS5_TRACE_FRAMES":"3400:700"},"gpu":"NVIDIA GeForce RTX 5060 Laptop GPU","driver":"NVIDIA 615.71.09","os":"Linux 7.2.8-zen1-2-zen","cpu":"AMD Ryzen AI 9 465 w/ Radeon 880M","cpu_threads":20,"memory_mib":31391,"title_id":"PPSA04263","title":"Grand Theft Auto V","content_version":"01.010.002","resolution":"3840x2160","window":{"spec":"frames 3400:700","first_present":3400,"ms":54721.349},"presents":700,"frame_ms":{"p50":75.949,"p90":87.600,"p99":116.600,"max":126.659},"gpu_busy_ms_per_present":59.780,"worker_busy_pct":{"queue worker 0x0":98.052},"top_phases_ms_per_frame":{"Driver.Packet":72.866,"Graphics.Draw":56.056,"Graphics.Draw.draw_and_resource_release":52.632,"Driver.Packet.draw":50.412,"Driver.Draw":50.207,"Driver.Draw.shader_compile_and_link":24.780,"VideoOut.Flip":23.329,"Driver.Present":23.287},"trace_dropped":false,"trace":"aps5-trace-7e2edf15ebe0-3.json.gz"}

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 26, 2026
@oneandonlydean
oneandonlydean merged commit d1de04f into boykopovar:main Oct 27, 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* docs perf numbers missing perf pull request without a before and after summary line perf Performance change shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants