Skip to content

AGC: GTA V libSceJobManager compute kernel reads its V#s from a block that is still all 0xFF at capture #3055

Closed

Description

@tibzejoker

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:

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

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

  1. xXPBSXx commented on Oct 11, 2026

    @xXPBSXx
    Contributor

    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 are ffffffff ×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).

  2. tibzejoker commented on Oct 12, 2026

    @tibzejoker
    ContributorAuthor

    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:

    • The descriptor is read unconditionally. The kernel (host address 0x7ff681da1200 in my runs) loads 4 dwords with s_load_dwordx4 from the address in user s[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.
    • The memory is a transient pool, not a fixed table. User s[4:7] of these dispatches is itself a buffer descriptor (for example base 0x2a63e7900, stride 0x18, one record), and the same 64 bytes at 0x2a63e7900 are rewritten by many JobManager kernels in one submission. With APS5_SYNC_DISPATCH=1 and APS5_WATCH_MEMORY=2a63e7900:40 (plus a local print of every change), the contents after successive dispatches were: zeros, all ffffffff (after 0x242d8d000), index and float records (after 0x7ff681dab000, 0x7ff681e26f00), all ffffffff again (after 0x7ff681e27700, which looks like a fill), then 00000814 00000815 ffffffff ffffffff ... (after 0x7ff681e27d00). The same submission also writes bounding-box seeds there with WRITE_DATA (7f800000 x3, ff800000 x3).
    • The usual ordering switches do not change it. The count stays at 3 failing dispatches with APS5_SYNC_DISPATCH=1, with APS5_LABEL_LOCK_EACH=1 (no deferred labels) and with APS5_DRAIN_COMPLETION_LABELS=1.
    • My earlier statement that the block "stays all 0xFF 200 ms later" is not reliable: that probe slept on the queue worker thread itself, which also blocks the work that would have written it.

    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).

  3. tibzejoker commented on Oct 12, 2026

    @tibzejoker
    ContributorAuthor

    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 of 0x..e06200 / 0x..dab000) all read their block at user s[4:5]. That block is written by a 68-word WRITE_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 (all ffffffff).

    On main, resolveGroupAhead (DispatchAhead.cpp) runs dispatch() for later packets of the submission before the packets in front of them have executed. That speculative capture reads the block before the WRITE_DATA lands, 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 ...
    • no in-order failure of any JobManager kernel in the same run.

    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_DATA that 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).

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions