Skip to content

fix(agc): resolve sparse indirect index ranges per record - #6606

Merged
adriadam10 merged 3 commits into
boykopovar:mainfrom
veosett:codex/indirect-index-prefix
Oct 19, 2026
Merged

adriadam10 merged 3 commits into
boykopovar:mainfrom
veosett:codex/indirect-index-prefix

Conversation

@veosett

@veosett veosett commented Oct 15, 2026 •

Copy link
Copy Markdown

What

An indexed indirect draw checks all of INDEX_BUFFER_SIZE before reading its records. Guardians of the Galaxy (PPSA01748 v01.006.000) declares 512 MiB over about 54 MiB of mapped index memory and stops at that check during the first level load. Addresses #6526.

Preserve the declared index limit and its address, alignment and overflow checks. If that range is not fully readable, use the existing driver CPU-record path: its checked record/count reads wait for preceding GPU writes, clamp against the original index limit, and validate and prepare only each record's actual index range. Unused holes and tails are not copied or scanned for index values; an active record reaching an unreadable page still throws. Fully readable buffers retain the existing GPU path. The profiler names the fallback index range not fully readable.

The regression compares rendering with a direct reference triangle: 16/32-bit indices, single/counted multi draws, GPU-written records/counts, accessible ranges before and after a hole, and records outside the declared limit. A separate case requires an unreadable active record to fail on its actual six-byte index range. The PM4 test now checks deferred validation while retaining overflow and alignment rejection.

The title report uses #6232 to pass an earlier shader blocker. This fix builds independently of it.

Tested

Merged base main 3259e4c3e; tested head 94bd3c387. Release, bundled dependencies, SPIRV-Tools enabled.

  • Windows 11, WinLibs MinGW-w64 GCC 15.2.0 r7, AMD Radeon RX 6900 XT / AMD 25.10.30.02 / Vulkan 1.4.315: driver and four selected test targets build with their CMake dependencies. 5/5 focused CTests pass in 3.34 s, 2/2 sparse cases with APS5_PIPELINED_DRAWS=0 in 1.05 s, and shader_cache_native_paths 1/1 in 1.69 s. No skips.
  • Ubuntu 24.04 WSL2, GCC 13.3, lavapipe/llvmpipe LLVM 20.1.2, Mesa 25.2.8: the same targets build. 5/5 focused cases pass in 1.85 s, 2/2 inline cases in 0.55 s, and the cache check 1/1 in 0.25 s. No skips.
  • GPU selection was checked per run; Vulkan was required and the AnyPS5 shader cache and pipeline journal were disabled. The five cases are agc_driver_pm4, agc_driver_draw_offset_indices, agc_driver_indirect_patched_stage, agc_driver_sparse_indirect_indices and agc_driver_sparse_indirect_indices_unreadable. The unreadable case still rejects its active six-byte range.
  • The CMake resolution keeps both sparse-indirect registrations and main's implicit-derivative, storage-file-write and enabled/disabled pipeline-trace test settings. Their registrations and 30 s timeouts are checked on both hosts.
  • Conventions, whitespace and test registration pass: 1041 Windows / 1054 Linux test executables, none newly unregistered.
  • Original negative control, not rerun for this refresh: on 31cbb55d7 plus only the new test (62b85a602), both sparse cases fail on Windows and Linux at the full declared-range check.

Independent title evidence: Tamalero's comparison reports three Guardians of the Galaxy runs on two bases with this PR and #6232; the index-range stop is removed and the title reaches a separate compute-shader limitation. This is attributed integration evidence, not a local title run.

Not run here: titles, the full CTest suite, or a performance comparison.

Checklist

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

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 1191 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 1341 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 4072 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5426 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5441 core/libs/prx/libSceAgcDriver/Graphics/include/Draw.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5480 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5499 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Draw.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5656 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Draw.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6146 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6185 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Pm4.cpp
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/Pm4.cpp
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/Pm4.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Draw.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6202 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6249 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6292 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6479 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6539 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6549 core/libs/prx/libSceAgcDriver/Execution/src/Pm4.cpp
core/libs/prx/libSceAgcDriver/tests/Pm4.cpp
PR 6611 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6612 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6615 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6636 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6661 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6683 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6701 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6727 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6730 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6747 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6887 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
core/libs/prx/libSceAgcDriver/Graphics/include/Draw.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6947 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Draw.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6963 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6965 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6973 core/libs/prx/libSceAgcDriver/CMakeLists.txt
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 7008 core/libs/prx/libSceAgcDriver/Execution/src/Pm4.cpp
core/libs/prx/libSceAgcDriver/tests/Pm4.cpp
PR 7048 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7085 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7223 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7254 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7256 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7310 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7332 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7340 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7369 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7505 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7615 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/include/Draw.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 7647 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7800 core/libs/prx/libSceAgcDriver/CMakeLists.txt

@jotitadev jotitadev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran this on NVIDIA, which the PR's GPU list doesn't include.

Machine: NVIDIA GeForce RTX 3070, driver 595.99.02, Vulkan 1.4.329, Ubuntu 26.04 (kernel 7.0.0-38), i7-8700. GCC 15.2, Release, BUILD_TESTING=ON, selected with ANYPS5_GPU="NVIDIA GeForce RTX 3070". Head 925f9a84b merged into main 5d9dcc42d.

  • Test-only (PR tests and CMake, sources from main): agc_driver_sparse_indirect_indices and agc_driver_sparse_indirect_indices_unreadable fail with guest memory is not readable at ... (range ...ff0+0x20000000), and agc_driver_pm4 with the same check on +0x1fffffffc. That is the full-range check the PR describes.
  • With the fix: the focused set (agc_driver_pm4*, draw_offset_indices, indirect_patched_stage, both sparse_indirect_indices modes, 10 tests) passes 3/3, and 1/1 with APS5_PIPELINED_DRAWS=0.
  • ctest -R "^agc|shader|recompiler" -j1 (flip, display and lds_atomics64 excluded): same as main plus the new test. The only failure is agc_driver_store_over_untracked, which fails on main here too (#6347); stencil_ref_export skips (no VK_EXT_shader_stencil_export on this driver).

GPUs tested: NVIDIA GeForce RTX 3070, driver 595.99.02, Ubuntu 26.04

Written with AI assistance (Claude Code). I ran the builds and tests above on my machine.

@SleglJan

Copy link
Copy Markdown
Contributor

A run on a second title with the same stop: 007 First Light (PPSA11386 v01.018.000), on Linux 7.2.10, NVIDIA GeForce RTX 3080 10 GB, driver 615.78.08, GCC 16.2.1, Release with BUILD_TESTING=ON, in a bubblewrap sandbox. Head 925f9a84b merged on top of a bring-up stack: main 4186f06 plus open PRs, unpublished local fixes the title needs to get this far, local logging and scripted input, and the title's two feedback-wait limits widened in its executable as described in #6172 (local only); the merge brings main up to 5d9dcc4. A local change for the same stop that the stack otherwise carries was taken out for this run, so the title's indirect index ranges go through this PR's fallback alone.

The title declares 16-bit indices with INDEX_BUFFER_SIZE 0xffffff, a 32 MiB range, over several separate direct mappings with unmapped pages between them. Without a change for it the title stops at the level load with AGC driver: guest memory is not readable at … (range …+0x1fffffe).

  • With this PR the level load passes and the title reaches gameplay's first tutorial prompt by present 1159. The run ended at present 1223 at its 3600 s time limit, with no fault and no stop.
  • What it costs here, from the draw profiler (APS5_PROFILE_DRAW=1): 2030 indirect draws took index range not fully readable, every CPU-side indirect draw of the run (32,629 went GPU-side). They came between presents 1093 and 1223, in 127 of the 152 profile windows (10 s or longer each) from the first of them to the end of the run: 2 to 60 per window, median 14; 6 per window up to present 1119, mostly 30 to 60 over presents 1121-1155, 2 to 20 after that.
  • The profiler's argument reads for these draws (the count and record reads, with their waits for recorded GPU writers) came to 1610.7 ms in total, 0.79 ms per draw on average; 66 of those 127 windows read under 1 ms, the top tenth over 42 ms, the largest 78.9 ms. The per-record draws after the reads are counted with the ordinary draw phases and are not separated.
  • Frame rates on this stack are set by other changes and are not a measure of this PR.
  • Title run only; no CTest run on this machine.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added build agc libSceAgc* labels Oct 16, 2026
@Tamalero

Copy link
Copy Markdown
Contributor

Title check for #6526 on Marvel's Guardians of the Galaxy (PPSA01748): with this PR the title gets past the indirect indexed draw that #6526 reports.

Same tree with and without this PR's two commits: main 03c4cb5e7 + #6232 (6b662dd8b), which the title needs to get this far. The PR was cherry-picked onto that base (no conflicts). Same relinked executable and route for every run: start a game from the menu and let it load the first level.

Build Runs Result
without this PR 2 (cold and warm shader cache) both stop at AGC driver: guest memory is not readable at 0x3865a0000 (range 0x383240000+0x20000000) / 0x386590000, the #6526 draw (DRAW_INDEX_INDIRECT_MULTI, INDEX_BUFFER_SIZE 0x10000000)
with this PR 1 (warm) no not readable stop; the title runs on until it dispatches compute shader 0x3b91c3e00

That next stop is a separate, already known limit: ShaderRecompiler::Recompile: GetImageResource dword 0 is not a valid runtime value at pc=0x00004380. The same shader fails to prepare at registration in all three runs; it only becomes fatal once the title dispatches it, which the runs without this PR never reached. It's the key noted as unplanned in #6191.

Details

Linux (CachyOS), RTX 4090, i9-14900K, GCC 16.2.1, Release. The title was relinked with --to-intel by the relinker at 03c4cb5e7. Not tested: AMD, Windows, or this PR on its own base 5d9dcc42d.

Tested and written by Claude (AI assistant) on a contributor's machine.

@Tamalero

Copy link
Copy Markdown
Contributor

Follow-up: the same result on this PR's own base. Tree main 5d9dcc42d + #6232 (6b662dd8b) + this PR's two commits (cherry-picked unchanged), same title, route and relinked executable as above, warm shader cache, 2 runs: neither has a guest memory is not readable stop; both run on to the dispatch of compute shader 0x3b91c3e00 (GetImageResource dword 0 is not a valid runtime value at pc=0x00004380) about 2 minutes in, as in the first run.

That's three runs with this PR, on two bases, against two control runs without it that stop at the #6526 draw.

Tested and written by Claude (AI assistant) on a contributor's machine.

@marco-scheffler

Copy link
Copy Markdown

Linux NVIDIA data point: Ubuntu 24.04.4, RTX 4000 SFF Ada Generation, driver 595.99.02, GCC 13.3.0, Release. This PR at 925f9a84b merged onto main c9e6c45de, full ctest on the RTX (ANYPS5_GPU=RTX, Xvfb with -DANYPS5_VIDEO_OUT_TEST_DRIVER=x11): no new failures. The only failures, video_out_flip_eop{,_main,_aftergpu} (#6616) and agc_driver_{f16_fma,fma_mix_f16}_denormal_modes, fail the same way on that main (0/5 serial with and without this PR).

@Scramblrrrr

Copy link
Copy Markdown
Contributor

I can cross-test this on 007 First Light (PPSA11386) on Windows11/RTX5070Ti617.42. Our integration 8e0bd2c (base e5c2b3c plus public 007/shared-table/resource stack) reaches the rendered offline menu at1.963FPS, then Resume aborts during the level load on a full index-range readability check. The local packet diagnostics show INDEX_BUFFER_SIZE=0x00ffffff followed by DRAW_INDEX_INDIRECT; 16-bit indices give the failing declared0x1fffffe-byte span, with an unreadable gap. This looks like the same class as #6526. Raw title data stays local; no title result claimed for #6606 yet.

I fetched925f9a84b and will first build/run the five focused native controls here, then test that level transition. No duplicate implementation. I will report a genuinely unreadable active record separately rather than hiding it or padding the tail. Game has exited; no native tests/builds overlap it. AI-assisted: Codex.

@Scramblrrrr

Copy link
Copy Markdown
Contributor

Windows RTX5070Ti/617.42 results on integration ad3586f, carrying exact #6606 head925f9a84b: 5/5 focused controls PASS2.37s; both sparse-indirect modes with APS5_PIPELINED_DRAWS=0 PASS0.98s; four related import-settle/draw-cache/relocation controls PASS1.90s. Zero skips; ANYPS5_REQUIRE_VULKAN=1. Full native binaries are used (ANYPS5_AGC_EXECUTION_TESTS is empty). Conventions pass; source is clean/pushed at https://github.com/Scramblrrrr/AnyPS5/tree/codex/first-light-oct18-current . The seven-file merge was clean. These are integration cross-tests, not a claimed main-only/Guardians title result.

Matched patched graphics modules are staged, and 007 is restarting with the same warm cache/settings/guards as the preceding declared-range failure. No title outcome for this candidate yet. No build or GPU test runs concurrently with the game. AI-assisted: Codex; title data stays local.

@github-actions github-actions Bot added fix error Closes an issue (Fixes #N) and removed unblocks title Names a title ID on the Unblocks line needs rebase Conflicts with main, rebase needed labels Oct 19, 2026
@adriadam10 adriadam10 self-assigned this Oct 19, 2026
@adriadam10
adriadam10 merged commit d53d0e2 into boykopovar:main Oct 19, 2026
11 of 12 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the per-record path: the CPU fallback reads the records through the checked path, clamps against the declared index limit (Draw.cpp indexed branch) and validates only each record's actual range; the overflow and alignment checks stay in resolveIndirectDraw. The new tests pin both the sparse draws and the six-byte unreadable failure, and the title and NVIDIA/Windows cross-runs in the thread cover what we can't run. Merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* build fix error Closes an issue (Fixes #N)

Projects

None yet

7 participants