Repository navigation
fix(agc): address-based builds map only memory mapped for the GPU - #1905
Conversation
44759d2 to
cf6ae85
Compare
MarcZX10
left a comment
There was a problem hiding this comment.
Reviewed the complete diff against current main f145139. The registry now carries GPU-access state through direct/flexible mappings and protection changes, and address-based builds omit CPU-only registrations. The tests cover map and mprotect transitions plus BDA inclusion/exclusion; the Linux and Windows CI runs and Conventions all pass. The PR description clearly scopes the remaining directional-permission and CPU-unreadable cases as follow-up work. I found no blocking issue in this change.
|
Native Windows run, since the description only covers Windows under Wine. Setup: Windows 10 (19045), RTX 3060 Laptop (NVIDIA 616.92), MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Head
No title was run. 🤖 Addressed by Claude Code |
|
A data point for the follow-up that registers AnyPS5's libc heap without GPU access: vkQuake (PPSA99010, homebrew, through RADV) allocates ~10,000 small blocks through AnyPS5's libc heap, and every address-based build refreshes a heap mirror for each. Leaving only the libc-heap blocks out of address-based builds in a local spike took the demo from ~22 to ~44 FPS, with correct rendering and no BDA faults. RADV's own memory is also freeable, so excluding every releasable range broke rendering; a real GPU-access flag, as in your follow-up, is what's needed. Windows 11, RTX 5070 Ti. AI-assisted (Claude Code). |
|
Conflicts with main in |
cf6ae85 to
0ac4243
Compare
|
Rebased on main c9da0f9. The conflict in Main's newer tests that register memory the GPU reads ( The test registration step fails on main itself right now: e5c6099 runs |
0ac4243 to
c7ec821
Compare
c7ec821 to
a754a99
Compare
a754a99 to
b5679a9
Compare
The registry records whether a range was mapped or protected with GPU access (0x10/0x20), and an address-based build leaves out ranges without it, as the console's GPU page tables do. The main image is registered without GPU access; the title's own mprotect with GPU bits adds it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
b5679a9 to
c11a9cb
Compare
|
The |
|
Checked the diff against main: every |
What
An address-based build put every readable registered range in its BDA table and imported or mirrored it, including memory the guest mapped for the CPU only. On the console a mapping reaches the GPU only if its protection has GPU access (
0x10read,0x20write).sceKernelMapDirectMemory, flexible maps, fixed remaps andsceKernelMprotect. Reservations and the main image have none; a title's mprotect with GPU bits gives the image pieces access.GuestAllocations::Mutation::AddandProtecttake the flag.Sources:
src/core/memory.hMemoryProt(CpuRead = 1,CpuWrite = 2,GpuRead = 16,GpuWrite = 32).src/kernel/memory.cppCountPageTableEntries(bool gpu)counts a range for the GPU only if its protection hasPROT_GPU_READorPROT_GPU_WRITE, andsceKernelGetPageTableStatsreports the CPU and GPU counts separately.3and sets the GPU bits where the GPU reads: its bundledlibc.prxmaps the malloc heap withsceKernelMapNamedFlexibleMemoryInternal(4h6F1LLbTiw), protection3, at both call sites (+0xb2eb,+0xb4fd); its executable's segments carry only R/W/X flags, and it mprotects the two pieces the GPU reads with0x12and0x11.PPSA36082
During loading and the main menu it registers: the 1 GiB malloc heap at
0x200000000with3, 6784 MiB of direct memory with GPU read and write, and the two 32 KiB image pieces. Its first address-based draw runs on the queue the loader's fence waits on. That draw imported the heap; the import fails to pin (the kernel logsCannot map memory with base addr 0x200000000 and size of 0x40000 pages), the fence is late, and the 512 MiB upload pool overflows (eboot0x28fba9). With this change the heap is not in the table and nothing fails to pin.In my local build I bypassed both problems by hand: a driver option,
APS5_GPU_EXCLUDE=0x200000000+0x40000000, kept that address range out of address-based builds, and a patched executable got through loading with a 2.5 GiB upload pool instead of 512 MiB. Both are specific to this title. This change replaces the first: the title maps its heap with3, which has no GPU access, so address-based builds leave it out without an option. Loading with the original 512 MiB pool also needs the changes below.It also needs #861, #1367, #1249, #290 and a follow-up I will open after this one, which imports GPU-mapped memory when it is mapped and depends on this PR. With those, on main df16c4c with an earlier version of the follow-up, 40 s runs to the main menu: 4/5 pass with this change (the other overflowed at 4.1 s; the pool's margin is thin and that is separate work), 0/3 without it (each overflowed at 503 MiB with the pin failure above).
Local changes not in this PR
I also have these on local branches. They finish making the GPU follow the guest's protection, but I am not opening them because no title I can run needs them. Do you want PRs for them?
libc.prxmaps its heap with3. PPSA36082's only range where CPU and GPU write differ (an image piece mprotected with0x12) gets no GPU stores, and it allocates nothing through AnyPS5's libc heap.WRITE_DATA,DMA_DATA, labels, waits, fills), render targets, index and vertex inputs, DCC keys, display buffers and shader code fault on such memory; texture reads see zeros. The driver's GDS backing and AvPlayer's fallback frames are mapped with GPU access. A counted PPSA36082 run made no access to memory without GPU access.0x10,0x30) reach address-based builds, and AMM PRT pages with no physical memory read zero and drop GPU stores, through an unbound Vulkan sparse buffer (strict residency). Sources: amdgpuAMDGPU_PTE_PRT, which turns off faults on unmapped PRT accesses (gmc_v8_0_set_prt), and RADV reportingsparseResidencyNonResidentStrict. PPSA36082 makes no such mappings and imports nosceAmpr*function.Tested
Linux (CachyOS), x86-64, GCC, 7800X3D / RTX 4090.
guest_memory: a direct map with3has no GPU access,0x32has;sceKernelMprotectto0x13adds it and back to3removes it; flexible maps with3and0x33likewise; the main image has none. Mapping with the GPU bits ignored fails it, and so does registering the image with GPU access.agc_driver_graphics: an address-based build includes a range with GPU access and leaves out one without. Dropping the check fails it.agc_driver_graphicsandagc_driver_flat_storepass;guest_memorypasses the new checks, then stops atCheckMlock(the working-set query), as it does without this change.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)