Skip to content

fix(agc): support packed 16-bit storage images - #6218

Open
harry-z-kang wants to merge 3 commits into
boykopovar:mainfrom
harry-z-kang:codex/issue-6119-packed-storage
Open

harry-z-kang wants to merge 3 commits into
boykopovar:mainfrom
harry-z-kang:codex/issue-6119-packed-storage

Conversation

@harry-z-kang

@harry-z-kang harry-z-kang commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

What

Fixes #6119: guest format 133 (5_6_5_UNORM) fails when NVIDIA does not expose the packed format as a storage image. Formats 134 (5_5_5_1_UNORM) and 136 (4_4_4_4_UNORM) have the same capability gap.

Keep the packed image and native sampled/attachment formats, but write through a compatible R16_UINT storage view. Materialize storage descriptors with the original conversion format and pack stores into the original 16-bit guest layout, including half-precision inputs. Restrict each view's usage to the operations its format supports.

Packing reuses EmitFormatStoreComponent in SpirvBackend/src/SpirvMemory/SpirvFormatConvert.cpp and the existing packed texture channel mappings. Vulkan's format compatibility classes, extended image usage and normalized fixed-point conversion define the view compatibility and clamping/scaling. AMD/PS5 comparison of rounding ties and NaN handling remains unverified and is recorded with the existing packed-texture entry in docs/dev/debt/libSceAgcDriver.md.

The branch retains merged native format-43 repacking (#7271), converted 32-bit sampling (#5958), R8/RG8 sRGB copy handling (#6054), D16 SINT stores (#5899) and float-mode handling (#5943). No open PR is required.

Tested

Local validation on main 6ef5a1c4c and rebased PR head 4d26b03aa: Windows 11 (NT build 26300), NVIDIA GeForce RTX 5080, driver 617.42, WinLibs GCC 15.2.0, Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=OFF.

  • Rebuilt the six focused GPU test targets and their driver/runtime/shader dependencies on main and the PR. This pass did not repeat the full default build or libs build; both passed in the previous validation on base 9b34cba9e.
  • Ran the same nine focused cases on main's implementation and the PR with the identical regression harness. Both runs used ANYPS5_GPU=5080, ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1 and VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation.
  • Command: ctest --test-dir build -R '^agc_driver_(image_(converted_unorm|packed16_load|store_sint|sint8|repacked_float|packed16_storage_(133|134|136))|fmask_image_reads)$' -V --parallel 1.
  • Main passed the six existing cases and refused the three new packed-storage cases because their formats cannot be used as storage images. The PR passed 9/9 with zero skipped, including all three packed-storage cases; the final restored-PR run took 4.21 s.
  • Used Khronos validation 1.4.365 from the official Windows CI artifact, commit aea761f4d54b86682be4099c428dba27b6609940, supplied through a workspace-local VK_LAYER_PATH. Loader logs confirm insertion in every test. Neither log contains a missing-layer warning or any VUID- error: zero on main, zero on the PR.
  • The rebase applied cleanly. Both code/test commits have identical patches; the debt commit changes only its surrounding context. Conventions, whitespace and registration of all nine focused cases passed.

The wider suite was not repeated in this focused validation pass. Its previously reported image-table reuse failure was reproduced on the older main 60fb8078c.

Three new packed-format cases cover channel order, 2,048-texel bit-exact sampled-load/store round trips, full/partial masks, swizzles, 32-bit/half-precision stores, clamping and NaN/infinity inputs, sampling after repeated stores and packed guest-memory write-back.

Title and Linux validation reported by @snoozedDev, on the original main d92a8dad3 plus PR heads 8322164f1 and 628767b52: Linux kernel 7.2.5, GCC 16.2.1, RTX 3090, NVIDIA 610.57.04, Release with ANYPS5_ENABLE_SPIRV_TOOLS=ON.

The packed-storage additions are unchanged. No new title run on the rebased head, AMD/PS5 packed-store comparison or lavapipe run is claimed.

Checklist

@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

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.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6612 docs/dev/debt/libSceAgcDriver.md L185-186
PR 7085 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L1798-1799
PR 8563 core/shader/recompiler/SpirvBackend/src/SpirvBufferFormat.cpp L57, L112
PR 8564 core/shader/recompiler/SpirvBackend/src/SpirvBufferFormat.cpp L57, L112
PR 8658 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L1217-1218
PR 8898 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp L252-255, L1950
PR 8998 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L1973-1974
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp L277-278

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 907 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
PR 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 2434 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 4448 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
PR 4449 docs/dev/debt/libSceAgcDriver.md
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
PR 5372 docs/dev/debt/libSceAgcDriver.md
PR 5431 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6044 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6169 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6194 docs/dev/debt/libSceAgcDriver.md
PR 6197 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6202 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6223 docs/dev/debt/libSceAgcDriver.md
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6292 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6300 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6488 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
PR 6501 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6539 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6549 docs/dev/debt/libSceAgcDriver.md
PR 6615 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6788 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6804 docs/dev/debt/libSceAgcDriver.md
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6867 docs/dev/debt/libSceAgcDriver.md
PR 6868 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 6946 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6960 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 6971 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 7201 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7256 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7275 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7550 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7642 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 7684 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
PR 7689 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
PR 7705 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7910 docs/dev/debt/libSceAgcDriver.md
PR 8014 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8077 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaDescriptorFormat.hpp
core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp
PR 8126 core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8246 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8395 docs/dev/debt/libSceAgcDriver.md
PR 8484 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
PR 8527 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8552 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 8592 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 8625 core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
PR 8672 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9020 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvBufferFormat.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9335 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvBufferFormat.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9387 docs/dev/debt/libSceAgcDriver.md
PR 9508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/SpirvBackend/src/SpirvImageEmitter.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9533 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9671 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaDescriptorFormat.hpp
core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp
PR 9672 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaDescriptorFormat.hpp
core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9673 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaDescriptorFormat.hpp
core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9674 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaDescriptorFormat.hpp
core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9675 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaDescriptorFormat.hpp
core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9676 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/RdnaDecoder/include/RdnaDecoder/RdnaDescriptorFormat.hpp
core/shader/recompiler/RdnaDecoder/src/RdnaDescriptorFormat.cpp
docs/dev/debt/libSceAgcDriver.md
PR 9717 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9742 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/debt/libSceAgcDriver.md
PR 9748 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Optimization/src/ResourceMaterializer.cpp
core/shader/recompiler/SpirvBackend/src/SpirvBufferFormat.cpp
docs/dev/debt/libSceAgcDriver.md

@github-actions github-actions Bot added build shader core/shader docs agc libSceAgc* labels Oct 15, 2026
@harry-z-kang

Copy link
Copy Markdown
Contributor Author

Reviewed both PRs in the overlap report. Neither is a prerequisite, so Depends on: none remains accurate.

Using the overlap checker's normalized merge procedure, the updated branch merges cleanly with #5899 at 8c1193744ac5 and #5958 at 8338defe54dd, in either order, and with both combined. No fixed merge order is required for those heads. These are merge checks; combined runtime builds were not run.

The updated standalone branch passed the full build, libs, all 98 related tests on the RTX 5080, and conventions/whitespace checks. Cyberpunk remains untested. The PR description now records the dependency review; the scheduled overlap report can refresh against the new head.

This was referenced Oct 15, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 17, 2026
@github-actions github-actions Bot added fix error Closes an issue (Fixes #N) needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 17, 2026
@Dextroid17

Copy link
Copy Markdown
Contributor

Repeated @jotitadev's MoltenVK check on Linux, on the current head and plain main: 5d3a43196 merged onto main a62c724c3, lavapipe (llvmpipe, Mesa 26.2.4, LLVM 23.1.1), GCC 16.2.1, Release, ANYPS5_ENABLE_SPIRV_TOOLS=ON. lavapipe reports no optimal-tiling STORAGE_IMAGE for R5G6B5, A1R5G5B5 or B4G4R4A4_UNORM_PACK16 (it does for R16_UINT), so main refuses these three formats here, as on the RTX 3090 in #6119. By reading Texture.cpp, the PR sends them through the R16_UINT view on every device, not only on drivers without the bit.

  • agc_driver_image_packed16_storage_{133,134,136}, agc_driver_image_packed16_load and agc_driver_image_converted_unorm: 15/15 passed (3 repeats).
  • With the six non-test source files checked out from main (the PR's tests and CMakeLists.txt kept), the three packed-storage tests fail with the Cyberpunk 2077 (PPSA04029) on NVIDIA: guest storage texture format 4 (R5G6B5) cannot be used as a storage image #6119 error, guest storage texture format 4 cannot be used as a storage image for 133, and format 8 and 3 for 134 and 136. With the PR sources restored, all 5 pass again.
  • Full ctest: 1 failure out of 1,451 (65 skipped), agc_compute_pipeline_replay (replay did not export a pipeline cache header). It fails the same way with those six files from main, and the PR does not touch it.

AI-assisted: yes

@github-actions github-actions Bot added unblocks title Names a title ID on the Unblocks line needs rebase Conflicts with main, rebase needed labels Oct 18, 2026
@harry-z-kang
harry-z-kang force-pushed the codex/issue-6119-packed-storage branch from 5d3a431 to ca0ad2c Compare October 19, 2026 00:25
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@harry-z-kang
harry-z-kang force-pushed the codex/issue-6119-packed-storage branch from ca0ad2c to 10fbb16 Compare October 19, 2026 10:44
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 19, 2026
@harry-z-kang harry-z-kang reopened this Oct 19, 2026
@DavidAmsellem

Copy link
Copy Markdown
Contributor

First AMD-on-Linux (RADV) run of this PR. Merged onto main 8d5d4df96 (clean merge), built in full and compared with the same main, on the same machine.

AMD Radeon RX 7900 XT (RADV NAVI31, gfx1100), Mesa 25.2.8, Linux Mint 22.3 (Ubuntu 24.04 base), kernel 7.0.0-38, GCC 13.3, Release.

Full suite (ANYPS5_REQUIRE_VULKAN=1 ctest -j8) at b74c8abf4: 1641/1643 with this PR, against 1638/1640 on main. The two failures are the same on both, so this PR adds none: agc_driver_image_table_vouched_lookups (#7766, fixed by #7916) and agc_driver_guest_memory_lifetime (#7784).

The PR's three new ctest entries (agc_driver_image_packed16_storage_133, _134 and _136) all run and pass here; none is skipped. No other ctest entry is added, skipped or removed compared with main.

This checks correctness only; I did not measure performance.

GPUs tested: AMD Radeon RX 7900 XT (RADV NAVI31, gfx1100), Mesa 25.2.8, Linux Mint 22.3 / kernel 7.0.0-38

AI-assisted: yes

@klosixgaming-arch

klosixgaming-arch commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Cyberpunk 2077 PPSA03974 (v02.120.000, the same title as #6119 under another region's ID) on Windows 11 26200, RTX 5090, NVIDIA 617.42, WinLibs GCC 15.2.0.

AI-assisted: yes. Written with AI assistance and reviewed by me.

@harry-z-kang
harry-z-kang force-pushed the codex/issue-6119-packed-storage branch from 10fbb16 to 4adf405 Compare October 19, 2026 19:01
@thuanquang

Copy link
Copy Markdown
Contributor

Hardware data for the packed stores on RDNA 2: RX 6700 XT (gfx1031), raw ISA through the HIP runtime of AMD's Windows driver 32.0.21045.5002, so the conversion is the hardware's, not a Vulkan driver's.

Method: image_store v[4:7] ... dmask:0xf dim:SQ_RSRC_IMG_2D unorm glc through a linear 2D T# of each format (GFX10 codes), then image_load of the same texel through a 16_UINT T# over the same memory. First, one-channel stores of 1.0 locate each field. Then each channel gets 0, -0, 0x00000001, 0.25, 0.5, 0.5 ± 1 ulp, 1, 1 + 1 ulp, 2, -1, ±inf, ±NaN, a signalling NaN, 1/3 and 2/3, plus the f32 neighbours of every rounding midpoint (k + 0.5) / (2^n - 1) of its field. The same rows ran at IEEE 0 and 1, DX10_CLAMP 0 and 1, and with f32 denormals flushed and kept, and again with d16 half-precision data for the special values.

code fields, low bit first matches this PR's layout
133 5_6_5 R 0-4, G 5-10, B 11-15 yes
134 R 0-4, G 5-9, B 10-14, A bit 15 yes (5_5_5_1, W in bit 15)
135 R bit 0, G 1-5, B 6-10, A 11-15 not mapped by the PR
136 4_4_4_4 R 0-3, G 4-7, B 8-11, A 12-15 yes

Per field, in every mode, f32 and d16 alike:

  • The stored value is the exact product x * (2^n - 1) rounded to nearest, not fl32(x * scale) rounded: 429 of 429 rows for 133, 252 of 252 for 136, and the same for 134/135 except the tie below. Rounding fl32(x * scale) misses 32 to 78 rows per format.
  • NaN of either sign and signalling NaN store 0. -0, negative values and -inf store 0. +inf and values ≥ 1 store the field maximum. No bits outside the field are touched.
  • The one exact tie, 0.5 into a 1-bit field, stores 1 (the A bit of 134 and the R bit of 135, with f32 0x3f000000 and with d16 0x3800). This is 2 of 354 rows per format.

So NormStoreBits' round-half-to-even differs from the hardware on that tie: it stores 0, the GPU stores 1. With f32 or f16 inputs, a 1-bit field at exactly 0.5 is the only tie that can occur: a tie needs x = (2k + 1) / (2 (2^n - 1)), which is a binary fraction only for n = 1. So rounding exact ties up would only change that case. The test's StoreField uses std::nearbyint, which rounds half to even too, and StoreValues contains 0.5, so the test expects 0 for that W bit as well.

This is desktop RDNA 2, not a PS5. I haven't run the PR's Vulkan tests here.

@DavidSamir

Copy link
Copy Markdown
Contributor

First run on AMD's Windows Vulkan driver. It shows a different failure on main than on NVIDIA and lavapipe.

Setup: Windows 11 Pro 26200, AMD Radeon 680M (RDNA 2 iGPU, 1002:1681), AMD driver 32.0.21030.2001 (Vulkan 1.4.315), WinLibs GCC 15.2.0 r7, Release. main 1ff5c8ac5. This PR's head 4adf40588 merged into it cleanly. Khronos validation layer from SDK 1.4.363 (VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation), plus ANYPS5_REQUIRE_VULKAN=1 and ANYPS5_NO_SHADER_CACHE=1. The command is the PR's own nine-case ctest -R '^agc_driver_(image_(converted_unorm|packed16_load|store_sint|sint8|repacked_float|packed16_storage_(133|134|136))|fmask_image_reads)$' -V -j1. On the main side, main's implementation is built with only this PR's ImageConvertedUnorm.cpp and its test registration, so both sides run the same cases.

This driver reports optimal-tiling STORAGE_IMAGE for R5G6B5, B5G6R5, A1R5G5B5, R5G5B5A1, B4G4R4A4 and R4G4B4A4_UNORM_PACK16 (vulkaninfo --show-formats). So main does not refuse these formats here, as it does on the RTX 3090 and lavapipe. It uses them, and the result is wrong:

Case main this PR
agc_driver_image_packed16_storage_133 fails: packed image load/store changed guest bytes for format 133 passes
agc_driver_image_packed16_storage_134 fails: ... for format 134 passes
agc_driver_image_packed16_storage_136 fails: ... for format 136 passes
the six existing cases pass pass
total 6 of 9 9 of 9

No VUID- lines on either side, and no was not found but was requested by env var VK_INSTANCE_LAYERS.

On AMD's Windows driver, main doesn't stop on these formats the way it does on NVIDIA. It writes the wrong guest bytes without any error, so a title would render wrongly instead of stopping. This PR's route through the R16_UINT view gives the bit-exact round trip on this driver too.

AI-assisted: yes

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@harry-z-kang a useful data point from @DavidSamir: on AMD's Windows driver, which reports storage support for these packed 16-bit formats, main silently writes the wrong guest bytes for formats 133, 134 and 136, and this PR's R16_UINT route round-trips them exactly. Thanks @DavidSamir; that makes this a correctness fix on that driver, not just a refusal-to-support change. The gate on current main is next.

@harry-z-kang
harry-z-kang force-pushed the codex/issue-6119-packed-storage branch from 4adf405 to 4d26b03 Compare October 22, 2026 03:36

This branch has not been deployed

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

Labels

agc libSceAgc* build docs fix error Closes an issue (Fixes #N) shader core/shader unblocks title Names a title ID on the Unblocks line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cyberpunk 2077 (PPSA04029) on NVIDIA: guest storage texture format 4 (R5G6B5) cannot be used as a storage image

8 participants