You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AGC: VK_ERROR_DEVICE_LOST (read invalid) on the first scene load only with host imports (Onimusha: Way of the Sword, PPSA27836, NVIDIA) #6374
Onimusha: Way of the Sword (PPSA27836) loses the device on the first scene load after New Game, every run. It only happens with host imports on: with APS5_NO_HOST_IMPORT=1 the same point passes, and the title goes on to the refusal in #6362.
[device-fault] result 5:
[device-fault] read invalid at 0x4840000 (precision 0x1000)
[device-fault] instruction pointer unknown at ... (five waves)
AGC graphics: vkQueueSubmit graphics: Vulkan result -4
Same fault address across runs:0x4840000 in 9 of 10 runs. With APS5_TEXTURE_CACHE_MIB=6000 it moves to 0x4c90000. So it looks like a driver-side allocation, not a guest address.
Last GPU checkpoint (APS5_GPU_CHECKPOINTS=1) is an 8x8x1 wave64 compute program. Its recompiled IR has no buffer accesses. It only has:
two ImageSampleRaw, on 2D format-36 T#s of 256x64 and 32x32;
one ImageQueryDimensions and one ImageWrite to a 3D format-71 16x16x8 storage T#.
The program address differs per run. I have the .req dump if it helps.
APS5_TRACE_HOST_IMPORT=1 before the fault:
About 11,400 live imports (4.08 GiB of the budget), and 3,584 "retired: the range was mapped again" earlier in the load.
No budget refusals.
The last lines before the fault are five "joined at bind" imports in a row. One of them is 0x2116800000+0x1c10000, and the live count drops by 67 there.
host import of 0x212b000000+0x200000 ok (11459 live, 4078.9 MiB live, ...), joined at bind
host import of 0x212cc00000+0x200000 ok (11428 live, ...), joined at bind
host import of 0x2125c00000+0x30000 ok (11426 live, ...), joined at bind
host import of 0x2112c00000+0x180000 ok (11403 live, ...), joined at bind
host import of 0x2116800000+0x1c10000 ok (11336 live, ...), joined at bind
host import of 0x2208400000+0x280000 ok (11297 live, ...), joined at bind
[device-fault] result 5:
Shortly before, the log also has storage image ...: memory no longer registered; N pending ranges dropped and guest memory changed while GPU results were pending.
From reading retireImport and the join path, the replaced imports go through KeepThroughHold, so I don't see where a freed import could still be read. Someone who knows the import lifetime might. I can run any diagnostic build on this title.
I traced the current retirement path and do not see a specific lifetime defect supported yet: retireImport retires shadowed writes, extracts the import into a RetiredImport, and retains it with KeepThroughHold; the existing HostImportRetireHold test covers readback after retirement. The reported 0x4840000 does not match the logged guest import ranges, and changing the host-import switch also changes the whole resource path, so the current evidence shows correlation rather than which resource is invalid. A clean-current-main run without local sample-count changes plus attribution of 0x4840000 to the Vulkan allocation/resource used by the last checkpoint would distinguish host-import lifetime from the sampled/storage-image path. I would hold off changing retirement or join semantics until that mapping is available.
The minimum stack is main plus those PRs. The "local sample-count changes" only widen #5907's sample-zero path:
PS_ITER_SAMPLE is accepted;
PERSP_SAMPLE inputs are taken at sample 0.
This is the same direction fdfawef324 proposes on #5907 for Resident Evil 4. I'm folding it into #5907 now, so the stack will be public PRs only. I'll re-run then, and name the exact heads.
Attributing 0x4840000: no APS5_* switch reports GPU virtual addresses. My plan is a local diagnostic with VK_EXT_device_address_binding_report (debug-utils callback). It logs every bind and unbind of a buffer or image range with its object handle and type, from the first device onward. I'll match the fault address to the object bound there, and check whether it was unbound before the fault. If you'd rather attribute it another way, say so, and I'll run that instead.
1. Clean stack, public PRs only.main44df216 plus #5907 (7ad8cb8), #5841 (63db31f), #5884 (15b0d03) and #5915 (2c8dda1). No local sample-count changes and no other local patches. #5884 conflicts with main's serializer version 30, so locally I moved its new mesh field to version 31; the field is the same. Windows 11 26200, RTX 5070, NVIDIA 617.42, warm shader cache, host imports on (the default). Same path as before: menus, New Game, difficulty, controller layout. Same result on the first scene load:
[device-fault] checkpoint: program 0x21a78f7000 at stage 0x2000
[device-fault] read invalid at 0x4840000 (precision 0x1000)
[gpu] driver failure: AGC graphics: vkQueueSubmit graphics: Vulkan result -4
2. Attributing 0x4840000. I used a local diagnostic (not for merging). It enables VK_EXT_device_address_binding_report (reportAddressBinding) and a debug-utils messenger for DEVICE_ADDRESS_BINDING messages, and logs every bind and unbind from device creation to the fault: 425,319 events over 264 s (VkDeviceMemory 77,923, VkBuffer 342,415, VkImage 4,981).
No event ever covered the fault page[0x4840000, 0x4841000): no bind, no unbind, nothing anywhere in 0x4600000..0x4b00000.
The fault sits inside a gap that is never bound during the whole run. The nearest object below ends at 0x43c2000 (a 64 KiB VkDeviceMemory), and the next one above starts at 0x6a90000.
So the faulting address is not an application buffer, image or memory object that was unbound or freed. It is not a use-after-free of anything the driver created, host imports included (they are VkDeviceMemory, which is reported).
One caveat. NVIDIA reported no driver-internal bindings at all: every event has flags 0, and the instruction-pointer addresses in the fault report (0x20f0dbd00 and others) appear in no event. So 0x4840000 is either an address that was never valid, or driver-internal memory, such as a descriptor or shader heap, that this extension does not report on NVIDIA. With APS5_TEXTURE_CACHE_MIB=6000 the fault moved to 0x4c90000. So the address depends on the allocation layout, which points to a bad pointer or descriptor base computed by the shader, rather than a fixed driver heap.
Next on my side: the faulting compute program has 2 ImageSampleRaw, 1 ImageWrite and no buffer loads (from my earlier dump). I'll compare the descriptor words it is given, at the failing dispatch, against the views they should decode to.
AI-assisted: Claude Code. The diagnostic patch is local; I can share it if useful.
Correction and new data. The compute program I named earlier is not where the fault is. Its checkpoint had reached stage 0x2000 (bottom of pipe), so it had finished. The driver only places checkpoints before dispatches, so whatever ran after it had no marker.
I added a local diagnostic (not for merging). With APS5_GPU_CHECKPOINTS, it wraps the device-proc lookup and gives every draw, dispatch, copy, fill, update, clear and begin-rendering a numbered vkCmdSetCheckpointNV marker with a one-line description. Same stack as my previous comment (main44df216 + #5907#5841#5884#5915), same path, first scene load:
[device-fault] checkpoint: marker 0x...6c67 at stage 0x1 beginRendering 1024x1024, depth only
[device-fault] checkpoint: marker 0x...6c64 at stage 0x2000 drawIndexed 516x1 base 52219
[device-fault] read invalid at 0x4a00000 (precision 0x1000)
So the fault is in one of the two indexed draws between those markers: drawIndexed 139710x1 base 206 or drawIndexed 2919x1 base 1700. Both belong to a depth-only pass. The next 1024x1024 depth-only pass had already started.
On the address side:
In four runs the fault address was 0x4840000 (x2), 0x4a00000 and 0x63f7000. With APS5_TEXTURE_CACHE_MIB=6000 it was 0x4c90000 (earlier).
All of them fall in the same range, 0x43c2000..0x6a90000. The binding report shows nothing is ever bound there, from device creation to the fault, in every run.
Every buffer and image the driver creates is bound above 4 GiB (0x4_xxxxxxxx to 0x6_xxxxxxxx). A pointer whose high 32 bits are lost, or a guest offset added to a null base, would land in exactly this kind of low range. I have not proven either yet.
robustImageAccess2 (local, APS5_ROBUST_IMAGES) does not prevent it: same device loss, at 0x63f7000.
Next: log the faulting draw's vertex and index inputs (V# bases and the BDA ranges they resolve to) to see which pointer has a zero high part.
AI-assisted: Claude Code. Both diagnostics are local.
Negative result: #6522 (09f5749, a multisampled target's commands recorded on its own device, the #6512 race) does not change this. Same stack as above plus #6522, same path: the same device loss on the first scene load, read invalid at 0x62a9000, again inside the never-bound range 0x43c2000..0x6a90000.
Correction to my previous comment. "Every buffer and image the driver creates is bound above 4 GiB" is wrong. The binding log has about 105,000 events below 1 GiB: host imports at 0x13a20000 and 0x15a80000, pool slabs from 0x10160000 up, and so on. So low addresses are normal on this driver, and the truncation idea has no support from the address alone.
What still holds: the fault addresses fall in one hole, 0x43c2000..0x6a90000, which is never bound in any run. Below it there are sixteen 64 KiB VkDeviceMemory/VkBuffer pairs bound at startup (0x42c2000..0x43c2000). Above it the next object starts at 0x6a90000. So a read running past the end of one of those low objects, or an offset applied to the wrong base, would land in this hole. I'm capturing the faulting draw's vertex and index bindings, push constants and descriptor buffers to check that.
The faulting draw, captured. Same stack, same path. Fault at 0x5201000, again inside the never-bound hole 0x43c2000..0x6a90000.
It is the same draw as in my previous run. The checkpoints put it between bottom-of-pipe for the draw before and top-of-pipe for this one:
drawIndexed 139710x1 first 0 base 206 (depth-only 1024x1024 pass)
pipeline 0x186b0d8d0
index 0x140e36d8f50+0x0, VK_INDEX_TYPE_UINT16 -> VA 0x693444000, size 0x4437c (= 139710 x 2 bytes)
vertex 0..2 = buffer A +0x0/+0x13c2c0/+0x13c2c4 -> VA 0x52fc10000, size 0x200000
vertex 3..7, 9 = buffer B +0xef40..+0xe1bcc -> VA 0x596410000, size 0x200000
vertex 8 = 0x1c18854d0+0x0 -> VA 0x3a2d30000, size 0x32feb
push constants: 0x0 0x100000080 0x8000000200 0x0 0x400000000 0x0 0xffffffff 0x0 0x0
Every vertex and index binding is live and sits far from the hole. The index buffer is exactly the size the draw needs.
I also checked every BDA range the driver builds (GuestBufferMemory::addressRange, so in-place imports, mirrors and copies) for one whose device span touches the hole: none in the whole run.
So this draw's own vertex, index and BDA inputs don't point into the hole.
My descriptor-set capture for this draw is not reliable. It kept entries from earlier writes to recycled set handles, so I'm not reporting it.
Open question for someone who knows the NVIDIA side: does the driver keep something of its own in 0x43c2000..0x6a90000? The hole is stable across runs, and the binding report never shows anything there. If this pipeline's vertex input or its descriptors pointed at a driver-internal object, that could explain it. If useful, I can share the pipeline's shaders (the VS/PS guest programs) for this draw.
Ada data point: the first-scene-load device loss reproduces on an RTX 4090, so it is not Blackwell-only.
Setup. Windows 11 (26200), RTX 4090 (NVIDIA 616.92, VK_EXT_device_fault), AMD Ryzen 7 5800X, MinGW-w64 GCC 15.2.0 r7 (UCRT), Release libs. Tree: main5d9dcc4 + #5884 (a0347cf) + #5907 (7ad8cb8), nothing else local; #5915 no longer merges onto main (State.cpp) and is not in. app.exe relinked by main31cbb55's relinker with --windows --windows-fixed-base 0x400000000. Dump 01.000.001 (base, no patch, playgo-chunk.dat present). Host imports on (default), cold shader cache for the scene.
Path. Save-data creation, display and voice language, EULA, brightness (3), initial settings, accessibility, age, privacy notice, autosave notice, title screen, New Game, difficulty, Defensive layout. The first scene load then compiles about 12,600 shaders over roughly six minutes at 2 to 3 FPS, and dies on the GPU:
[device-fault] result 5:
[device-fault] write invalid at 0x5bab000 (precision 0x1000)
[device-fault] instruction pointer unknown at 0x21ca78500 (precision 0x10)
... 14 instruction pointers in 0x21ca78c00..0x21ca7ec50 ...
[gpu] color target 0x2001f40000 stays non-resident: AGC graphics: vkQueueSubmit graphics: Vulkan result -4
[gpu] driver failure: AGC graphics: vkQueueSubmit graphics: Vulkan result -4
what(): AGC graphics: vkQueueSubmit graphics: Vulkan result -4
Two differences from the 5070 runs worth noting: here the fault is a write, not a read, and it lands at 0x5bab000, inside the same never-bound hole you measured (0x43c2000..0x6a90000). The last cache line before it is the scene compile still in progress (0 hits, 787 misses in the preceding 10 s), so on this box the loss comes while shaders are still being produced, not after a warm load. A second run with host imports on also lost the device, but earlier: during the front-end load after the autosave notice, before the title screen was seen (one settings save written, not the New Game one), write invalid at 0x47c0000 on the recorder queue, vkQueueSubmit recorder: Vulkan result -4, warm cache (30,938 hits, 0 misses). So on this box the loss is tied to a load with host imports on, not to the first scene load alone; 2 of 2 runs, both fault addresses inside the hole.
With APS5_NO_HOST_IMPORT=1 (1 of 1, warm cache): no device loss. The front end, title, New Game, difficulty and layout go through, the New Game save is written, and the first scene load then stops on a different refusal than your #6362, since #5915 is not in this tree:
[gpu] driver failure: depth export, shader coverage or ordered fragment execution is unsupported (register 0x203 = 0x00000045)
That is the DB_SHADER_CONTROL mask check in State.cpp (nonzero(cx, 0x203, shaderControlMask(zFormat), ...)): 0x45 sets Z_EXPORT_ENABLE, STENCIL_OP_VAL_EXPORT_ENABLE and KILL_ENABLE, and one of them is outside the mask for that depth format. The card has VK_EXT_shader_stencil_export, so this is not #4276's missing-extension abort, though it is the same stencil-export family. So the host-import correlation holds on Ada as well.
Logs and the input notes are in the #5769 update: #5769 (comment) Not run: #5915 (conflicts), #6522, a second run with host imports on.
@frankea thanks, this is useful. It rules out a Blackwell-only cause, and the write at 0x5bab000 and the recorder-queue loss at 0x47c0000 both land in the same never-bound hole, so the fault address keeps pointing at the same region on two architectures and on two queues.
Both of your trees and all my runs since 2026-10-15 already contain #6060 (merged as 0afa6a6), so that change doesn't avoid the loss.
On the APS5_NO_HOST_IMPORT=1 path: my tree is main4eb91ea + #5907 + #5884 + #5915 + #6557, and its first scene load does not log the 0x203 = 0x00000045 refusal. It stops later, at the native depth publication refusal tracked in #6570. I haven't checked which of #5915 and #6557 (or the order of the scene's draws) keeps it from reaching that check, so I can't say #5915 alone avoids it. #5915 still merges onto today's main5d9dcc4 for me, with the State.cpp resolution SandstromPL and I described on that PR.
Correction to my comment above, @frankea: my tree does reach the 0x203 = 0x00000045 refusal. It reaches it later, because the depth publication stop (#6570) came first in the same load. With #6727 on top of my stack that stop is gone, and the first scene load now ends at the same DB_SHADER_CONTROL refusal you saw, with APS5_NO_HOST_IMPORT=1. I haven't checked why your tree, without #5915, #6557 and #6727, reached it without the earlier stops.
Negative result for #6763, which copies draw vertex and index inputs on Windows instead of binding them in place from host imports.
Tree: maineb901bc + #5907 + #5915 + #6557 + #6727 + #6762 + #6763, host imports on (default), APS5_GPU_CHECKPOINTS=1, cold shader cache, RTX 5070 (617.42), Windows 11 26200. Same path as before: menus, New Game, difficulty, layout. The New Game save is written, then the first scene load compiles shaders for about 2 minutes (about 21,000 by then) and the device is lost:
[device-fault] checkpoint: program 0x223ead6d00 at stage 0x1
[device-fault] checkpoint: program 0x223ead6d00 at stage 0x2000
[device-fault] read invalid at 0x5103000 (precision 0x1000)
0x5103000 is again in the never-bound range 0x43c2000..0x6a90000. So the in-place binding of draw inputs from host imports is not what reads there. #6763 is out of our stack for this issue.
Ampere data point: the first-scene-load device loss also reproduces on an RTX 3080, so that's three NVIDIA generations (Blackwell, Ada, Ampere).
Setup. Windows 10 Pro 22H2 (19045), RTX 3080 (NVIDIA 617.42), Ryzen 7 7800X3D, WinLibs GCC 15.2.0 r7, Release libs. Tree: main452494439 + #7005 (SDL WGI off; this host faults in Windows.Gaming.Input.dll without it) + #6196. Dump 01.000.001, owned. Relinked with --windows --windows-fixed-base 0x400000000. Host imports on (default).
Path. Setup screens, title screen, settings, New Game, layout, then the first scene load:
[device-fault] result 5:
[device-fault] write invalid at 0x5a94000 (precision 0x1000)
[gpu] driver failure: AGC graphics: vkQueueSubmit recorder: Vulkan result -4
Recorder queue, a write, at 0x5a94000: also inside the never-bound range 0x43c2000..0x6a90000. No checkpoints in this run (APS5_GPU_CHECKPOINTS unset).
APS5_NO_HOST_IMPORT=1 path, for comparison. With #5915 + #6557 + #6727 + #6762 on the same base, the load passes the device loss. On this GPU the next stop was the NVIDIA stencil export emulation refusal (stencil reference export emulation requires a proven set of at most 16 values, pixel shaders 0x2112444f00 and 0x210687de00, #4276). With a change that replays all 256 eight-bit values for an unbounded export (#7006, closed for now by the open-PR limit), it goes on to the #6570 publication stop, as on your RTX 5070.
Not run: APS5_GPU_CHECKPOINTS=1, repeated runs for the fault address's stability.
@MarcZX100 the clean-current-main run you asked for is now possible. Current main reaches the first scene load without any of the refusals that stopped it earlier. The title needed only one libc export to get there, which #7506 adds.
Tree: main b51c65d + #7506, no other PRs and no local changes. Windows 11 26200, RTX 5070 Ti (NVIDIA 617.42), WinLibs GCC 15.2.0 r7, Release. Dump 01.000.001, relinked with --windows, APS5_PLAYGO_UNLISTED_CHUNKS=installed (the dump has no PlayGo metadata). Same path: menus, New Game, difficulty, layout, then the first story-mode load.
Host imports on (default), APS5_GPU_CHECKPOINTS=1. The device is lost early in the load:
[device-fault] no checkpoint reached
[device-fault] result 5:
[device-fault] read invalid at 0x4840000 (precision 0x1000)
[device-fault] instruction pointer unknown at 0x2011322f0 (precision 0x10)
[device-fault] instruction pointer unknown at 0x201130000 (precision 0x10)
[device-fault] instruction pointer unknown at 0x2010f4c00 (precision 0x10)
[gpu] driver failure: AGC graphics: vkQueueSubmit graphics: Vulkan result -4
0x4840000 is the same address as most of @simonbronk's RTX 5070 runs, inside the never-bound range 0x43c2000..0x6a90000. An earlier run of the same tree without checkpoints also ended in Vulkan result -4 during this load (fault address not captured).
APS5_NO_HOST_IMPORT=1 (plus APS5_GPU_CHECKPOINTS=1), same tree. No device loss. The load gets further (about a third of the progress bar) and stops on the refusal @frankea reported:
[gpu] driver failure: depth export, shader coverage or ordered fragment execution is unsupported (register 0x203 = 0x00000045)
So the host-import correlation holds on current main with no open PRs in the tree besides the libc export. One run each way.
Not run: #7446, repeated runs, the binding report.
#7446 on PPSA27836, as listed under "Not run" above.
Tree: upstream/main385ed71 + #6727 (rebased today, carries #6557) + #6762 + #7446 (3fd9a62). Windows 11 Pro 26200, RTX 5070 (NVIDIA 617.42), WinLibs GCC, Release. Host imports on (default), APS5_GPU_CHECKPOINTS=1, APS5_PROFILE_DRAW=1, APS5_BINDLESS_MATERIAL_SCAN=65536, cold shader cache. Same path: menus, New Game, difficulty, layout, then the first story-mode load. GPU tests on this tree: ctest -R "agc|shader|video_out" 743/743 on NVIDIA.
Result: no device loss in this run. The load stops on a different refusal, about 560 s after boot:
[gpu] driver failure: shader 0x2107d3b200 stage 5: ShaderRecompiler::Recompile: stencil reference export emulation requires a proven set of at most 16 values
[videoout] presentation failed: shader 0x2107d3b200 stage 5: ...
That is #4276's case, which #7006 targets. With #6762 in the tree, the register 0x203 = 0x00000045 refusal from the no-host-import run is not reached.
#7446 did not act in this run. All 46 [labels] reports show 0 packets redone for a queued label over the capture, 0 for captured memory that changed. The snapshot warning of frankea's run (0x2112c009d0) did not appear either. Two other mismatches did (0x210d800038+0x10 and 0x210dc00180+0x38, live region 0x210d800000+0x800000).
So I can't credit #7446 with the missing device loss. One run only: the stencil refusal may simply come before the point where the device was lost. Next step: #7006 on top of this tree, to see whether the load then completes or the read invalid at 0x4840000 comes back.
Activity
MarcZX10 commentedon Oct 15, 2026
I traced the current retirement path and do not see a specific lifetime defect supported yet:
retireImportretires shadowed writes, extracts the import into aRetiredImport, and retains it withKeepThroughHold; the existingHostImportRetireHoldtest covers readback after retirement. The reported0x4840000does not match the logged guest import ranges, and changing the host-import switch also changes the whole resource path, so the current evidence shows correlation rather than which resource is invalid. A clean-current-main run without local sample-count changes plus attribution of0x4840000to the Vulkan allocation/resource used by the last checkpoint would distinguish host-import lifetime from the sampled/storage-image path. I would hold off changing retirement or join semantics until that mapping is available.simonbronk commentedon Oct 15, 2026
Thanks @MarcZX100, agreed that the switch only shows correlation.
A clean
mainrun can't reach this point. On currentmain, the title stops much earlier, on refusals that open PRs handle:unsupported geometry input or output assembly(feat(agc): draw line-strip output of NGG geometry programs as mesh lines #5884);guest buffer view ... exceeds its GPU owner(fix(agc): bind a read-only V# over the cached address space through the region that holds it #5815);the depth target's sample count differs from the rasterizer's(feat(agc): rasterize a multisampled draw into one-sample targets at sample 0's locations #5907).The minimum stack is
mainplus those PRs. The "local sample-count changes" only widen #5907's sample-zero path:This is the same direction fdfawef324 proposes on #5907 for Resident Evil 4. I'm folding it into #5907 now, so the stack will be public PRs only. I'll re-run then, and name the exact heads.
Attributing
0x4840000: noAPS5_*switch reports GPU virtual addresses. My plan is a local diagnostic withVK_EXT_device_address_binding_report(debug-utils callback). It logs every bind and unbind of a buffer or image range with its object handle and type, from the first device onward. I'll match the fault address to the object bound there, and check whether it was unbound before the fault. If you'd rather attribute it another way, say so, and I'll run that instead.simonbronk commentedon Oct 15, 2026
@MarcZX100 here are both things you asked for.
1. Clean stack, public PRs only.
main44df216 plus #5907 (7ad8cb8), #5841 (63db31f), #5884 (15b0d03) and #5915 (2c8dda1). No local sample-count changes and no other local patches. #5884 conflicts withmain's serializer version 30, so locally I moved its new mesh field to version 31; the field is the same. Windows 11 26200, RTX 5070, NVIDIA 617.42, warm shader cache, host imports on (the default). Same path as before: menus, New Game, difficulty, controller layout. Same result on the first scene load:2. Attributing
0x4840000. I used a local diagnostic (not for merging). It enablesVK_EXT_device_address_binding_report(reportAddressBinding) and a debug-utils messenger forDEVICE_ADDRESS_BINDINGmessages, and logs every bind and unbind from device creation to the fault: 425,319 events over 264 s (VkDeviceMemory 77,923, VkBuffer 342,415, VkImage 4,981).[0x4840000, 0x4841000): no bind, no unbind, nothing anywhere in0x4600000..0x4b00000.0x43c2000(a 64 KiB VkDeviceMemory), and the next one above starts at0x6a90000.One caveat. NVIDIA reported no driver-internal bindings at all: every event has flags 0, and the instruction-pointer addresses in the fault report (
0x20f0dbd00and others) appear in no event. So0x4840000is either an address that was never valid, or driver-internal memory, such as a descriptor or shader heap, that this extension does not report on NVIDIA. WithAPS5_TEXTURE_CACHE_MIB=6000the fault moved to0x4c90000. So the address depends on the allocation layout, which points to a bad pointer or descriptor base computed by the shader, rather than a fixed driver heap.Next on my side: the faulting compute program has 2
ImageSampleRaw, 1ImageWriteand no buffer loads (from my earlier dump). I'll compare the descriptor words it is given, at the failing dispatch, against the views they should decode to.AI-assisted: Claude Code. The diagnostic patch is local; I can share it if useful.
simonbronk commentedon Oct 15, 2026
Correction and new data. The compute program I named earlier is not where the fault is. Its checkpoint had reached stage 0x2000 (bottom of pipe), so it had finished. The driver only places checkpoints before dispatches, so whatever ran after it had no marker.
I added a local diagnostic (not for merging). With
APS5_GPU_CHECKPOINTS, it wraps the device-proc lookup and gives every draw, dispatch, copy, fill, update, clear and begin-rendering a numberedvkCmdSetCheckpointNVmarker with a one-line description. Same stack as my previous comment (main44df216 + #5907 #5841 #5884 #5915), same path, first scene load:So the fault is in one of the two indexed draws between those markers:
drawIndexed 139710x1 base 206ordrawIndexed 2919x1 base 1700. Both belong to a depth-only pass. The next 1024x1024 depth-only pass had already started.On the address side:
APS5_TEXTURE_CACHE_MIB=6000it was 0x4c90000 (earlier).0x43c2000..0x6a90000. The binding report shows nothing is ever bound there, from device creation to the fault, in every run.robustImageAccess2(local,APS5_ROBUST_IMAGES) does not prevent it: same device loss, at 0x63f7000.Next: log the faulting draw's vertex and index inputs (V# bases and the BDA ranges they resolve to) to see which pointer has a zero high part.
AI-assisted: Claude Code. Both diagnostics are local.
simonbronk commentedon Oct 15, 2026
Negative result: #6522 (09f5749, a multisampled target's commands recorded on its own device, the #6512 race) does not change this. Same stack as above plus #6522, same path: the same device loss on the first scene load,
read invalid at 0x62a9000, again inside the never-bound range0x43c2000..0x6a90000.AI-assisted: Claude Code.
simonbronk commentedon Oct 15, 2026
Correction to my previous comment. "Every buffer and image the driver creates is bound above 4 GiB" is wrong. The binding log has about 105,000 events below 1 GiB: host imports at 0x13a20000 and 0x15a80000, pool slabs from 0x10160000 up, and so on. So low addresses are normal on this driver, and the truncation idea has no support from the address alone.
What still holds: the fault addresses fall in one hole,
0x43c2000..0x6a90000, which is never bound in any run. Below it there are sixteen 64 KiB VkDeviceMemory/VkBuffer pairs bound at startup (0x42c2000..0x43c2000). Above it the next object starts at0x6a90000. So a read running past the end of one of those low objects, or an offset applied to the wrong base, would land in this hole. I'm capturing the faulting draw's vertex and index bindings, push constants and descriptor buffers to check that.simonbronk commentedon Oct 15, 2026
The faulting draw, captured. Same stack, same path. Fault at
0x5201000, again inside the never-bound hole0x43c2000..0x6a90000.It is the same draw as in my previous run. The checkpoints put it between bottom-of-pipe for the draw before and top-of-pipe for this one:
GuestBufferMemory::addressRange, so in-place imports, mirrors and copies) for one whose device span touches the hole: none in the whole run.My descriptor-set capture for this draw is not reliable. It kept entries from earlier writes to recycled set handles, so I'm not reporting it.
Open question for someone who knows the NVIDIA side: does the driver keep something of its own in
0x43c2000..0x6a90000? The hole is stable across runs, and the binding report never shows anything there. If this pipeline's vertex input or its descriptors pointed at a driver-internal object, that could explain it. If useful, I can share the pipeline's shaders (the VS/PS guest programs) for this draw.AI-assisted: Claude Code. Diagnostics are local.
frankea commentedon Oct 16, 2026
Ada data point: the first-scene-load device loss reproduces on an RTX 4090, so it is not Blackwell-only.
Setup. Windows 11 (26200), RTX 4090 (NVIDIA 616.92,
VK_EXT_device_fault), AMD Ryzen 7 5800X, MinGW-w64 GCC 15.2.0 r7 (UCRT), Releaselibs. Tree:main5d9dcc4 + #5884 (a0347cf) + #5907 (7ad8cb8), nothing else local; #5915 no longer merges ontomain(State.cpp) and is not in.app.exerelinked bymain31cbb55's relinker with--windows --windows-fixed-base 0x400000000. Dump 01.000.001 (base, no patch,playgo-chunk.datpresent). Host imports on (default), cold shader cache for the scene.Path. Save-data creation, display and voice language, EULA, brightness (3), initial settings, accessibility, age, privacy notice, autosave notice, title screen, New Game, difficulty, Defensive layout. The first scene load then compiles about 12,600 shaders over roughly six minutes at 2 to 3 FPS, and dies on the GPU:
Two differences from the 5070 runs worth noting: here the fault is a write, not a read, and it lands at
0x5bab000, inside the same never-bound hole you measured (0x43c2000..0x6a90000). The last cache line before it is the scene compile still in progress (0 hits, 787 missesin the preceding 10 s), so on this box the loss comes while shaders are still being produced, not after a warm load. A second run with host imports on also lost the device, but earlier: during the front-end load after the autosave notice, before the title screen was seen (one settings save written, not the New Game one),write invalid at 0x47c0000on the recorder queue,vkQueueSubmit recorder: Vulkan result -4, warm cache (30,938 hits, 0 misses). So on this box the loss is tied to a load with host imports on, not to the first scene load alone; 2 of 2 runs, both fault addresses inside the hole.With
APS5_NO_HOST_IMPORT=1(1 of 1, warm cache): no device loss. The front end, title, New Game, difficulty and layout go through, the New Game save is written, and the first scene load then stops on a different refusal than your #6362, since #5915 is not in this tree:That is the
DB_SHADER_CONTROLmask check inState.cpp(nonzero(cx, 0x203, shaderControlMask(zFormat), ...)): 0x45 setsZ_EXPORT_ENABLE,STENCIL_OP_VAL_EXPORT_ENABLEandKILL_ENABLE, and one of them is outside the mask for that depth format. The card hasVK_EXT_shader_stencil_export, so this is not #4276's missing-extension abort, though it is the same stencil-export family. So the host-import correlation holds on Ada as well.Logs and the input notes are in the #5769 update: #5769 (comment) Not run: #5915 (conflicts), #6522, a second run with host imports on.
AI-assisted: yes (Claude Code).
simonbronk commentedon Oct 16, 2026
@frankea thanks, this is useful. It rules out a Blackwell-only cause, and the write at
0x5bab000and the recorder-queue loss at0x47c0000both land in the same never-bound hole, so the fault address keeps pointing at the same region on two architectures and on two queues.Both of your trees and all my runs since 2026-10-15 already contain #6060 (merged as 0afa6a6), so that change doesn't avoid the loss.
On the
APS5_NO_HOST_IMPORT=1path: my tree ismain4eb91ea + #5907 + #5884 + #5915 + #6557, and its first scene load does not log the0x203 = 0x00000045refusal. It stops later, at the native depth publication refusal tracked in #6570. I haven't checked which of #5915 and #6557 (or the order of the scene's draws) keeps it from reaching that check, so I can't say #5915 alone avoids it. #5915 still merges onto today'smain5d9dcc4 for me, with theState.cppresolution SandstromPL and I described on that PR.simonbronk commentedon Oct 16, 2026
Correction to my comment above, @frankea: my tree does reach the
0x203 = 0x00000045refusal. It reaches it later, because the depth publication stop (#6570) came first in the same load. With #6727 on top of my stack that stop is gone, and the first scene load now ends at the sameDB_SHADER_CONTROLrefusal you saw, withAPS5_NO_HOST_IMPORT=1. I haven't checked why your tree, without #5915, #6557 and #6727, reached it without the earlier stops.simonbronk commentedon Oct 16, 2026
Negative result for #6763, which copies draw vertex and index inputs on Windows instead of binding them in place from host imports.
Tree:
maineb901bc + #5907 + #5915 + #6557 + #6727 + #6762 + #6763, host imports on (default),APS5_GPU_CHECKPOINTS=1, cold shader cache, RTX 5070 (617.42), Windows 11 26200. Same path as before: menus, New Game, difficulty, layout. The New Game save is written, then the first scene load compiles shaders for about 2 minutes (about 21,000 by then) and the device is lost:0x5103000is again in the never-bound range0x43c2000..0x6a90000. So the in-place binding of draw inputs from host imports is not what reads there. #6763 is out of our stack for this issue.TheSovietWaffle commentedon Oct 17, 2026
Ampere data point: the first-scene-load device loss also reproduces on an RTX 3080, so that's three NVIDIA generations (Blackwell, Ada, Ampere).
Setup. Windows 10 Pro 22H2 (19045), RTX 3080 (NVIDIA 617.42), Ryzen 7 7800X3D, WinLibs GCC 15.2.0 r7, Release
libs. Tree:main452494439+ #7005 (SDL WGI off; this host faults inWindows.Gaming.Input.dllwithout it) + #6196. Dump 01.000.001, owned. Relinked with--windows --windows-fixed-base 0x400000000. Host imports on (default).Path. Setup screens, title screen, settings, New Game, layout, then the first scene load:
Recorder queue, a write, at
0x5a94000: also inside the never-bound range0x43c2000..0x6a90000. No checkpoints in this run (APS5_GPU_CHECKPOINTSunset).APS5_NO_HOST_IMPORT=1path, for comparison. With #5915 + #6557 + #6727 + #6762 on the same base, the load passes the device loss. On this GPU the next stop was the NVIDIA stencil export emulation refusal (stencil reference export emulation requires a proven set of at most 16 values, pixel shaders0x2112444f00and0x210687de00, #4276). With a change that replays all 256 eight-bit values for an unbounded export (#7006, closed for now by the open-PR limit), it goes on to the #6570 publication stop, as on your RTX 5070.Not run:
APS5_GPU_CHECKPOINTS=1, repeated runs for the fault address's stability.AI-assisted: yes (Claude Code).
cadenasynyster commentedon Oct 18, 2026
@MarcZX100 the clean-current-main run you asked for is now possible. Current main reaches the first scene load without any of the refusals that stopped it earlier. The title needed only one libc export to get there, which #7506 adds.
Tree: main b51c65d + #7506, no other PRs and no local changes. Windows 11 26200, RTX 5070 Ti (NVIDIA 617.42), WinLibs GCC 15.2.0 r7, Release. Dump 01.000.001, relinked with
--windows,APS5_PLAYGO_UNLISTED_CHUNKS=installed(the dump has no PlayGo metadata). Same path: menus, New Game, difficulty, layout, then the first story-mode load.Host imports on (default),
APS5_GPU_CHECKPOINTS=1. The device is lost early in the load:0x4840000 is the same address as most of @simonbronk's RTX 5070 runs, inside the never-bound range 0x43c2000..0x6a90000. An earlier run of the same tree without checkpoints also ended in
Vulkan result -4during this load (fault address not captured).APS5_NO_HOST_IMPORT=1(plusAPS5_GPU_CHECKPOINTS=1), same tree. No device loss. The load gets further (about a third of the progress bar) and stops on the refusal @frankea reported:So the host-import correlation holds on current main with no open PRs in the tree besides the libc export. One run each way.
Not run: #7446, repeated runs, the binding report.
AI-assisted: yes
simonbronk commentedon Oct 18, 2026
#7446 on PPSA27836, as listed under "Not run" above.
Tree:
upstream/main385ed71 + #6727 (rebased today, carries #6557) + #6762 + #7446 (3fd9a62). Windows 11 Pro 26200, RTX 5070 (NVIDIA 617.42), WinLibs GCC, Release. Host imports on (default),APS5_GPU_CHECKPOINTS=1,APS5_PROFILE_DRAW=1,APS5_BINDLESS_MATERIAL_SCAN=65536, cold shader cache. Same path: menus, New Game, difficulty, layout, then the first story-mode load. GPU tests on this tree:ctest -R "agc|shader|video_out"743/743 on NVIDIA.Result: no device loss in this run. The load stops on a different refusal, about 560 s after boot:
That is #4276's case, which #7006 targets. With #6762 in the tree, the
register 0x203 = 0x00000045refusal from the no-host-import run is not reached.#7446 did not act in this run. All 46
[labels]reports show0 packets redone for a queued label over the capture, 0 for captured memory that changed. The snapshot warning of frankea's run (0x2112c009d0) did not appear either. Two other mismatches did (0x210d800038+0x10and0x210dc00180+0x38, live region0x210d800000+0x800000).So I can't credit #7446 with the missing device loss. One run only: the stencil refusal may simply come before the point where the device was lost. Next step: #7006 on top of this tree, to see whether the load then completes or the
read invalid at 0x4840000comes back.AI-assisted: yes