Repository navigation
fix(shader): apply the V# DST_SEL to formatted buffer stores - #5172
nikowolf123 wants to merge 2 commits into
Conversation
|
Linux validation: configured a Release build with GCC 12.2 and built |
|
Measured the supplied probes for head The supplied UNORM probe matches both predicted rows exactly, in wave32 and wave64. The supplied UINT probe does not match the predicted three-cycle store/readback. Both wave sizes produce: Your predicted first two words are I isolated the 16_16_16_16_UINT store by removing the second descriptor and all its stores/loads, retaining only the first descriptor,
All repetitions agree in wave32 and wave64, including the second input row. Thus the isolated three-cycle result is the same as the full supplied probe; the identity/swap controls do not show the mismatch. Used exactly your This supports the measured UNORM swap examples, but does not support the predicted general inverse mapping for the supplied UINT cycle. I have not established a general replacement rule, run the PR's host implementation, or measured the other permutations/formats or GPU-selected descriptor path. Exact assembly, inputs and raw logs retained. |
|
Thanks, this is decisive. The rotation result means the store mapping for selector permutations that are not their own inverse isn't settled, and this PR's test pins the wrong value for that 16_16_16_16_UINT Y,Z,X,W row. I'll narrow the PR to what your measurement and the cited CTS cases settle (identity, the Z,Y,X,W swap, and the CTS 0/1 selector patterns). Other permutations will be refused, and your rotation result will go into the technical debt entry. I'll post here when it's pushed. |
|
One additional boundary for the narrowing: being its own inverse is not sufficient on gfx1036 for this UINT format. Keeping only identity and the measured Z,Y,X,W swap avoids these two additional counterexamples. I swept all 24 permutations of X/Y/Z/W in the isolated For input
The inverse-store prediction would instead give raw |
buffer_store_format_* and its D16 forms wrote memory component i from data VGPR i and ignored the V#'s DST_SEL, while loads through the same V# apply it. A store through a swizzled V# therefore did not read back what it stored: with 8_8_8_8_UNORM and DST_SEL Z,Y,X,W, storing (1.0, 0.75, 0.2, 0.25) wrote 0x4033bfff instead of 0x40ffbf33. The RDNA 2 ISA guide (section 8.1.4, table 31) takes DST_SEL from the resource for BUFFER_STORE_FORMAT_*. RADV builds texel-buffer V#s with the format's swizzle (Z,Y,X,W for B8G8R8A8, 0,0,0,X for A8) and ACO stores through them unchanged, so each format component takes the data slot whose selector names it, and slots that select 0 or 1 write nothing. StoreTexel applies the same rule to image stores. TBUFFER stores keep the identity selectors. These sources settle only a DST_SEL that names each format component once. A V# that names one twice or not at all, or holds a reserved selector, now throws when the binding plan is prepared, and a GPU-selected one records an invalid-descriptor fault and skips the store. ShaderInfo records which buffers have formatted stores (disk cache format 31, as the open boykopovar#4883 takes 30). Technical debt records that none of this is measured on hardware. agc_driver_buffer_store_format_dst_sel stores through Z,Y,X,W 8_8_8_8_UNORM (also D16 and store_format_x), Y,Z,X,W 16_16_16_16_UINT, 0,0,0,X 8_UINT and X,0,0,1 32_UINT V#s in wave32 and wave64, reads the first three back with buffer_load_format_xyzw, checks that three unsettled selector sets are refused, and compiles a store through a GPU-selected V#. On main it fails with red and blue swapped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
simonbbby measured this PR's hw-oracle probes on RDNA2 gfx1036. The identity and Z,Y,X,W on 16_16_16_16_UINT, Z,Y,X,W on 8_8_8_8_UNORM and 0,0,0,X on 8_UINT store as modelled, but a sweep of all 24 permutations on 16_16_16_16_UINT matches the model for only 12. Being its own inverse is not enough: Y,X,Z,W and X,W,Z,Y store (0x1234, 0x5678, 0x9abc, 0xdef0) as 56781234 9abcdef0 and 56789abc def01234, and the rotation Y,Z,X,W stores it as def01234 9abc5678. A formatted MUBUF store now accepts a DST_SEL only if it is the identity on the format's components, as on main, or one of the swizzles that are measured or conformance-tested for that format: Z,Y,X,W on 8_8_8_8_UNORM and 16_16_16_16_UINT, and 0,0,0,X on 8_UNORM and 8_UINT. 0,0,0,X on 8_UNORM is the V# RADV builds for the VK-GL-CTS without_format a8_unorm buffer store, which Mesa's CI passes on Navi 21. The b8g8r8a8 and a2r10g10b10 cases of that group store equal X and Z components, so they do not test Z,Y,X,W, and the other 8_8_8_8 and 2_10_10_10 formats stay refused. SettledFormattedStoreSwizzle holds this list for both the binding plan check and the GPU-selected path. Every other DST_SEL throws in DescriptorBindingBuilder::Prepare, and a GPU-selected V# with one records an invalid-descriptor fault and skips the store. The selectors of components a format lacks are ignored, as on main, so a reserved or repeated one there no longer throws. The test also stores through 16_16_16_16_UINT X,Y,Z,W and pins lane 0 of it and of Z,Y,X,W to the measured raw dwords. It checks the accepted set for every format and for all 24 permutations on 16_16_16_16_UINT, and expects V#s with Y,Z,X,W, Y,X,Z,W and X,W,Z,Y on 16_16_16_16_UINT, Z,Y,X,W on 16_16_16_16_FLOAT, 8_8_8_8_UINT and FORMAT 50, and 0,0,0,X on 32_UINT to throw; its target gets the recompiler's include directories for that. The technical debt entry records the measurements. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e2340c7 to
e5c8d15
Compare
|
Thanks for the full sweep, and for isolating the 16_16_16_16_UINT store first. The two self-inverse counterexamples show that my last comment drew the line in the wrong place: being its own inverse does not make a permutation safe. e5c8d15 limits the store mapping to what your runs show, plus one VK-GL-CTS case. A formatted MUBUF store now accepts only:
Everything else is refused. On the host path the V# throws in The PR body also cited the CTS The test checks that the accepted set holds exactly X,Y,Z,W and Z,Y,X,W of the 24 permutations on 16_16_16_16_UINT, and that V#s with your Y,Z,X,W, Y,X,Z,W and X,W,Z,Y throw when the binding plan is prepared. It also stores through X,Y,Z,W and Z,Y,X,W and pins lane 0 to your raw dwords ( I also rebased onto AI-assisted: written with Claude Code; I checked the change and ran the tests described in the PR body. |
|
Verified the narrowed head
I also measured the remaining 8_UNORM Y/W ambiguity directly on gfx1036. With word3
Thus these distinct Y/W inputs select W on this hardware. Two rows repeated to 64 lanes, three runs in wave32 and three in wave64, all agreeing; same explicit FP controls as my earlier probes. Exact assembly/inputs/raw logs retained. The CTest legs pin the respective ICD and set |
|
Thank you, that closes the last open point. Your 8_UNORM rows ( |
|
Closing: no title is known to reach this. With the queue at 700+ open PRs, please hold off on new PRs that don't name a title needing the change until it's down. If a title stops on this on current main, reopen with the title ID and the log line. |
* Metal semantics: run upstream image execution tests through the Metal driver The existing semantics shim binds only guest buffers. A second shim (tests/metal_semantics/driver_shim) runs the upstream execution tests that bind images, samplers and color targets through the native Metal driver: dispatches bind their descriptors with MetalShaderResources and draws go through MetalDraw::DrawSynchronously, as in a title. The tests' host arrays are the guest memory; the device borrows every range the shader's buffer and image descriptors and the color targets name. ImagePlaneAddressOnLine and ImageVolumeAddressOnPlane (already on main) now run on Metal and pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): capture image descriptors read from constant buffers at uniform offsets Removes the tracker check that refused a T# whose dwords come from a ReadConstBuffer, so a T# loaded with s_buffer_load from a table record that user data selects is captured like any other runtime descriptor. Metal: tests/metal_semantics/ImageTableRecord.cpp runs the upstream program through the Metal driver (MetalShaderResources image binding) and checks that the record user data selects is the texture sampled. It fails on main with the removed "is not a valid runtime value" error. Ported from upstream PR boykopovar#5188 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): accept TYPE=0 images during materialization A T# with TYPE=0 is null on AMD hardware even when its base and other words are nonzero; the materializer now accepts it as a null image instead of refusing it as invalid (reserved TYPE=1 is still refused). Upstream's frontend test is ported to tests/ShaderMemory.cpp. Metal: the Metal image binding already treats TYPE=0 as null (IsNullTextureResource), so such an image binds no texture. The Metal ImageTableRecord test now also samples a TYPE=0 record with a nonzero base and reads zero; on main it fails with "runtime image descriptor is invalid". Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5473 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): read 1D T#s through 3D image_sample and image_load accesses A DIM 3D image_sample_lz, plain image_sample or mip-less image_load whose T# is 1D gets a runtime image mode that binds the 1D texture: the sample reads the texel u selects, and the load reads the x texel when z is 0 and zero otherwise, as measured on RDNA1. Other 3D accesses of such an image still throw. ImageResource gains flatVolumeLineCompatible, so the shader disk cache FormatVersion goes from 35 to 36. This is the only bump in this series: the later image-mode fields reuse it. Metal: the 1D mode binds through the existing Image1D shape (a 2D texture of height 1) with no new view. Upstream's ImageVolumeAddressOnLine execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_imagevolumeaddressonline). It fails without the materializer hunk ("incompatible with the static runtime image interface"). Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5375 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): sample single-level volumes through biased 2D accesses A pixel-stage, direct, plain 32-bit image_sample_b with DIM 2D whose T# is a one-slice, single-level 3D image gets the 3D runtime image mode: the sample supplies a zero third coordinate and keeps the bias, as measured on RDNA2. The binding requires a normalized point sampler and the descriptor one slice and mip zero; other cases throw. ImageResource gains singleMipPlaneBiasCompatible; it is encoded by the shader disk cache under the FormatVersion 36 bump of this series (upstream's own bump to 31 is not taken). Metal: the 3D mode binds the volume as the Image3D shape it already has, with no new view. Upstream's ImagePlaneBiasOnSingleLevelVolume execution test (a pixel draw) runs unchanged through MetalDraw (anyps5_metal_driver_semantics_imageplanebiasonsinglelevelvolume). It fails without the tracker hunk ("incompatible with the static runtime image interface"). Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5461 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): decode forced degamma on biased RGBA8_UINT samples A direct RGBA8_UINT image sampled only by plain biased pixel accesses (the one-slice volume case of boykopovar#5461) through samplers that all set FORCE_DEGAMMA is materialized as RGBA8_SRGB, which returns the same decoded floats as the hardware. Mixed sampler states, indirect images, other accesses and formats still throw. Metal: MetalSampler refused every FORCE_DEGAMMA S#, so this (and the existing sRGB case of ImageSampleForceDegamma) could not bind. Metal now does what the Vulkan driver does: MetalShaderResources::Bindings creates the sampler with forceDegammaPaired and refuses a sampled image of a non-sRGB format paired with a forcing sampler (the same message as RequireDegammaFormat). The rewritten descriptor binds through the existing sRGB pixel-format view. Upstream's extended ImagePlaneBiasOnSingleLevelVolume and the existing ImageSampleForceDegamma tests now pass on Metal; both failed with "forces sRGB decoding which is not implemented". Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5472 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): read cube T#s through DIM 2D image_sample and image_load as face 0 A DIM 2D image_sample_lz, plain image_sample, image_sample_l or mip-less image_load whose T# is a cube gets the cube runtime image mode and reads the T#'s BASE_ARRAY face with face coordinate 0, as measured on RDNA1. Other DIM 2D accesses through a cube T# still throw. ImageResource gains cubeFaceCompatible; encoded under the series' FormatVersion 36 bump. Metal: a cube T# is already a 2D-array texture of faces and the cube mode binds the Image2DArray shape, so no new view is needed. Upstream's ImagePlaneAddressOnCube execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_imageplaneaddressoncube) and fails without the materializer hunk. Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5509 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): compare through 2D image_sample_c on 1D T#s The flat-line (2D access through a 1D T#) compatibility now ignores the compare flag, so image_sample_c and image_sample_c_lz with DIM 2D on a 1D T# take the 1D mode like their non-compare forms. Metal: the 1D mode binds through the existing Image1D shape (a 2D texture of height 1), with no new view. Upstream's ImagePlaneCompareOnLine execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_imageplanecompareonline) and fails without the tracker hunk. The debt note in docs/dev/TechnicalDebt.md is updated as upstream's. Ported from upstream PR boykopovar#5456 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj * fix(shader): apply the V# DST_SEL to formatted buffer stores buffer_store_format_* (D16 included) wrote memory component i from data VGPR i whatever the V#'s DST_SEL. A formatted store now writes each format component from the slot its selector names, only for the DST_SELs measured on RDNA2 or covered by conformance tests: the identity, Z,Y,X,W on 8_8_8_8_UNORM and 16_16_16_16_UINT, and 0,0,0,X on 8_UNORM and 8_UINT. Every other DST_SEL on a formatted store is refused: a host V# throws in DescriptorBindingBuilder::Prepare, and a GPU-selected V# records an invalid-descriptor BDA fault and skips the store. BufferResource gains formattedWritten; encoded under the series' FormatVersion 36 bump. Metal: the store is lowered in the shared SPIR-V (SpirvRuntimeBuffer), so no Metal binding change. Upstream's BufferStoreFormatDstSel execution test runs unchanged through the Metal driver (anyps5_metal_driver_semantics_bufferstoreformatdstsel). Without the SpirvRuntimeBuffer hunk it fails (Z,Y,X,W on 8_8_8_8_UNORM writes 0x4033bfff, expected 0x40ffbf33). Debt note added to docs/dev/TechnicalDebt.md. Ported from upstream PR boykopovar#5172 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DgW4n3qYgi5jAAohEmXRQj --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
What
buffer_store_format_*and its D16 forms ignored the V#'s DST_SEL. Memory component i was always written from data VGPR i. Loads through the same V# do apply DST_SEL, so a store through a swizzled V# did not read back what it stored. With 8_8_8_8_UNORM and DST_SEL Z,Y,X,W (word30x31038f2e, a B8G8R8A8 buffer), storing (1.0, 0.75, 0.2, 0.25) wrote0x4033bfffinstead of0x40ffbf33: red and blue were swapped. This affects any shader that writes a formatted buffer through a V# whose DST_SEL reorders the channels (B8G8R8A8, for example); no title is known to hit it.A formatted store now writes each format component from the data slot whose selector names it, but only for the DST_SELs that are measured or covered by conformance tests for that format. Hardware measurements show that this rule does not hold for every permutation, so every other DST_SEL is refused instead of guessed.
Accepted:
main's behaviour, unchanged; the selectors of components the format does not have are ignored, as onmain.Refused: every other DST_SEL, including the other 22 permutations on 16_16_16_16_UINT, Z,Y,X,W on any other format and 0,0,0,X on any other one-component format. On the host path the V# throws in
DescriptorBindingBuilder::Prepare; a GPU-selected V# records an invalid-descriptor BDA fault and skips the store.Measured by simonbbby on RDNA2 gfx1036 (Ryzen 9 9950X iGPU) with the project's HSA hardware oracle, wave32 and wave64, using this PR's probes:
_xyzwand_d16_xyzw) stores and reads back as modelled. In an isolated 16_16_16_16_UINT store of (0x1234, 0x5678, 0x9abc, 0xdef0), X,Y,Z,W writes56781234 def09abcand Z,Y,X,W writes56789abc def01234, as modelled, and both read back the input. The rotation Y,Z,X,W writesdef01234 9abc5678, where this PR first predicted12349abc def05678. The 8_UINT 0,0,0,X words of the full UINT probe (_xyzw, then_xto the next byte) equal the predictedaaaa00ffandaaaa0044;mainwould giveaaaaffffandaaaa1111.56781234 9abcdef0and X,W,Z,Y writes56789abc def01234, where the model gives12345678 def09abcanddef01234 56789abc.Sources for 0,0,0,X on 8_UNORM:
buffer_store_format_*through that V# as it is (aco_select_nir_intrinsics.cpp#L1873-L1971). It drops trailing undefined or zero components, and before GFX12 the components it leaves out "receive zero" (L1896-L1918).dEQP-VK.image.store.without_format.buffer.a8_unormstores four position-dependent components (vktImageLoadStoreTests.cpp#L692-L694) without a declared format, so the store keeps all four (nir_opt_shrink_stores.c#L34-L67), and compares the buffer with the format's layout (#L967-L984, #L3675-L3732). It runs only if the format supports storage texel buffers, unformatted stores and a 1D storage image (#L582-L655), which RADV gives A8_UNORM (radv_formats.c#L111-L218, #L374-L389). It is in the vk-default mustpass (store.txt#L2445). Mesa's CI runs the vk-main caselist on Navi 21 (gfx1030) inradv-navi21-vkcts(gitlab-ci.yml#L250-L259, deqp-radv.toml#L1-L7), andradv-navi21-fails.txtlists nodEQP-VK.image.storetest. The buffer is 64 texels wide and one high (#L3041), so at texel x the case stores x, 63 - x, x and 63 - x, scaled alike (#L692-L694, reference #L377-L378). It passes only if the one component comes from the Y or the W slot; the 8_UINT words in simonbbby's first comment show W.The
b8g8r8a8_{unorm,snorm,uint,sint}anda2r10g10b10_{unorm,uint}_pack32cases of the same group store equal X and Z components at every texel for the same reason, so they pass whether or not the store swaps X and Z and do not test Z,Y,X,W. Z,Y,X,W on 8_8_8_8 SNORM, UINT and SINT, on the 2_10_10_10 formats and on every other four-component format, and 0,0,0,X on other one-component formats, are neither measured nor tested, and the sweep shows that the store does not apply DST_SEL as a general permutation, so they stay refused.Changes:
SpirvRuntimeBuffer.cpp,formatted(): a MUBUF formatted store writes each format component from the data slot whose DST_SEL names it, or 0 if no slot the instruction provides names it. TBUFFER stores keep the identity selectors.SettledFormattedStoreSwizzleandIsSettledFormattedStoreDstSel(SpirvBufferFormat.cpp) hold the accepted set, used byDescriptorBindingBuilder::Preparefor a present V# and by the GPU-selected store for each format.ResourceTrackerrecords which buffers have formatted stores (BufferResource::formattedWritten, disk cache format 30, sincemaintook 29 in fix(shader): read the ancillary render target index from Layer when the draw exports it #5097).docs/dev/debt/shader.mdrecords the accepted set, both measurements, why the B8G8R8A8 and A2R10G10B10 cases do not count, and what is not measured: narrower stores (_x,_xy,_xyz) through Z,Y,X,W and through 0,0,0,X on 8_UNORM, D16 stores through Z,Y,X,W on 16_16_16_16_UINT, buffer stores with a selector naming a channel the format lacks (feat(agc): implement sint storage images through uint views #944 measured gfx1035 writing channel 1 of a two-channel image from the W slot), and gfx1013.agc_driver_buffer_store_format_dst_sel(tests/execution/BufferStoreFormatDstSel.cpp; its target gets the recompiler's include directories, like other execution tests that call recompiler functions), wave32 and wave64, 64 lanes, every value checked:buffer_store_format_xyzw,_d16_xyzwand_xthrough 8_8_8_8_UNORM Z,Y,X,W;_xyzwthrough 16_16_16_16_UINT Z,Y,X,W and X,Y,Z,W, with lane 0 pinned to the gfx1036 raw dwords;_xyzwand_xthrough 8_UINT 0,0,0,X;_xyzwthrough 32_UINT X,0,0,1.buffer_load_format_xyzwreads the first three back and must return the stored data.IsSettledFormattedStoreDstSelmust accept exactly X,Y,Z,W and Z,Y,X,W of the 24 permutations on 16_16_16_16_UINT, and for each of the 77 formats: the identity always, Z,Y,X,W and 0,0,0,X only on the listed formats, and X,0,0,1 and X,0,0 with the reserved selector 2 only on one-component formats. X,X,Z,W and Z,Y,X,1 on 8_8_8_8_UNORM and 1,0,0,X on 32_UINT must be refused.Tested
Rebased onto
main0214069 (no conflicts; #5097 had taken disk cache format 29, so this PR uses 31, as the open #4883 takes 30; and #4250 changed sub-dword buffer stores inSpirvRuntimeBuffer.cpp, so all results below are on the rebased branch).Ubuntu 26.04 under WSL2, GCC 15.2.0, configured like CI (Release, Ninja,
-DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON, ccache), lavapipe from Mesa 26.0.8 withVK_ICD_FILENAMES=<lvp_icd.json> ANYPS5_REQUIRE_VULKAN=1 GALLIUM_OVERRIDE_CPU_CAPS=avx,ctest -j4. The machine was heavily loaded by other builds (load average around 110), so the times are long:ctest -R '^agc_driver_buffer_store_format_dst_sel$'passes 3 of 3 runs in 32 to 39 s.mainwith the new test added (without theIsSettledFormattedStoreDstSelchecks, which need this PR's function), it fails 3 of 3:wave32 lane 0 buffer_store_format_xyzw 8_8_8_8_UNORM Z,Y,X,W is 0x4033bfff, expected 0x40ffbf33.a store through DST_SEL Y,Z,X,W on 16_16_16_16_UINT compiled.ctest -R 'agc_shader|agc_driver|shader|recompiler': onmain, 354 passed and 36 skipped of 390; with this PR, 355 passed and 36 skipped of 391.ctest: onmain, 1033 passed, 43 skipped and 1 timed out of 1077; with this PR, 1034 passed, 43 skipped and 1 timed out of 1078. Compared test by test, the only difference is the new test. The timeout isguest_pthread_start(20 s limit) in both runs; alone it passes 3 of 3 on this branch in 17 to 19 s. The skips are the existing lavapipe skips.IsSettledFormattedStoreDstSelwith a transcription of the GPU-selected check for every DST_SEL value (4096) on each of the 77 formats, with three patterns in the other word3 bits: they agree on all 946176 words and accept exactly the list above, and every accepted word stores asmaindoes or as the listed swizzle, for_xto_xyzw.main'stools/check_conventions.py --base origin/mainpasses, with--titleand--body.Native Windows 11, WinLibs GCC 15.2.0, NVIDIA GeForce RTX 5080 (driver 616.92), this branch:
agc_driver_buffer_store_format_dst_selandagc_shader_disk_cachepass 3 of 3 runs (the new test in 1.6 to 1.9 s), andctest -R 'agc_shader|agc_driver|shader|recompiler'passes 389 of 390 with 1 skipped (agc_driver_stencil_ref_export).A store through a GPU-selected formatted V# did not finish within 150 s on lavapipe, on
mainas well and also with 32_32_32_32_UINT, so that path is compiled and validated by SPIRV-Tools here but not run. Its selector check is emitted in each of the 77 format cases of the GPU-selected store helper.AMD hardware: the RDNA2 gfx1036 results above are simonbbby's measurements, linked in What; I have no AMD GPU. The PS5's gfx1013 is not measured.
Verified on hardware by @simonbbby on this head (e5c8d15) (comment):
agc_driver_buffer_store_format_dst_sel,agc_shader_memoryandagc_shader_disk_cachepass 3 of 3 runs each on gfx1036 (RADV, Mesa 25.2.8) and on an RTX 3090 (NVIDIA 595.99.02). With onlyDescriptorBindingBuilder.cpprestored from the parent, the test fails witha store through DST_SEL Y,Z,X,W on 16_16_16_16_UINT compiled.buffer_store_format_xyzwthrough 8_UNORM with 0,0,0,X stores the W component (rawaaaaaa40for W = 0.25 andaaaaaafffor W = 1, Y differing), which settles the Y-or-W case the CTS left open.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)🤖 Generated with Claude Code