Skip to content

test(agc): measure pipeline cache hits against the bytes a pipeline adds - #7676

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
DavidAmsellem:test/agc-pipeline-cache-hit-detection
Oct 19, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
DavidAmsellem:test/agc-pipeline-cache-hit-detection

Conversation

@DavidAmsellem

@DavidAmsellem DavidAmsellem commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

What

agc_pipeline_cache_file decides whether a pipeline is already in a cache by creating it and
checking that vkGetPipelineCacheData returns the same size as before. That size is not stable on a
driver that really stores pipelines.

Measured on an AMD Radeon RX 7900 XT (RADV NAVI31, Mesa 25.2.8), with
VkPipelineCreationFeedback as the reference for whether a create hit the cache:

step cache size driver verdict
cache loaded from a blob holding pipeline A 1384 B
create pipeline A 1392 B hit
create pipeline A, four more times 1392 B hit
(other order) create pipeline B, absent 2768 B miss
then create pipeline A, present 2760 B hit

A hit moves the serialized size by +8 or -8 bytes, so the exact comparison reports a hit as a miss
and the test fails on hardware with the cache file lost the pipeline of the object that saved first. The driver keeps both pipelines: vkMergePipelineCaches and the round trip through
vkGetPipelineCacheData were checked separately and report a hit for both pipelines in every
combination.

lavapipe never stores anything in a pipeline cache (every size stays at 32 bytes), so the probe at
the start reads that as a device that does not keep pipelines and the whole test skips. That is why
CI has not seen this: on the only driver it runs, the test never executes.

This sizes each pipeline in an empty cache first and counts a change below half that as a hit, which
separates the 8 byte noise from the ~1348 bytes a real miss adds, with no fixed constant. The skip
now asks the same question directly: a device where a pipeline adds nothing to an empty cache does
not keep pipelines. lavapipe still skips, unchanged.

Open PRs #6958 and #6771 add further holds calls to this test; they do not touch these lines and
this change makes those assertions work on hardware too.

Tested

Linux (Ubuntu 24.04, GCC 13.3), full build, no CI run.

  • agc_pipeline_cache_file on RADV NAVI31: fails 3 of 3 on main, passes with this change.
  • agc_pipeline_cache_file on lavapipe: skips before and after.
  • Full ctest with ANYPS5_REQUIRE_VULKAN=1: 1479 of 1480. The one failure is
    agc_driver_guest_memory_lifetime_direct, which needs read-write access to /dev/udmabuf and is
    unrelated to this change.
  • python3 tools/check_conventions.py --base origin/main passes.

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
  • GPUs tested: AMD, Radeon RX 7900 XT (RADV NAVI31), Mesa 25.2.8, Ubuntu 24.04; Mesa llvmpipe (LLVM 20.1.2), Ubuntu 24.04
  • AI-assisted: yes

vkGetPipelineCacheData is not stable in size on a driver that keeps
pipelines: RADV grows a loaded cache by 8 bytes on the first create and
shrinks it by 8 on a later hit, so an exact size match reports a hit as a
miss and agc_pipeline_cache_file fails on hardware. lavapipe keeps
nothing, so every size stays equal, the probe reads that as a device that
does not store pipelines and the test skips, which is why CI never saw
this.

Size each pipeline in an empty cache first and treat a change below half
that as a hit, and skip on a device where a pipeline adds nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@MarcZX10

Copy link
Copy Markdown
Contributor

The current conventions check fails because the PR template sections What, Tested, and Checklist are empty. The problem summary above is useful, but please move or repeat the implementation summary under What, report the local/CI validation under Tested (or say Not tested), and complete the checklist so the change can proceed through intake.

@github-actions

github-actions Bot commented Oct 18, 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 1368 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 1395 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 5021 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 5925 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6185 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6186 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6188 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6192 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6683 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6747 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6868 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6946 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6947 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6958 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6970 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 6971 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7048 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7258 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7332 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7505 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7604 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
PR 7642 core/libs/prx/libSceAgcDriver/tests/Recorder.cpp

@LeandroLP23

Copy link
Copy Markdown
Contributor

Windows and AMD's proprietary driver, since the description covers Linux and RADV. Radeon 860M (RDNA 3.5, driver 32.0.13058.8001), Windows 11 26300, WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON. Build: main 8a456334f with #7677, #7673, #7671, #7666, #7676, #7675, #7672, #7668, #7664 and #7658 merged together (each merge clean, built once).

agc_pipeline_cache_file and agc_driver_guest_memory_lifetime_direct pass 3 runs of 3. The test saves, merges and reloads the pipeline cache file under %TEMP% as expected.

AI-assisted

@DavidAmsellem

Copy link
Copy Markdown
Contributor Author

Thanks @LeandroLP23. One more data point would settle the scope of this: does
agc_pipeline_cache_file fail on main without this PR on that driver?

Your run has this PR merged in, so it shows the change is good there, but not whether AMD's
proprietary driver hits the same problem RADV does. On RADV the test fails on plain main because a
cache hit moves the vkGetPipelineCacheData size by 8 bytes, which the exact size comparison reads
as a miss (measured with VkPipelineCreationFeedback: the driver reports a hit while the size
changes, and a loaded blob can even shrink by 8 bytes after a hit).

If it already fails on main there, this is AMD-wide rather than RADV-only. If it passes on main
there, the proprietary driver keeps the size stable and only RADV moves it, which is worth recording
either way.

AI-assisted (Claude Code).

@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.

An NVIDIA data point for the scope question: on an RTX 3070 agc_pipeline_cache_file passes on main too, so the exact-size comparison does not misread a hit on this driver. With this PR it still runs (no skip) and passes.

Machine: Ubuntu 26.04, i7-8700, GCC 15.2, Release, BUILD_TESTING=ON. NVIDIA GeForce RTX 3070 (driver 595.99.02) and lavapipe (Mesa 26.0.3, LLVM 21.1.8) on the same host. PR merged onto main 84c1a4d9a (clean). ANYPS5_NO_SHADER_CACHE=1, -j1 --timeout 30.

agc_pipeline_cache_file RTX 3070 lavapipe
main 84c1a4d9a Passed (2 runs, one with -V) Skipped: the device does not keep pipelines in a pipeline cache
head eccc81b50 Passed, 4 runs Skipped, same message

The -V output is the same on main and with the PR: the cache file is saved and reloaded at 6.3, 6.5 or 12.8 KiB, so a second pipeline adds roughly 6 KiB. Since the exact-size comparison on main passes, a hit doesn't move the vkGetPipelineCacheData size on this driver, and the RADV +8/-8 byte drift doesn't show up here. With a miss around 6 KiB, the half-pipeline threshold gives the same verdicts on NVIDIA.

Not run: Windows, AMD, Intel.

GPUs tested: NVIDIA GeForce RTX 3070 (595.99.02) and lavapipe (Mesa 26.0.3), Ubuntu 26.04

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

@MaxLikesCode

Copy link
Copy Markdown

Another driver that really stores pipelines: NVIDIA GeForce RTX 4090, driver 617.42, Windows 11 Pro 26200, WinLibs GCC 15.2.0 r7, Release, BUILD_TESTING=ON. This head (eccc81b) merged into main ad502d7.

agc_pipeline_cache agc_pipeline_cache_file
main 3 of 3 pass 3 of 3 pass
this PR 3 of 3 pass 3 of 3 pass

So the exact size comparison holds on NVIDIA, and the +/-8-byte movement looks specific to RADV. The new check passes here too. All 250 tests tools/select_tests.py selects for this change pass.

AI-assisted: yes (Claude Code)

@thuanquang

Copy link
Copy Markdown
Contributor

@DavidAmsellem for the scope question, on AMD's proprietary driver without this PR: RX 6700 XT (gfx1031, RDNA 2), driver 32.0.21045.5002, Windows 11 26200, plain main 7f596df48, WinLibs GCC 15.2.0 r7, Release.

agc_pipeline_cache and agc_pipeline_cache_file pass 3 of 3, and the file test really runs here (it doesn't take the 77 skip): it saves the 2.2 KiB cache, merges it to 4.4 KiB with the second object's pipeline, reloads it, and prints Pipeline cache file merge tests passed. It also passed in three earlier full-suite runs on this machine (main 505767380, 6685795f7 and 023106ae4). So the exact size comparison holds on this AMD Windows driver, as on NVIDIA; the ±8-byte movement looks RADV-specific.

@oneandonlydean oneandonlydean self-assigned this Oct 19, 2026
@oneandonlydean
oneandonlydean merged commit 1bb7656 into boykopovar:main Oct 19, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants