Skip to content

fix(agc): keep the small staging pool on an integrated GPU whose heap has a device-only type - #14076

Open
atinseau wants to merge 1 commit into
boykopovar:mainfrom
atinseau:codex/agc-staging-pool-integrated-gpu
Open

atinseau wants to merge 1 commit into
boykopovar:mainfrom
atinseau:codex/agc-staging-pool-integrated-gpu

Conversation

@atinseau

@atinseau atinseau commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

What

The staging pool's device tier keeps released device-only buffers for reuse. Since #5893 it keeps a sixty-fourth of the largest device-local heap (at least 128 MiB) when that heap is system memory, and an eighth (at least 512 MiB) otherwise. It takes a heap for system memory when every memory type on it is host-visible, on the ground that a discrete GPU always has a device-only type. MoltenVK on Apple GPUs does not fit that rule: it reports one device-local heap, the whole unified memory, with a device-only type beside the host-visible ones. The tier then gets the budget of a dedicated card, 3,594 MiB of idle buffers on a 36 GB M3 Max.

buildContext now records Context::integratedGpu from the device type, and BufferPool::DeviceBudget gives an integrated GPU the system-memory budget whatever its memory types: 449 MiB on that Mac. A discrete GPU keeps the heap check, and APS5_STAGING_POOL_MIB still overrides both. An Intel or AMD integrated GPU that reports a device-only type on its device-local heap takes the smaller budget too. ycbuzi measured one: the Radeon iGPU of a Ryzen 9 7900 on Windows has a 10.52 GiB device-local heap with device-only types, so the tier goes from 1.25 GiB to 160 MiB there (see Tested).

Tested

macOS 27.0.1, Apple M3 Max (36 GB), MoltenVK 1.4.2 from Vulkan SDK 1.4.363.0, Release build with -DBUILD_TESTING=ON. main does not build its libraries on macOS, so both sides of the tests below are main 4bc9e779a with the macOS port (the squash of #8658, which its author is upstreaming in parts), #13220 and three local build fixes; the change is this commit on top. This branch is that commit rebased on main 0f302813c, where BufferPool.cpp, BufferPool.hpp and stagingPoolBudgetTests are unchanged.

  • agc_driver_graphics: stagingPoolBudgetTests (mock memory properties, no GPU) gains two cases on a 16 GiB device-local heap with a device-only type: an integrated GPU gets 256 MiB, and 192 MiB under a reported budget of 12 GiB. With the integratedGpu condition taken out of DeviceBudget the test fails with "an integrated GPU's device-local heap with a device-only memory type was not taken for system memory"; with it, it passes.

  • Focused tests on both sides with VK_LAYER_KHRONOS_validation, ANYPS5_REQUIRE_VULKAN=1 and ANYPS5_NO_SHADER_CACHE=1 (ctest --test-dir build-macos -R '<pattern>' -V over agc_buffer_pool*, agc_device_memory_fallback, agc_driver_graphics, agc_driver_pooled_buffer_range, agc_driver_multisample_retirement, agc_driver_host_import_failure_handles, agc_storage_write_back, agc_driver_sampled_cache_budget* and agc_driver_storage_cache_budget, 13 tests): neither log reports the layer missing, every test keeps its status (12 pass, agc_driver_multisample_retirement fails on both sides) and each test has the same VUID- errors on both sides (8 in all, VUID-VkDeviceCreateInfo-pProperties-04451, from MoltenVK's portability subset).

  • Reanimal (PPSA23372), the device: part of the [bufferpool] line (APS5_PROFILE_DRAW=1): at boot the tier's budget reads 3594 MiB on the base and 449 MiB with the change. Past that, both stop at the title's first 64-bit image atomic, which main cannot run on MoltenVK yet.

  • Reanimal on our local macOS branch (the bring-up described in fix(relinker): keep moved instructions off a function entry after padding #11413), the same build with and without this commit, warm caches, 170 s from boot through the main menu into a new game load:

    Build Runs Budget Kept at 170 s Misses Evictions Peak footprint
    without 5 3,594 MiB 811 to 1,013 MiB 72 to 112 0 10 to 12 GiB
    with 4 449 MiB 439 to 448 MiB 1,591 to 1,759 1,712 to 1,882 10 to 11 GiB

    The change keeps about 400 MiB less of idle buffers in this window. The cost is the one perf(agc): keep a smaller staging pool on system-memory heaps #5893 measured on its Arc iGPU: the title's working set of these buffers is larger than the budget, so the tier misses and evicts about ten times a second (misses and evictions are those of the three runs with the change that reached 170 s). One of the four runs with the change stopped with SIGBUS 61 s in; none of the five without it did. The investigation shows that this fault does not depend on the budget. The investigation ran 14 runs on one binary, alternating the default budget and APS5_STAGING_POOL_MIB=449. Both SIGBUS in them came with the default budget, and both are a guest read of guest memory that the macOS runtime maps without access, a path that does not reach the staging pool. The same 14 runs had two GPU hangs, both with the 449 MiB budget. Two later series, with the memory guard raised so the default runs could be followed to 170 s, show that these hangs do not depend on the budget either: the device was lost in 3 of 7 runs with the default budget and 3 of 8 with 449 MiB, and for each loss the system log names a command buffer of WindowServer or of the iOS Simulator's Metal host as the cause, or none, with Reanimal's command buffers discarded as innocent victims.

  • Frame time, Reanimal's main menu, 20 s captured with APS5_TRACE_SECONDS=45:20 after the menu came up, two runs of each build, alternated: frame p50 252.0 and 242.1 ms without the change, 242.2 and 247.4 ms with it, GPU busy 172 to 181 ms per present in all four. The tier is at its budget and evicting in this scene; the frame rate is bound by the GPU at about 4 FPS, so these runs show no cost at this frame rate, nothing finer. Summary lines below; the traces are available on request.

  • AMD Radeon iGPU of a Ryzen 9 7900 (1002:164e), driver 25.10.30.02, Windows 11, run by ycbuzi on this head and its parent: the 13 focused tests above, with VK_LAYER_KHRONOS_validation, ANYPS5_REQUIRE_VULKAN=1 and ANYPS5_NO_SHADER_CACHE=1, pass 13 of 13 on both sides with no VUID- error. The layer was confirmed loaded by a control test. No title was run there.

  • NVIDIA RTX 2000 Ada, driver 595.99.02, Ubuntu 26.04.1, NVIDIA GPU test on this head merged onto main 500d37a: the build passes, and of the 2,444 tests the change can reach, 2,395 pass with no new failure and no new validation ID against main.

  • python3 tools/check_conventions.py --base origin/main passes. tools/pr_overlap.py could not compare 42 open pull requests that conflict with main and share a file with this one (VulkanDevice.cpp, Context.hpp, tests/Graphics.cpp); reading their diffs, only perf(agc): stop pooling released device buffers over the memory budget #4472 touches the same code. It adds the same Context::integratedGpu field, set the same way in buildContext, so that its VRAM budget leaves integrated GPUs alone; whichever of the two merges second keeps the other's field and drops its own two lines.

Not tested: Intel integrated GPUs, and a title on Linux, on Windows or on the AMD integrated GPU. On discrete GPUs the path is unchanged, and stagingPoolBudgetTests keeps its cases for them.

Summary lines, main menu, in run order: commit 42411a4d0 is our branch with this commit reverted, caa2308d0 the same branch with it
{"commit":"42411a4d0019","dirty":false,"env":{"APS5_LOG_TIMESTAMPS":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"45:20"},"gpu":"Apple M3 Max","driver":"MoltenVK 1.4.2","os":"Darwin 27.0.0","cpu":"VirtualApple @ 2.50GHz","cpu_threads":14,"memory_mib":36864,"title_id":"PPSA23372","title":"REANIMAL","content_version":"01.000.006","resolution":"3840x2160","window":{"spec":"seconds 45:20","first_present":204,"ms":20040.125},"presents":79,"frame_ms":{"p50":252.019,"p90":261.268,"p99":291.679,"max":291.679},"gpu_busy_ms_per_present":181.048,"worker_busy_pct":{"queue worker 0x0":99.169,"queue worker 0x20":20.511},"top_phases_ms_per_frame":{"Driver.Packet":298.309,"Driver.Packet.dispatch":205.177,"Driver.Dispatch":176.660,"Vulkan.Dispatch":159.855,"Recorder.Sync":159.282,"Vulkan.Dispatch.shader_resources":159.115,"Driver.Packet.memory_wait":40.810,"Recorder.Submit":28.232},"trace_dropped":false,"trace":"aps5-trace-42411a4d0019-33550.json.gz"}
{"commit":"42411a4d0019","dirty":false,"env":{"APS5_LOG_TIMESTAMPS":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"45:20"},"gpu":"Apple M3 Max","driver":"MoltenVK 1.4.2","os":"Darwin 27.0.0","cpu":"VirtualApple @ 2.50GHz","cpu_threads":14,"memory_mib":36864,"title_id":"PPSA23372","title":"REANIMAL","content_version":"01.000.006","resolution":"3840x2160","window":{"spec":"seconds 45:20","first_present":205,"ms":20020.089},"presents":82,"frame_ms":{"p50":242.068,"p90":247.660,"p99":290.461,"max":290.461},"gpu_busy_ms_per_present":172.131,"worker_busy_pct":{"queue worker 0x0":99.131,"queue worker 0x20":20.402},"top_phases_ms_per_frame":{"Driver.Packet":286.974,"Driver.Packet.dispatch":199.308,"Driver.Dispatch":171.462,"Vulkan.Dispatch":155.309,"Vulkan.Dispatch.shader_resources":154.549,"Recorder.Sync":149.681,"Driver.Packet.memory_wait":36.980,"Recorder.Submit":28.028},"trace_dropped":false,"trace":"aps5-trace-42411a4d0019-35890.json.gz"}
{"commit":"caa2308d0b7a","dirty":false,"env":{"APS5_LOG_TIMESTAMPS":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"45:20"},"gpu":"Apple M3 Max","driver":"MoltenVK 1.4.2","os":"Darwin 27.0.0","cpu":"VirtualApple @ 2.50GHz","cpu_threads":14,"memory_mib":36864,"title_id":"PPSA23372","title":"REANIMAL","content_version":"01.000.006","resolution":"3840x2160","window":{"spec":"seconds 45:20","first_present":212,"ms":20160.226},"presents":83,"frame_ms":{"p50":242.170,"p90":245.502,"p99":276.725,"max":276.725},"gpu_busy_ms_per_present":174.090,"worker_busy_pct":{"queue worker 0x0":99.170,"queue worker 0x20":19.760},"top_phases_ms_per_frame":{"Driver.Packet":283.933,"Driver.Packet.dispatch":191.668,"Driver.Dispatch":160.661,"Recorder.Sync":150.937,"Vulkan.Dispatch":145.253,"Vulkan.Dispatch.shader_resources":144.498,"Driver.Packet.memory_wait":35.229,"Recorder.Submit":29.226},"trace_dropped":false,"trace":"aps5-trace-caa2308d0b7a-34772.json.gz"}
{"commit":"caa2308d0b7a","dirty":false,"env":{"APS5_LOG_TIMESTAMPS":"1","APS5_PAD_INPUT_FILE":"<path>","APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"45:20"},"gpu":"Apple M3 Max","driver":"MoltenVK 1.4.2","os":"Darwin 27.0.0","cpu":"VirtualApple @ 2.50GHz","cpu_threads":14,"memory_mib":36864,"title_id":"PPSA23372","title":"REANIMAL","content_version":"01.000.006","resolution":"3840x2160","window":{"spec":"seconds 45:20","first_present":211,"ms":20196.191},"presents":81,"frame_ms":{"p50":247.408,"p90":253.241,"p99":307.403,"max":307.403},"gpu_busy_ms_per_present":175.321,"worker_busy_pct":{"queue worker 0x0":99.137,"queue worker 0x20":20.481},"top_phases_ms_per_frame":{"Driver.Packet":292.565,"Driver.Packet.dispatch":200.276,"Driver.Dispatch":169.883,"Vulkan.Dispatch":153.607,"Recorder.Sync":153.304,"Vulkan.Dispatch.shader_resources":152.823,"Driver.Packet.memory_wait":39.772,"Recorder.Submit":29.083},"trace_dropped":false,"trace":"aps5-trace-caa2308d0b7a-37031.json.gz"}

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: Apple M3 Max, MoltenVK 1.4.2 (Vulkan SDK 1.4.363.0), macOS 27.0.1; AMD Radeon iGPU of a Ryzen 9 7900, driver 25.10.30.02, Windows 11 (run by ycbuzi); NVIDIA RTX 2000 Ada, driver 595.99.02, Ubuntu 26.04.1 (NVIDIA GPU test)
  • AI-assisted: yes

Context

Found in the Reanimal bring-up on macOS that #11413 describes. On 2026-10-24, on an older form of our local branch, a memory guard stopped Reanimal's new game load at 175 s with 2,481 MiB of idle buffers in this tier (budget 3,594 MiB); with this commit the tier stayed at its 449 MiB budget and the same load ran until the guard stopped it at 441 s, for other memory. The load does not finish on this Mac yet, with or without the change.

… has a device-only type

The staging pool keeps released device-only buffers for reuse in its device tier, up to an
eighth of the largest device-local heap (512 MiB at least), or up to a sixty-fourth (128 MiB at
least) when that heap is system memory. A heap counted as system memory only when every memory
type on it is host-visible. MoltenVK on Apple GPUs reports a single device-local heap, the whole
system memory, with a device-only type beside the host-visible ones, so the tier took the budget
of dedicated video memory: 3,594 MiB on a 36 GB M3 Max.

The device-local heap of an integrated GPU is system memory whatever its memory types, so the
context records an integrated device and the device tier takes the system-memory budget for it:
449 MiB on that Mac. Discrete GPUs keep their budget, and APS5_STAGING_POOL_MIB still overrides it.

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

Reviewed — changes requested

The changed-build evidence includes an unexplained SIGBUS during the Reanimal run, so I cannot approve the cache-eviction change until its relationship to the new behavior is investigated.

What I ran

Reviewed head 24303071a21de966fb22d9fa90962de7aafa1d82 against the PR base 0f302813cebfc09e3e0b6f8fced15262d186879e. The stack check also previewed the head cleanly against live main ca073ec3ad0d766ea9f4658e418a5c977001a353. Environment: Debian Linux 6.1, Python 3.11.2, GCC 12.2.0; no build or CTest run.

python3 tools/pr_precheck.py --repo boykopovar/AnyPS5 --pr 14076 --output-dir /tmp/anyps5-14076-review
git diff --check 0f302813cebfc09e3e0b6f8fced15262d186879e...24303071a21de966fb22d9fa90962de7aafa1d82
python3 tools/pr_stack_check.py 14076 --repo boykopovar/AnyPS5 --output-dir /tmp/anyps5-14076-review/stack

Results

Check Result
Patch and conventions Passed.
Dependency and merge preview No declared dependencies; clean preview against live main ca073ec3ad0d766ea9f4658e418a5c977001a353.
Source and added budget assertions The change applies the smaller budget to integrated GPUs and adds two corresponding DeviceBudget assertions. I inspected these but did not execute the C++ test.
Precheck helper steps The ABI and test-quality helpers could not launch because those reviewer-only scripts are absent from the isolated PR checkout; no ABI files changed.
Author-reported runtime evidence The PR description reports one changed-build SIGBUS after 61 seconds, during a run with 1,428 misses and 1,547 evictions; none of five comparison runs crashed. The other three changed runs reached the 170-second limit. This is reported evidence, not independently reproduced, and does not establish causation.
Hosted CI Conventions, library portability, intake, labels and report passed; Windows was in progress at the last check; Linux and specialized jobs were skipped.
Raw outputs

git diff --check produced no output:

Conventions check:

All conventions checks passed.

Precheck helper errors:

/usr/bin/python3: can't open file '/tmp/anyps5-14076-review/head-24303071a21d-3ea03f0d/tools/pr_abi_audit.py': [Errno 2] No such file or directory
/usr/bin/python3: can't open file '/tmp/anyps5-14076-review/head-24303071a21d-3ea03f0d/tools/pr_test_quality.py': [Errno 2] No such file or directory

Stack check output:

/tmp/anyps5-14076-review/stack/stack-report.md
/tmp/anyps5-14076-review/stack/stack-report.json

Hosted checks at the last status query:

windows	pending	0	https://github.com/boykopovar/AnyPS5/actions/runs/41227149523/job/124613602926
library-portability	pass	1m21s	https://github.com/boykopovar/AnyPS5/actions/runs/41227149380/job/124613577360
linux	skipping	0	https://github.com/boykopovar/AnyPS5/actions/runs/41227149523/job/124613603974
register-context	skipping	0	https://github.com/boykopovar/AnyPS5/actions/runs/41227149523/job/124613604459
relinker	skipping	0	https://github.com/boykopovar/AnyPS5/actions/runs/41227149523/job/124613604379
relinker-asan	skipping	0	https://github.com/boykopovar/AnyPS5/actions/runs/41227149523/job/124613604607
write-watch	skipping	0	https://github.com/boykopovar/AnyPS5/actions/runs/41227149523/job/124613603893
conventions	pass	18s	https://github.com/boykopovar/AnyPS5/actions/runs/41227149244/job/124613577638
eligibility	pass	4s	https://github.com/boykopovar/AnyPS5/actions/runs/41227149523/job/124613577900
intake	pass	18s	https://github.com/boykopovar/AnyPS5/actions/runs/41227149325/job/124613577968
labels	pass	6s	https://github.com/boykopovar/AnyPS5/actions/runs/41227149332/job/124613578035
report	pass	38s	https://github.com/boykopovar/AnyPS5/actions/runs/41227149367/job/124613577068

Negative control

Assertion Mutation or change Did the new test fail?
An integrated GPU with a device-only heap gets the smaller staging budget. The author reports removing the integratedGpu budget condition. Author reports the added assertion fails; I did not run this mutation locally.

Findings

Blocking

The PR's own comparison reports one SIGBUS in a changed-build Reanimal run and none in five runs without the change. The crash occurred after substantial cache churn (1,428 misses and 1,547 evictions); the cause is unknown, and these counts do not prove the new budget caused it. Because the changed behavior sharply increases eviction frequency, this is a material unresolved stability signal. Please investigate the crash with the available system/crash diagnostics and a repeated matched run, determine whether the new eviction behavior is involved, and fix it if so. If it is unrelated, include reproducible evidence that isolates it from this change. Until then, the runtime behavior is not sufficiently verified for approval.

Non-blocking

The PR includes summary records but says the corresponding traces are available on request. If retaining the frame-time comparison as evidence for the “no cost” statement, please attach the traces and tools/trace_digest.py output for the matched runs so the comparison can be reproduced.

Sources

Not verified

No local build, CTest, macOS run, GPU run, or console run was performed. The author-reported SIGBUS and performance measurements were not independently reproduced. Windows CI was still running; Linux and specialized CI jobs were skipped.

To get this to a good state

Investigate the SIGBUS with repeated matched runs and diagnostics, fix any issue tied to the more frequent evictions, and attach trace/digest evidence if retaining the frame-time comparison. I will rerun the same no-build checks on the updated head.

@github-actions

github-actions Bot commented Oct 31, 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 1395 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 2434 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 4472 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/BufferPool.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/BufferPool.cpp
PR 5021 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 5925 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6188 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6194 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6235 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6280 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6481 core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6548 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6553 core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 6804 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6808 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 6970 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7085 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7256 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7275 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 7410 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7449 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7464 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7642 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/BufferPool.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/BufferPool.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 7668 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 8004 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 8246 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9020 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9335 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9356 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9387 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9675 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9700 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9712 core/libs/prx/libSceAgcDriver/Graphics/include/BufferPool.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/BufferPool.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9748 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9895 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9897 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 9898 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 9915 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 10049 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 10193 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/BufferPool.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/BufferPool.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 10442 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 10867 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11351 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11435 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11436 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11483 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 11825 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 11998 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 12120 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 12567 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 12828 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 12944 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 13148 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/src/BufferPool.cpp
PR 13646 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 13863 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 13920 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
PR 13928 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/BufferPool.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/BufferPool.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 13929 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/Graphics/include/BufferPool.hpp
core/libs/prx/libSceAgcDriver/Graphics/include/Context.hpp
core/libs/prx/libSceAgcDriver/Graphics/src/BufferPool.cpp
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 14032 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 14217 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 14218 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 14344 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 14561 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 14621 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp
PR 14943 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 14944 core/libs/prx/libSceAgcDriver/tests/Graphics.cpp

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@atinseau Please investigate the reported candidate-only SIGBUS before treating the smaller default budget as validated on the affected platform. The change increases eviction churn, and one of four changed-arm runs stopped while all five base runs reached the limit. That is not enough to attribute the fault to the pool, but it also does not establish that it is unrelated. Please preserve the failing evidence, obtain a fault address/backtrace or allocation-lifetime evidence, and compare a matched base/change eviction-heavy run. Resolve a pool-lifetime fault if found, or document concrete evidence that the failure is independent of this change. The device-type classification and budget arithmetic otherwise look correct.

@github-actions github-actions Bot added the agc libSceAgc* label Oct 31, 2026
@atinseau

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I ran the investigation you asked for; here are the results.

The SIGBUS does not depend on the budget. I used one binary: our macOS branch with this commit reverted. I added a local probe to the write watch's fault handler, where an unhandled SIGBUS ends. The probe prints si_addr, the x86 registers, the VM regions of the address and of rip, the write watch's state for the page, and a frame-pointer walk. Then I ran 16 times the same Reanimal scene (170 s from boot into a new game load, warm caches), alternating the default budget (3,594 MiB on this Mac) and APS5_STAGING_POOL_MIB=449, which gives the tier the budget this PR computes. The two arms differ only in the budget.

Default, 3,594 MiB APS5_STAGING_POOL_MIB=449
Runs 7 7
SIGBUS 2 0
GPU hang, device lost 0 2
Stopped by our memory guard 3 2
Reached 170 s 2 3
Largest device tier 745 to 2,632 MiB 449 MiB

Two other runs, one per arm, stopped with SIGSEGV within 6 s of launch, right after the first SIGBUS run; they are left out. The guard stops a run when the title's footprint passes 14 GiB, when the system's wired memory passes 22 GiB, or when free memory falls under 15 % (36 GB Mac).

Both SIGBUS came with the default budget and have the same signature:

  • At 67 s, a read (err 0x4) of 0x91e83b0000 by guest code (the title's libc.prx at +0x13da1, called from the executable). The page belongs to a 128 KiB private region with protection 0 and nothing resident, which the write watch tracks with a recorded protection of 0.
  • At 108 s, a read of 0x7c81428f9c by the executable (+0x2da780d), in the same kind of region (110 MiB, protection 0, nothing resident) and with the same write watch state.

In both cases the guest reads its own memory, which the macOS runtime maps without access. Nothing on that path touches the staging pool: its device tier only holds device-only Vulkan buffers, which the CPU never maps. agc_write_tracking stops the same way on our macOS base, without this change: GuestMemory::HashPage reads a watched page whose protection is 0. The fault belongs to the macOS port, not to this PR; we will look at it separately.

GPU hangs. Two of the seven 449 MiB runs lost the device, at about 110 and 130 s. The system log records a GPU hang caused by a WindowServer command buffer (kIOGPUCommandBufferCallbackErrorHang), with Reanimal's command buffers discarded as innocent victims. Freeing a buffer still in use would show up instead as a page fault or an invalid resource in Reanimal's own work. None of the seven default runs hung, nor did any of the nine runs in the description (four of them with the change). That makes 2 of 11 runs with the smaller budget against 0 of 12 with the default one. That is too few to say whether the extra evictions play a part, and I have no mechanism that would link them; I am reporting it so that it is not missed.

Memory. The default arm also shows the problem this PR addresses: in one run the device tier held 2,632 MiB of idle buffers when the title's footprint passed 15 GiB, and the guard stopped it at 123 s.

The probe is a local diagnostic and is not part of this PR; its logs are available if useful.

@ycbuzi

ycbuzi commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

A Windows run on an AMD integrated GPU, since your description says you had none to measure on. It has the shape you describe. AMD Radeon iGPU of a Ryzen 9 7900 (1002:164e, driver 25.10.30.02), Windows 11, WinLibs GCC 15.2.0, Release. Head 24303071a2 and its parent 0f302813ce.

Memory layout, from vulkaninfo: the device-local heap is 10.52 GiB, with a reported budget of 10.00 GiB. Types 0 and 8 on it are DEVICE_LOCAL only, and types 4 and 12 are device-only too, so systemMemoryHeap returns false here and main treats this as a dedicated card.

What that means for the budget, worked out from DeviceBudget, not read from a log:

Rule Device tier
main budget / 8 1.25 GiB
This PR budget / 64 160 MiB

So this PR does change behaviour on this kind of GPU, by a factor of 8.

Focused tests, your set of 13 (agc_buffer_pool*, agc_device_memory_fallback, agc_driver_graphics, agc_driver_pooled_buffer_range, agc_driver_multisample_retirement, agc_driver_host_import_failure_handles, agc_storage_write_back, agc_driver_sampled_cache_budget*, agc_driver_storage_cache_budget), with ANYPS5_GPU=Radeon, ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1 and VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, one run on each side from a non-elevated process:

Result VUID- lines Missing-layer lines
Parent 13 of 13 pass 0 0
Head 13 of 13 pass 0 0

The layer was confirmed loaded by a control run of agc_driver_vertex_fetch on each side, which wrote 43 lines to a layer log. Selected GPU in both logs is the Radeon. agc_driver_graphics also passes 2 of 2 on the head, and tools/check_conventions.py passes.

Not tested: a title on this GPU. So this doesn't show whether the smaller tier costs frame time through more buffer churn here, which is the question @oneandonlydean raised for your Mac.

AI-assisted: yes (Claude Code)

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head 2430307 merged onto main 500d37a · tested 2026-10-31 21:29 UTC · 19 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 2,395 passed · 5 failed (0 new, 4 also fail on main, 1 unstable on main) · 44 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 2,444 of 3,085 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (924 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 46.3 s, ⚠️ agc_driver_graphics_maps_fallback 30.9 s, ⚠️ agc_driver_graphics 30.1 s
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)
agc_submit_progress_no_timeline: failed in 9 of the last 10 main runs
Failing on main too (4, not counted against this PR)
agc_driver_idle_store_yields
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validation IDs already present on main (5 IDs in 476 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (476 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 468 more
VUID-vkCmdCopyImage-srcImage-01548 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_prepared_exports
VUID-VkShaderModuleCreateInfo-pCode-08737 (1 test): agc_driver_image_sample_derivatives
Skipped (44)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_dcc: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_deferred: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_main: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_fresh: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_f
Reproduce
git fetch origin 24303071a21de966fb22d9fa90962de7aafa1d82 500d37a747c2b958e8696aa16213a0ee78d47505
git checkout 500d37a747c2b958e8696aa16213a0ee78d47505 && git merge --no-ff 24303071a21de966fb22d9fa90962de7aafa1d82
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

@atinseau

Copy link
Copy Markdown
Contributor Author

Thanks @ycbuzi, that is the case I could not test. It is the one #5893 aimed at: the 10.5 GiB device-local heap of that iGPU is system memory, and main lets the tier keep up to 1.25 GiB of idle buffers in it. The open question is still the cost of the extra misses in a title. On the Mac the main menu showed no frame-time difference, but it is GPU-bound at about 4 FPS, so it says little about a faster scene.

@atinseau

Copy link
Copy Markdown
Contributor Author

I ran a second series for the GPU hangs of my previous comment. They reproduce, and only with the smaller budget.

Setup. One binary (our macOS branch with this commit reverted, plus the local fault probe), the same Reanimal scene (170 s from boot into a new game load, warm caches), 20 runs alternating the default budget (3,594 MiB on this Mac) and APS5_STAGING_POOL_MIB=449, which gives the tier the budget this PR computes.

Default, 3,594 MiB APS5_STAGING_POOL_MIB=449
Runs that booted 10 9
Device lost after a GPU hang 0 6, at 102, 115, 130, 134, 155 and 156 s
Stopped by our memory guard 9, between 120 and 157 s 1
SIGSEGV 1, at 70 s 0
Reached 170 s 0 2

The memory guard stops a run when the title's footprint passes 14 GiB or the system's wired memory passes 22 GiB, so the default runs could not be followed to 170 s. Every hang happened after 100 s, so I compared the time each arm was observed from 100 s on. The default runs were observed for 339 s in total, with no hang. The 449 MiB runs were observed for 365 s, counting each run up to its hang or its end, and lost the device six times. With the first series and the runs in the description, the smaller budget now shows 8 hangs in 20 runs, against 0 in 22 runs with the default one.

What the hangs look like. Each one is a GPU recovery. Reanimal's command buffers are discarded as innocent victims, then MoltenVK reports VK_ERROR_OUT_OF_DEVICE_MEMORY and the device is lost (vkWaitForFences recorder: Vulkan result -4). In four of the six cases, the system log names a WindowServer command buffer as the cause of the hang (kIOGPUCommandBufferCallbackErrorHang); the other two log only the victims. No case logs an invalid resource or a GPU page fault, which a buffer freed while in use would usually produce. In both arms the system's wired memory reached 21 to 23 GiB. The 449 MiB runs miss and evict about 1,700 times each, against about 100 misses and no eviction with the default budget.

My previous comment left this open. It now goes against this PR: on this Mac, the smaller budget comes with device loss. I do not know the mechanism yet. The candidates are the allocation churn itself, or the way MoltenVK and the Apple GPU handle frequent private allocations near the wired memory limit. I will look into it before asking for another review. The SIGBUS conclusion stands. The one new guest fault in this series, a SIGSEGV in the default arm, is a read of 0x1800 by the executable (+0x2d550c), outside any watched range.

A first attempt of this series crashed at boot in all 20 runs, in both arms, within six minutes. After that the title booted normally again, so those runs are not counted. One 449 MiB run of the counted series also crashed at boot and is left out.

@JJenkx

JJenkx commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Windows GPU check of head 24303071a2, merged onto main 5bae1a4bc2 (clean merge), run through the shared GPU queue.

  • Machine: Windows 11 Enterprise 10.0.22621, Ryzen 9 5950X, AMD Radeon RX 6700 XT, AMD proprietary driver 26.10.1, WinLibs GCC 15.2.0 UCRT r7, Release, BUILD_TESTING=ON.
  • Tests: 39 tests: the AGC tests whose sources or linked code this PR touches, each repeated 3 times (--repeat until-fail:3) with Vulkan Validation Layers 1.4.363 enabled. All 39 pass, with no validation errors (no VUIDs reported).
  • Not run: no title.

🤖 Generated with Claude Code

@atinseau

atinseau commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

Thanks @JJenkx. The RX 6700 XT is a discrete GPU, so this change leaves its staging pool tier at an eighth of the device-local budget, as on main; your 39 tests passing three times with no VUID confirm that discrete GPUs are unaffected.

The open point is still the device loss I measured on the Mac with the smaller budget (my comment of 31 October). I'm looking into its cause before asking for another review.

@atinseau

atinseau commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

I looked for the cause of the device losses on the Mac. They do not depend on the budget, and my previous comment was wrong to tie them to the smaller one.

Why the second series pointed at the budget. Its memory guard stopped a run when the system's wired memory passed 22 GiB. The default runs keep about 2 GiB more in the device tier, so the guard stopped nine of them between 120 and 157 s, the window where every hang fell. They were never observed where the 449 MiB runs hung.

Two more series with the guard raised. Same binary (our macOS branch with this commit reverted), same Reanimal scene, 170 s, warm caches, guard at 18 GiB footprint and 26 GiB wired, runs alternating the two budgets. One of them also caps both texture caches with APS5_TEXTURE_CACHE_MIB=1024.

Default, 3,594 MiB APS5_STAGING_POOL_MIB=449
Texture caches as on main: runs past 100 s 3 5
Device lost 1, at 162 s 1, at 147 s
Texture caches at 1,024 MiB: runs past 100 s 4 3
Device lost 2, at 111 and 124 s 2, at 121 and 133 s

Three more runs stopped with SIGSEGV (at boot, at 33 s and at 67 s) and are left out; that is the write-watch fault of my first comment, which does not reach the pool.

What loses the device. In every loss, Reanimal's command buffers are discarded as innocent victims of a GPU recovery. The system log names the command buffer that caused it: WindowServer's twice, and twice one of the iOS Simulator's Metal host (SimMetalHost), once with a GPU address fault in a simulator workload, after which SimMetalHost exited. For the two other losses it names none, and on 31 October it named WindowServer for four of the six. The test Mac had five iOS simulators booted and ran at its memory limit: every run, lost or not, took free memory down to 14 to 74 MiB with 23 to 25 GiB wired out of 36 GiB. The losses come from that load, and they hit both budgets alike. On the pool's side, eviction only destroys memory whose batch fence has passed, and no hang or fault was ever attributed to Reanimal.

That settles the two open points of the reviews on this Mac: the SIGBUS and the device losses are both independent of the budget. @oneandonlydean @MarcZX10, could you take another look?

@atinseau

atinseau commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

@MarcZX10 @oneandonlydean, could you take another look? Both points from your reviews now have an answer:

  • The SIGBUS does not depend on the budget. Both faults came with the default budget, as guest reads of memory that the macOS runtime maps without access, a path that does not reach the staging pool (investigation).
  • The device losses on the Mac do not depend on it either. With the memory guard raised, the device was lost in 3 of 7 runs with the default budget and 3 of 8 with 449 MiB. Each time the system log names a command buffer of WindowServer or of the iOS Simulator's Metal host as the cause, or none, and Reanimal's command buffers are discarded as innocent victims (series).

The head is still 24303071a. It merges cleanly with main 4f41f4c37, its checks pass, and the description carries both results.

@oneandonlydean oneandonlydean self-assigned this Nov 5, 2026
@oneandonlydean
oneandonlydean dismissed MarcZX10’s stale review November 6, 2026 08:21

The requested point is answered: atinseau showed the SIGBUS is independent of this change (comments 6548050915 and 6605046004: 16 alternating runs of the same Reanimal scene with a fault probe; both SIGBUS faults came with the DEFAULT budget, on guest reads of a non-resident region). Head 2430307 is unchanged since that evidence.

This branch has not been deployed

No deployments
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.

6 participants