Skip to content

fix(agc): throw instead of aborting when a heap mirror cannot be made - #1085

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
Celegans12:fix/agc-host-heap-budget
Oct 9, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
Celegans12:fix/agc-host-heap-budget

Conversation

@Celegans12

@Celegans12 Celegans12 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

What

When the device refused a heap mirror's buffer, or a new mirror would go past APS5_HEAP_MIRROR_MIB, acquireMirror printed a FATAL line and called abort(), so one address-based build short of host memory ended the process. PPSA26344 v1.008 hit it at 478 s, with 6.8 GiB of heap mirrors next to the host imports in the 16 GiB host-visible heap.

Tested

  • Windows 11, MinGW-w64 GCC 15.2.0, based on main 9619edf: configure -DBUILD_TESTING=ON, full build, --target libs, ctest:
  • 406/406 tests pass (ctest --output-on-failure)
  • Same build on lavapipe (Mesa 26.2.4 llvmpipe, 8-wide subgroups, VK_DRIVER_FILES): 405/405 pass; agc_driver_flat_store is left out there because it takes several minutes on Windows llvmpipe
  • agc_driver_graphics (APS5_HEAP_MIRROR_MIB=4, mock memory limit): a mirror past the budget is made in the memory of the expired mirror swept first; a refused one fails its build with Vulkan result -2 after one allocation attempt, and is made once the limit is lifted. Fails on main: FATAL: heap mirror of ...: past the budget, then abort().
  • PPSA26344 v1.008 with feat(agc): host import windows, least-recent eviction under the budget #290 (previous revision, same until a refusal): no FATAL in 900 s, host memory peaked at 13.1 of 15.9 GiB.
  • Not tested: Linux (CI), console behaviour.

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 in TechnicalDebt
  • 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
  • AI-assisted: yes

@oneandonlydean

Copy link
Copy Markdown
Collaborator

acquireMirror retries the allocation after the device refuses it (GuestBufferMemory.cpp:793-811). Retrying after an error isn't allowed here (#182); please sweep before the first allocation if you want the sweep, and keep the throw. The runtime_error instead of abort() is good.

@Celegans12
Celegans12 force-pushed the fix/agc-host-heap-budget branch from c14e28b to 6ab850e Compare October 8, 2026 04:04
@Celegans12 Celegans12 changed the title fix(agc): retry a refused heap mirror and throw instead of aborting fix(agc): throw instead of aborting when a heap mirror cannot be made Oct 8, 2026
@Celegans12

Copy link
Copy Markdown
Contributor Author

Thanks for pointing me at #182, I hadn't counted a retry after the device refuses as an error-driven fallback, but it is one. I've dropped it in 6ab850e: when a new heap mirror would go past APS5_HEAP_MIRROR_MIB, acquireMirror now sweeps the mirrors whose range is gone before the first and only allocation, and a refusal throws the runtime_error straight away. The test counts allocation attempts now and checks that a refused mirror fails after exactly one. If you'd rather not have the sweep there at all, I can take it out too.

An address-based build whose heap mirror the device refused, or one past
APS5_HEAP_MIRROR_MIB, stopped the process inside acquireMirror. PPSA26344
hit it at 478 s with 6.8 GiB of heap mirrors beside the host imports.

- a mirror that would go past the budget first sweeps the mirrors whose
  registered range is gone, before its allocation; if it still does not
  fit, the build throws "past the budget"
- the mirror is allocated once: a refusal throws with the range, the
  Vulkan result and the mirror totals, so the draw or dispatch fails like
  any other allocation; nothing is registered for the refused range
- the BDA resource tests run with a 4 MiB mirror budget and a mock memory
  limit: a mirror past the budget is made in the swept mirror's memory,
  and a refused one fails after a single allocation attempt
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.

2 participants