Repository navigation
AGC: GTA V libSceJobManager compute kernel reads its V#s from a block that is still all 0xFF at capture #3055
Description
Summary
GTA V (PPSA04264) stops on a compute queue worker about 30 s after Story mode starts, on every run so far:
compute shader 0x7ff7f8bb1200: buffer descriptor 1 uses an unsupported type: ffffffff ffffffff ffffffff ffffffff
The shader is a kernel from the title's own sce_module/libSceJobManager.prx (hence the host address). It reads its V#s from two places:
- the user V# table at
user[0:1], which is valid at capture time; - a per-dispatch block at
user[4:5](0x2a63e1000, 0x2a63e2000, 0x2a6406200, ... one 4 KiB slot per dispatch), which is all 0xFF in guest memory when the worker captures the dispatch.
The kernel has no wait loop (its only backward branch, at 0x440, is an element loop), so on hardware that block must hold valid descriptors before the dispatch runs. It looks like the same class as #1787: the dispatch is captured before its producer has written the block. The producer here is a JobManager job, either a CPU job thread or an earlier GPU job.
Evidence
The descriptor words were added to the error message, and a diagnostic hook in the catch block of Driver::dispatch dumps the tables at +0, +100 and +200 ms:
compute 0x7ff7f8bb1200 queue 40 user e56bd648 00780002 00000001 00005204 a63e1000 00000002 00000040 00000000
table 0x2e56bd648 (same at +0/+100/+200 ms):
00000001 00000001 b1ea6000 00240010 00000054 0004a3ac dd45c198 00060014
0000003e 00005204 00000000 00000000 00000002 00000001 3f800000 00000000
block 0x2a63e1000 (same at +0/+100/+200 ms):
ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ...
It is the same on queue 32 (block 0x2a63e2000). Caveat: the hook sleeps on the worker that failed, so that queue was stalled while it watched. If the title waits on that queue before it fills the block, as in #1787, the block staying 0xFF proves nothing about a late write.
Things that did not change the result:
APS5_LAND_WAITS_ALL_QUEUES=1+APS5_GROUP_CAPTURE_ALL_QUEUES=1;APS5_NO_COPY_HLE=1;- write watch on or off (
APS5_NO_WRITE_WATCH=1); - with or without fix(libc): track writes to singly mapped direct memory without faults on Windows #637 and feat(agc): host import windows, least-recent eviction under the budget #290.
An older build (main at b69270d plus older versions of the same topics, without #637, #448 or #2917) got through the start of the prologue without this error. Those builds differ in more than this, so it is not a clean bisect yet.
Build
This is not plain main. GTA V needs several open PRs to get this far, so this is main at 4a747c4 with #637, #448 (ported), #2917, #425, #374, #290 (ported), #1940, #1190, #2700, a port of #1491 and two small fixes of mine. The branch is https://github.com/tibzejoker/AnyPS5/tree/gtav-next. The diagnostic hook is the last commit, hack(gtav), which is not meant for upstream.
Windows 11, WinLibs GCC 15.2.0, RTX 4090, i9-13900K, relinked with --to-intel.
Next steps on my side
- Trace which CP packets or CPU job threads write the 0x2a63exxxx slots, with a write watch on the slot after submit, as was done for AGC: a compute dispatch is captured before the title has written its tables when a cross-queue wait passes on a recorded label #1787.
- Bisect main between b69270d and 4a747c4. Among the commits that touch dispatch, perf(agc): stage read and written buffer elements a dispatch sweeps #2681 is the first candidate.
If anyone has seen JobManager kernels read 0xFF descriptor blocks in other titles, or knows what initializes them, pointers are welcome.
AI-assisted: yes (Claude Code).
Activity
xXPBSXx commentedon Oct 11, 2026
Compared with the finding on #3701 (kernel that picks buffer or image from a run-time mode word, all sources reported
active=1): this issue's error is different in kind. The descriptor words here areffffffff×4, i.e. the per-dispatch block was still unwritten at capture, not a valid descriptor of the wrong kind sitting behind an untaken branch, so relaxing the eager validation of untaken sources would not make this dispatch pass. I have not examined the GTA V kernel itself for such a branch.AI-assisted (Claude Code).
tibzejoker commentedon Oct 12, 2026
Update, on current
main(325e0a8) with the PRs GTA V needs to reach Story mode (#425, #290, #637, #448 ported, #423, #1186, #1189, #4082, #4114, #4021), Windows 11, RTX 4090.GTA now plays the North Yankton prologue on that tree, but only because a local hack skips the compute dispatches that hit this error. It still happens: 3 dispatches of the JobManager kernel per run, always with
buffer descriptor 1 uses an unsupported type: ffffffff ffffffff ffffffff ffffffff.What I could narrow down since the first report:
0x7ff681da1200in my runs) loads 4 dwords withs_load_dwordx4from the address in users[4:5]in its entry block, before any branch, and uses them as the V# of its second buffer. So on hardware that memory must hold a valid V# when the dispatch runs; this is not an untaken path being validated eagerly.s[4:7]of these dispatches is itself a buffer descriptor (for example base0x2a63e7900, stride 0x18, one record), and the same 64 bytes at0x2a63e7900are rewritten by many JobManager kernels in one submission. WithAPS5_SYNC_DISPATCH=1andAPS5_WATCH_MEMORY=2a63e7900:40(plus a local print of every change), the contents after successive dispatches were: zeros, allffffffff(after0x242d8d000), index and float records (after0x7ff681dab000,0x7ff681e26f00), allffffffffagain (after0x7ff681e27700, which looks like a fill), then00000814 00000815 ffffffff ffffffff ...(after0x7ff681e27d00). The same submission also writes bounding-box seeds there withWRITE_DATA(7f800000x3,ff800000x3).APS5_SYNC_DISPATCH=1, withAPS5_LABEL_LOCK_EACH=1(no deferred labels) and withAPS5_DRAIN_COMPLETION_LABELS=1.So the V# the kernel needs is produced by an earlier job in the same submission (a kernel or a CP write into that pool), and the capture sees the pool as an earlier fill left it. My next step is to log the pool after every packet, not only after dispatches, around one failing dispatch, to see which packet should have written the V#. If someone knows how libSceJobManager lays out its per-job argument records, that would shortcut this.
AI-assisted (Claude Code).
tibzejoker commentedon Oct 12, 2026
Resolved on current main, as far as I can tell. The error is a speculative capture failure, not a dispatch failure.
The failing dispatches of
0x..1200(and of0x..e06200/0x..dab000) all read their block at users[4:5]. That block is written by a 68-wordWRITE_DATA(64 dwords, so the whole block including the V# at +0xd8) earlier in the same queue 0x20 submission (here@258, dispatch at@16345). When the error appears, the block still holds the previous contents (allffffffff).On main,
resolveGroupAhead(DispatchAhead.cpp) runsdispatch()for later packets of the submission before the packets in front of them have executed. That speculative capture reads the block before theWRITE_DATAlands, throws, and the group capture catches it and stops. When the dispatch is reached in order, the block is written and it recompiles and runs.I logged the two paths separately on main 325e0a8 plus the PRs GTA needs (Windows, RTX 4090):
ahead capture failed serial=10129 @16345 queue=0x20: compute shader 0x7ff681da1200: buffer descriptor 1 uses an unsupported type: ffffffff ...My earlier reports were misled by a local "skip failing dispatches" hack. It also ran during the speculative capture, logged the speculative failure as if it were the real one, and returned without throwing. That hid the in-order outcome. Sorry for the noise. The issue I opened on 2026-10-10 was against an older tree, and I can't reproduce a real failure on current main, so I'm closing it.
The only side effect left is wasted work: the speculative run gives up at the first such dispatch. Treating a large
WRITE_DATAthat the run has already passed as a write that invalidates captures over its range would let the run continue. That would be an optimization, not a fix.AI-assisted (Claude Code).