Repository navigation
feat(recompiler): implement 64-bit image atomics - #896
Conversation
|
A note on overlaps with open pull requests, for whichever lands second:
|
74be865 to
3e02fc7
Compare
image_atomic_* with a two-dword data mask (four for cmpswap) is the 64-bit form of an integer image atomic. The decoder rejected it with "invalid MIMG data mask". PPSA14632 (Unreal Engine) uses image_atomic_umax this way in a compute shader during its first frames. Swap, add, sub, signed and unsigned min/max, and, or, xor and cmpswap now decode with 64-bit data and translate to new ImageAtomic*64 IR opcodes. An image updated by them gets its own descriptor binding range, declared as an R64ui image of 64-bit integers, and the module uses Int64ImageEXT from SPV_EXT_shader_image_int64. The driver enables shaderImageInt64Atomics when the device offers it and binds an R64_UINT view of the 32_32 UINT, SINT or FLOAT surface. Without the feature, recompiling such a shader throws. 64-bit inc, dec and the float atomics still throw, as does any other access in the same shader to an image it updates with 64-bit atomics. The new agc_driver_image_atomics64 test runs every operation on 32_32 UINT, SINT and FLOAT surfaces and checks the returned and stored values against edge cases across the dword boundary. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Measured all 11 operations (cmpswap with equal and different comparator) on 32_32 UINT/SINT/FLOAT surfaces on RDNA2 hardware (gfx1035) with carry/sign edge rows plus random rows: returned and stored values match this PR's model bit for bit (5760 cells, 0 mismatches). The test passes on RADV and on CI's lavapipe, and fails without the change. Rebased on main (only conflict: the |
3e02fc7 to
9df5929
Compare
A pixel or vertex shader with a 64-bit image atomic declares Int64Atomics,
Int64ImageEXT and SPV_EXT_shader_image_int64, which graphics shader
validation rejected ("SPIR-V requires unsupported device capability"),
so the draw was dropped. Compute dispatches are not validated this way.
The device records whether it enabled shaderImageInt64Atomics
(imageInt64Atomics in the device state and the graphics Context), and
ValidateShaders accepts the two capabilities and the extension when it
did.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
|
A second commit makes draws work too. In PPSA14632, a pixel shader with a 64-bit image atomic was rejected by graphics shader validation ( #1074 does the same for 64-bit buffer atomics ( |
|
Re-checked the second commit: graphics validation now accepts |
What
Implement 64-bit integer image atomics.
image_atomic_*with a two-dword data mask (0x3, or0xffor cmpswap) is the 64-bit form of an integer image atomic, and the decoder rejected it withinvalid MIMG data mask.PPSA14632 (LEGO Horizon Adventures, Unreal Engine) updates a 32_32 surface with six 64-bit
image_atomic_umaxin a compute shader during its first frames, and stops there onmain.dataBits = 64.ImageAtomic*64opcodes take and returnU64, read from and written to register pairs as the 64-bit buffer atomics are.atomic64and gets its own descriptor binding range (five bindings after the 32-bit atomic ones), declared as anR64uiimage of 64-bit integers. The descriptor must be 32_32 UINT, SINT or FLOAT. The flag reaches the driver asDescriptorBinding::imageAtomic64and is stored in the shader disk cache.OpImageTexelPointerto a 64-bit texel and the 64-bit atomic opcodes, withInt64,Int64Atomics,Int64ImageEXTandSPV_EXT_shader_image_int64. When the target does not listInt64ImageEXT, recompiling throws64-bit image atomics need VK_EXT_shader_image_atomic_int64.VulkanDeviceenablesshaderImageInt64Atomicswhen the device offers it and advertisesInt64ImageEXT.StorageTexture::Atomic64Viewbinds anR64_UINTview of the surface; storage images are already created withMUTABLE_FORMATandEXTENDED_USAGE, andR64_UINTis in the 64-bit compatibility class ofR32G32_*.Not covered, and listed in TechnicalDebt: 64-bit
image_atomic_inc/decand the float atomics still throw, as does any other access in the same shader to an image it updates with 64-bit atomics.Tested
shaderImageInt64Atomics = true).agc_driver_image_atomics64: each of the 11 operations on 32_32 UINT, SINT and FLOAT surfaces, checking the returned and stored values for every thread against edge cases across the dword boundary (carry, borrow, sign bit, high word deciding min/max). Turning 64-bit umax into umin in the emitter makes it fail. Full ctest: 360/360.OpAtomicUMax %ulongon anR64uiimage,spirv-valaccepts it, and the title runs on to an unrelatedsceAgcCbBranch: null or misaligned address 0x0.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)🤖 Generated with Claude Code