Skip to content

perf(agc): read a sampled texture's DCC keys once per lookup - #8117

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
johandavidcm:perf/agc-sampled-key-scans
Oct 23, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
johandavidcm:perf/agc-sampled-key-scans

Conversation

@johandavidcm

@johandavidcm johandavidcm commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What

cachedTexture read the DCC keys of one range up to three times in a lookup with nothing written between the reads:

  • the ClearSingle check over a pending image scanned and dropped the result when no keys were held yet;
  • the staged-clear test (observedKeys) scanned on every lookup, though only a lookup with a pending source uses it, and kept nothing;
  • the final read scanned again.

On Windows the key ranges sit in compared host imports, so CollectWrites is 0 and no proof stands in for these scans (#6209 works on that for ProvedClearKeys, which this path does not use). In PPSA31327's gameplay the scans took 12 % of the draw committer's samples, and the committer bounds the frame (#8068).

The lookup now keeps the keys it read until it does something that can change them: the storage source it looks up (which may refresh), the pending source's Refresh, or FlushPending, which can publish unit shadows over the surface even when it flushes no image. The staged-clear test reads the keys only with a pending source. Which keys a lookup acts on is unchanged; only the repeated reads go.

Lookup Key reads before After
Snapshot, no storage source 2 1
Pending source without a clear fill 3 1
Storage-eligible surface that stays a snapshot 3 2
Pending source with ClearSingle keys, storage-eligible 4 2
Storage view 1 1

Reads around a Refresh or a flush are unchanged.

Tested

Windows 11 Pro 26200, WinLibs GCC 15.2.0 (ucrt, posix, seh, r7), Release, NVIDIA GeForce RTX 4070 (driver 617.42), Ryzen 7 7800X3D.

  • Tests on this head, rebased onto main 0c6a5bd. The rebase met main's refreshForView in cachedTexture, which replaced source->Refresh(); it is kept, and the key memo is reset after it, as after Refresh before.

  • With ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1 and VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (Vulkan SDK 1.4.363.0; the loader log shows the layer inserted), ctest -R <the seven below> -V passes on main 0c6a5bd and with this change, and neither log has a VUID- line or a missing-layer message. agc_driver_dcc_key_presync passes --repeat until-fail:20.

  • DccKeyPresync gains RunOneKeyReadPerLookup: a dispatch's first and repeated lookup of a texture with no key writer read its keys at most once under the GPU mutex (KeyWaitCounts().calls). With this change 1 and 1; on main the test fails, reading them twice.

  • Pass with the change: agc_driver_dcc_keys_first_write, agc_driver_staged_clear_sampled_read, agc_driver_dcc_key_presync, agc_driver_graphics, agc_pending_key_stores, agc_shadowed_key_stores, agc_copied_direct_ordering. The full agc_driver_recorder_tests run (not a ctest entry) stops at (9) a scan under a pending write was kept with and without this change.

  • tools/check_conventions.py --base origin/main passes.

PPSA31327 (Yakuza 0 Director's Cut 01.015.000), gameplay after loading the title's autosave, character still, 1920x1080, warm caches.

  • Base 1c230943a = main bf2c63f with fix(agc): accept PA_CL_CLIP_CNTL CLIP_DISABLE as depth clamp #6572 and fix(audioout2): keep each port's grain when ports share a buffer #7719, which the title needs to reach gameplay and play sound; the change is this pull request's commit cherry-picked onto that base (5e81d5a85).
  • Each run started the title, injected the load through APS5_PAD_INPUT_FILE (left and cross at the load prompt) with APS5_NO_PAD_INPUT=1, recorded APS5_TRACE_SECONDS=150:60 with no other trace or profile switch and the log not redirected, and closed the title once the trace was written.
  • Runs alternated A, B, A, B. Every window is steady gameplay: the median frame time of each 10 s inside a window stays within 13 ms, while the runs of one build differ by up to 39 ms (the scene after a load is not identical), so one pair alone says little.
Pair Base p50 (presents in 60 s) This change p50 (presents) Change
1 360.0 ms (165) 304.3 ms (197) -15.5 %
2 321.4 ms (186) 324.8 ms (185) +1.1 %
3 351.0 ms (171) 292.8 ms (204) -16.6 %
4 343.8 ms (174) 314.8 ms (190) -8.4 %
5 350.7 ms (171) 305.8 ms (196) -12.8 %
6 345.5 ms (174) 319.6 ms (188) -7.5 %
Mean 345.4 ms (173.5) 310.4 ms (193.3) -10.1 %

Graphics.Draw on the draw committer drops from 273-307 to 244-268 ms per frame; the GPU stays busy 94-110 ms per present in both.

Pairs 1-4 used the same code built from the uncommitted change (their summary lines say dirty); pairs 5 and 6 used the commit. With APS5_PROFILE_DRAW in separate runs (16 gameplay intervals of 10 s each), the [dcc] line counts per present 7,319 scans, 1,302 MiB and 37.1 ms of scanning on the base, and 2,635 scans, 442 MiB and 12.9 ms with the change.

Summary lines of pairs 5 and 6 (base, change, base, change):

{"commit":"1c230943afb4","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_SECONDS":"150:60"},"gpu":"NVIDIA GeForce RTX 4070","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"1920x1080","window":{"spec":"seconds 150:60","first_present":2299,"ms":60092.008},"presents":171,"frame_ms":{"p50":350.748,"p90":358.247,"p99":371.746,"max":455.105},"gpu_busy_ms_per_present":108.426,"worker_busy_pct":{"queue worker 0x0":98.776},"top_phases_ms_per_frame":{"Driver.Packet":346.693,"Driver.Packet.draw":306.647,"Driver.Draw":303.757,"Graphics.Draw":294.760,"Graphics.Draw.draw_and_resource_release":209.813,"Driver.Draw.shader_compile_and_link":161.547,"Shader.DrawStage":127.357,"Driver.Draw.draw_enqueued":112.812},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":3.500,"events_lost":4189934,"totals_full":false},"draw committer":{"events_full_after_s":9.477,"events_lost":1388692,"totals_full":false}},"trace":"aps5-trace-1c230943afb4-4812.json.gz"}
{"commit":"5e81d5a85e8b","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_SECONDS":"150:60"},"gpu":"NVIDIA GeForce RTX 4070","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"1920x1080","window":{"spec":"seconds 150:60","first_present":2377,"ms":60156.246},"presents":196,"frame_ms":{"p50":305.790,"p90":314.853,"p99":384.782,"max":395.209},"gpu_busy_ms_per_present":98.482,"worker_busy_pct":{"queue worker 0x0":98.502},"top_phases_ms_per_frame":{"Driver.Packet":302.062,"Driver.Packet.draw":265.411,"Driver.Draw":262.615,"Graphics.Draw":252.849,"Graphics.Draw.draw_and_resource_release":174.167,"Driver.Draw.shader_compile_and_link":151.446,"Shader.DrawStage":119.031,"Driver.Draw.draw_enqueued":83.793},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":3.349,"events_lost":4436450,"totals_full":false},"draw committer":{"events_full_after_s":8.891,"events_lost":1509189,"totals_full":false}},"trace":"aps5-trace-5e81d5a85e8b-37776.json.gz"}
{"commit":"1c230943afb4","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_SECONDS":"150:60"},"gpu":"NVIDIA GeForce RTX 4070","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"1920x1080","window":{"spec":"seconds 150:60","first_present":3175,"ms":60319.718},"presents":174,"frame_ms":{"p50":345.546,"p90":352.959,"p99":362.007,"max":438.244},"gpu_busy_ms_per_present":107.930,"worker_busy_pct":{"queue worker 0x0":98.787},"top_phases_ms_per_frame":{"Driver.Packet":342.046,"Driver.Packet.draw":303.453,"Driver.Draw":300.518,"Graphics.Draw":292.150,"Graphics.Draw.draw_and_resource_release":209.114,"Driver.Draw.shader_compile_and_link":160.670,"Shader.DrawStage":126.834,"Driver.Draw.draw_enqueued":110.735},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":3.566,"events_lost":4207546,"totals_full":false},"draw committer":{"events_full_after_s":9.514,"events_lost":1398521,"totals_full":false}},"trace":"aps5-trace-1c230943afb4-37816.json.gz"}
{"commit":"5e81d5a85e8b","dirty":false,"env":{"APS5_NO_PAD_INPUT":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_SECONDS":"150:60"},"gpu":"NVIDIA GeForce RTX 4070","driver":"NVIDIA 617.42","os":"Windows 10.0.26200","resolution":"1920x1080","window":{"spec":"seconds 150:60","first_present":2290,"ms":60191.514},"presents":188,"frame_ms":{"p50":319.585,"p90":325.781,"p99":344.166,"max":425.845},"gpu_busy_ms_per_present":102.473,"worker_busy_pct":{"queue worker 0x0":98.635},"top_phases_ms_per_frame":{"Driver.Packet":315.513,"Driver.Packet.draw":277.388,"Driver.Draw":274.481,"Graphics.Draw":264.238,"Graphics.Draw.draw_and_resource_release":181.399,"Driver.Draw.shader_compile_and_link":158.721,"Shader.DrawStage":124.397,"Driver.Draw.draw_enqueued":87.264},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":3.373,"events_lost":4403692,"totals_full":false},"draw committer":{"events_full_after_s":8.862,"events_lost":1507767,"totals_full":false}},"trace":"aps5-trace-5e81d5a85e8b-37824.json.gz"}

The twelve traces are attached.

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: NVIDIA GeForce RTX 4070, driver 617.42, Windows 11 Pro 26200
  • AI-assisted: yes

@github-actions github-actions Bot added the perf Performance change label Oct 19, 2026
@github-actions

github-actions Bot commented Oct 19, 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 9999 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp L819-820, L841-842

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 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 6202 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 6412 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6498 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6804 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 6970 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7002 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7484 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7618 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7689 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 7833 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8792 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 8998 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9400 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9592 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9674 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9884 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 9897 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10000 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10049 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10064 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp
PR 10193 core/libs/prx/libSceAgcDriver/Graphics/include/ShaderResources.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp

@github-actions github-actions Bot added the agc libSceAgc* label Oct 19, 2026
@Rajkamalcode

Copy link
Copy Markdown
Contributor

SWAG (PPSA22102) mechanism check - measured data

Clean pair on the heavy spawn scene, same save and pad schedule, 360 s per run, stock ini, APS5_PROFILE_DRAW=1; baseline prx 5AB0413B, PR prx 3189DE77 (RTX 3070 / Ryzen 5 5600X, 2026-10-20). DCC rows are medians over the last 30 x 10 s windows; resource rows are cumulative over the run.

Metric baseline run28 #8117 run29 Delta
builds 111,649 110,973 -0.6%
[resources] images 147,887 ms 123,388 ms -16.6%
images per build 1.325 ms 1.112 ms -16.1%
DCC scans / 10 s 91,895 71,855 -21.8%
DCC scanned MiB / 10 s 7,428 5,728 -22.9%
DCC ms / 10 s 541.6 435.4 -19.6%
sampled textures created 41,609 34,007 -18.3%
stage-A records 149,612 123,928 -17.2%
[resources] stage B 172,791 ms 173,190 ms +0.2%

No frame-rate claim. Scene trajectories diverged: run29 recorded 248,781 draws (+20.2%) and 680 presents (+67%) vs run28's 207,013 and 407; guest memory upload also doubled. The single pair is not a frame-time comparison. readTarget moved -3.0% cumulatively despite the extra draws, but it remains noisy and is not a claim here.

Measured takeaway: the memoization is active on SWAG - the direct DCC counters fall about 20%, and the cumulative images phase falls about 16% per build. That is consistent with the PR's mechanism, but a reverse-order pair or a fixed-scene capture is needed before calling it a performance win.

AI-assisted interpretation (separate from the measured table): the images reduction is larger than the draw-count difference and is measured per build, so it looks like a real CPU-side saving rather than only scene drift. I would not merge or claim FPS on this pair alone.

@TheSovietWaffle

Copy link
Copy Markdown
Contributor

Tested on RTX 3080 (NVIDIA 617.42) and AMD Radeon RDNA 2 iGPU (1002:164e, 32.0.21045.5002), Windows 10 Pro 22H2, WinLibs GCC 15.2.0, Release, head 8cd75d779: agc_driver_dcc_key_presync is flaky here. It fails 4 of 10 runs on the RTX 3080 and 2 of 10 on the Radeon, each time on the second new case:

AGC graphics: a dispatch's repeated lookup read the keys of its sampled texture 4 times under the GPU mutex with nothing written between the reads, expected at most once

The first case ("a dispatch's first lookup") never failed. KeyWaitCounts() looks process-wide, so the delta may include key reads that another thread (or work still settling from the earlier cases in main()) makes while the dispatch runs; I have not confirmed that. The other runs pass on both GPUs.

AI-assisted: yes (Claude Code).

@adriadam10 adriadam10 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks, the memoization itself reads correctly (the reset after the storage source, after Refresh and after FlushPending covers the paths that can change the keys). One blocker:

  • core/libs/prx/libSceAgcDriver/tests/execution/DccKeyPresync.cpp:247: RunOneKeyReadPerLookup compares KeyWaitCounts().calls before and after the dispatch, but that counter is process-wide (DccMetadata.cpp, KeyWaitTotals), so key reads from any other thread (or work still settling from earlier cases) land in the delta. @TheSovietWaffle measured it failing 4/10 runs on an RTX 3080 and 2/10 on a Radeon iGPU, always on the second case ("repeated lookup read the keys ... 4 times"). A flaky ctest entry is not acceptable. Please make the count specific to the lookup under test (for example a per-thread counter, or counting only reads made by the calling thread) or quiesce the other readers before taking the baseline, and show it passes repeatedly (ctest --repeat until-fail:20).

Once that is fixed this looks good to merge.

@johandavidcm

Copy link
Copy Markdown
Contributor Author

@adriadam10 @TheSovietWaffle Reproduced here: 7 of 30 runs failed, always the repeated lookup with 4 reads (RTX 4070, 617.42). The extra reads were not another thread's: a temporary per-thread counter saw the same 4 reads on the test thread. Only one of them comes from cachedTexture. The other three come from the storage image that the repeated lookup sometimes refreshes, depending on when the GPU finished: StorageTexture::upload → ProvedClearKeys, and StorageTexture::ProvedKeys → WaitForKeyWriters and ProvedClearKeys. This PR does not touch them, but KeyWaitCounts().calls counts them too, so a per-thread version of it would still fail.

f39d75d counts what the test is about. cachedTexture counts the key scans it makes on the calling thread (SampledLookupKeyScans(), next to ImageTableReuses()), and the test compares that count around the dispatch.

  • ctest -R ^agc_driver_dcc_key_presync$ --repeat until-fail:20 passes, and so does until-fail:100, with ANYPS5_REQUIRE_VULKAN=1 and ANYPS5_NO_SHADER_CACHE=1.
  • With main's cachedTexture plus the same counter, the test still fails: the first lookup scans twice.
  • agc_driver_dcc_key_presync, agc_driver_dcc_keys_first_write, agc_driver_staged_clear_sampled_read, agc_driver_graphics, agc_pending_key_stores, agc_shadowed_key_stores and agc_copied_direct_ordering pass through ctest.

With VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation as well (Vulkan SDK 1.4.363.0; the loader log confirms the layer loads), ctest -R <the seven above> -V passes on main 0d8c51a and with this PR, and neither log has a VUID- line or a missing-layer message.

AI-assisted: yes

@akkadbakkad89

Copy link
Copy Markdown
Contributor

agc_driver_dcc_key_presync flake — RTX 3070 datapoint

Windows 11 Pro 26200, WinLibs GCC 15.2.0 (ucrt, posix, seh, r7), Release, NVIDIA GeForce RTX 3070 (driver 617.42), main 1698d1ea6a + this PR's diff applied (git diff 0d8c51a54..HEAD). 30 consecutive runs of agc_driver_dcc_key_presync_tests per arm, ANYPS5_NO_SHADER_CACHE=1, APS5_NO_PIPELINE_JOURNAL=1.

Head Failures Signature
8cd75d779 (before the own-scan counter) 3 / 30 (runs 14, 24, 30) a dispatch's repeated lookup read the keys of its sampled texture 4 times under the GPU mutex with nothing written between the reads, expected at most once — always the 4-read case
f39d75d62f (current head) 0 / 30 —

Same signature as the RTX 3080 / RTX 4070 reports (always the second case, always exactly 4 reads), and the own-scan counter fixes it here too. So on this driver generation the storage-refresh interleave happens on NVIDIA Ampere as well; 10 % observed rate is in line with the other reports.

AI-assisted: yes (Devin).

cachedTexture read the keys of one range up to three times in a lookup
with nothing written in between: the ClearSingle check over a pending
image dropped its scan, the staged-clear test scanned even without a
pending image and kept nothing, and the final read scanned again. On
Windows the key ranges sit in compared host imports, so no proof stands
in for these scans; in PPSA31327's gameplay they took 12 % of the draw
committer's samples (boykopovar#8068).

The lookup now keeps the keys it read until it does something that can
change them: the storage source it looks up and may refresh, the pending
source's Refresh, or a pending flush, which can publish unit shadows
over the surface even when it flushes no image. The staged-clear test
reads the keys only with a pending source. Which keys a lookup acts on
is unchanged; only repeated reads with nothing between them are gone.

DccKeyPresync checks that a dispatch's lookup with no key writer reads
the keys at most once under the GPU mutex; main reads them twice.
RunOneKeyReadPerLookup compared the process-wide KeyWaitCounts().calls
around a dispatch. The repeated lookup sometimes refreshes the surface's
storage image, and its upload and ProvedKeys read the keys three more
times on the same thread, so the test failed in about one run of four.

cachedTexture now counts the key scans it makes on the calling thread
(SampledLookupKeyScans()), and the test compares that count.
@johandavidcm
johandavidcm force-pushed the perf/agc-sampled-key-scans branch from f39d75d to 2e7494b Compare October 21, 2026 20:47
@johandavidcm

Copy link
Copy Markdown
Contributor Author

Rebased onto main 0c6a5bd. The one conflict was in cachedTexture: main now calls refreshForView(*source, resource) where this PR had source->Refresh(). I kept main's call and the key memo's reset after it; refreshForView still refreshes the image (Refresh, or RefreshLayers for an array view), which can store over the keys.

On the rebased head (RTX 4070, 617.42): the seven focused tests pass, agc_driver_dcc_key_presync passes --repeat until-fail:20, and with the validation layer neither main 0c6a5bd nor this PR logs a VUID- line. The Tested section is updated.

@akkadbakkad89 thanks for the RTX 3070 runs.

AI-assisted: yes

@adriadam10
adriadam10 merged commit ca5f823 into boykopovar:main Oct 23, 2026
12 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

The flake is addressed: SampledLookupKeyScans() counts only the key scans cachedTexture makes on the calling thread, so the storage image's own reads no longer land in the test's delta (confirmed by @akkadbakkad89's 0/30 on an RTX 3070 against 3/30 before). The memo resets after the storage source, refreshForView and FlushPending still cover the paths that can rewrite the keys; merged.

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

Labels

agc libSceAgc* perf Performance change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants