Skip to content

perf(shader): keep native f16 conversion NaN results when a startup probe matches RDNA - #11351

Merged
adriadam10 merged 5 commits into
boykopovar:mainfrom
tibzejoker:perf/f16-convert-probe
Nov 6, 2026
Merged

adriadam10 merged 5 commits into
boykopovar:mainfrom
tibzejoker:perf/f16-convert-probe

Conversation

@tibzejoker

@tibzejoker tibzejoker commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

What

Step 3 of #11183. Native f16 conversions keep their own NaN result when a startup probe shows it is already RDNA's.

On a device with Float16, RoundingModeRTE 16 and DenormPreserve 16, v_cvt_f16_f32 and friends are one OpFConvert, and v_cvt_f32_f16 reads are one UnpackHalf2x16 (#1252, #7698). Rounding, denormals and infinities are fixed by those execution modes; the NaN is not (Vulkan lets the driver return any NaN). So every conversion rebuilds RDNA's NaN with integer ops:

  • f32 -> f16: sign of the input, quiet bit set, top 10 payload bits (0x7e00 | payload >> 13): 11 extra instructions, about 52 words;
  • f16 -> f32: sign and payload kept, no quieting: 6 extra instructions, about 28 words.

ProbeFloat16Conversions (Execution/src/Float16ConversionProbe.cpp) runs when the device is created, like ProbeFloat32FlushToZero (#6503). It compiles small RDNA programs twice, with the rebuilt NaN (today's code) and with the native result, dispatches both and compares every dword:

  • v_cvt_f32_f16 over all 65,536 halves (garbage in the upper 16 bits);
  • v_cvt_f16_f32, v_cvt_pkrtz_f16_f32 and v_cvt_f16_f32 followed by v_cvt_f32_f16, over 18,336 f32 values: every top-10 payload of quiet and signalling NaNs of both signs (with 4 low-bit patterns), every exponent with 16 mantissa patterns (ties, sticky bits, overflow to infinity, the largest finite values), and ties at every shift of the f16 denormal range;
  • each under no float mode, every denormal kept, every denormal flushed with IEEE_MODE, and a directed f16 rounding mode with FP16_OVFL;
  • inputs are read from a buffer, so the driver cannot constant-fold them.

SpirvTarget::float16WidenNans / float16NarrowNans are set per direction only when every result matches; the emitter then returns the OpFConvert / UnpackHalf2x16 result directly. Both fields are in the recompile cache key. The probe runs on each device creation, so a driver update is probed again. APS5_NO_NATIVE_F16_NANS skips it. The round trip and the toward-zero programs are there because they put OpFConvert next to OpFConvert. That caught a real problem (found by @Lander0606 on RADV, and the same on NVIDIA): v_cvt_pkrtz_f16_f32 corrects the nearest-even half when it widens back above the input, and without the NaN rebuild between them the drivers folded the f32 -> f16 -> f32 pair, so 140,763 of 280,480 inputs came out nearest-even. NoContraction on the widening fixed RADV but not NVIDIA; with float16NarrowNans the half is now widened with integer operations (shift, exact multiply for denormals), which leaves nothing to fold, and without it the module is main's (the NaN rebuild still separates the two conversions): 0 differences on both GPUs here, and --verify-spirv requires that this program has no widening OpFConvert.

Both fields are saved in recompile requests (serializer format 54, after main's shader image minimum LOD flag of format 53; 50 stays rejected as on main; older requests read them as false, round trips of the four combinations in request_serializer), so a dumped request replays with the conversions of the device that wrote it. Landing order with #11483: both append to the request format; this PR lands first with 50 and #11483 then takes 51 (agreed there). agc_shader_replay --f16-widen-nans / --f16-narrow-nans force them on as explicit overrides, so the sizes below can be reproduced.

Probe results

GPU f16 -> f32 f32 -> f16
RTX 4090 (NVIDIA 616.92) emulated: every NaN becomes 0x7fffffff (2,046 of 65,536 halves per mode) emulated: every NaN becomes 0x7fff (9,233 of 280,480 in the test)
UHD 770 (Intel 101.6129) emulated: signalling NaNs come back quieted (0x7c01 -> 0x7fc02000, RDNA gives 0x7f802000), 1,022 halves; quiet NaNs, denormals and the rest match native: 0 of 220,032 probe results differ, 0 of 280,480 in the test for each of the three programs

| Radeon 860M (RADV, Mesa 26.2.5, run by @Lander0606) | not probed: float16DenormPreserve needs denormBehaviorIndependence ALL and RADV reports 32_BIT_ONLY | native: 0 of 220,032 probe results differ, 0 of 280,480 in the test for each of the three programs |

So on the RTX 4090 nothing changes, and the f32 -> f16 direction changes on Intel and RADV.

Tested

Windows 11 Pro, MinGW-w64 GCC 15.2.0 (WinLibs r7), Ninja, Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON (spirv-val on every module), this head 6740167447 on main 9ab6a281ea.

  • New test agc_driver_float16_conversion_probe (tests/execution/Float16ConversionProbe.cpp):

    • agc_driver_float16_conversion_probe_spirv (--verify-spirv, no device needed): with each field set, the conversion loses exactly its NaN select and keeps one OpFConvert;
    • agc_driver_float16_conversion_probe, on the device: the emulated results are checked against a CPU model of RDNA (v_cvt_f32_f16 for all halves, v_cvt_f16_f32 and the round trip for the probe set plus 2^18 random f32 values), the native results are compared with them per class (quiet NaN, signalling NaN, not NaN), and the test fails if the device chose the native path for a direction where any result differs. It does not exist on main.
  • Focused tests, main 9ab6a281ea (this head's base) vs this PR (6740167447), ctest -R "(^agc.*(f16|float16|f64|convert|pack|interpolation|denorm)|request_serializer|shader_memory|agc_float16_conversion)" -E "^agc_driver_bda_device$" -V, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation with VK_LOADER_DEBUG=layer (84 / 85 layer insertions, no was not found line), ANYPS5_NO_SHADER_CACHE=1, ANYPS5_REQUIRE_VULKAN=1:

    GPU main this PR VUID- lines (main / PR) conversions used by the tests
    RTX 4090 (NVIDIA 616.92) 95/95 97/97 0 / 0 both: NaN rebuilt in both directions
    UHD 770 (Intel) 95/95 97/97 0 / 0 main: rebuilt; PR: native f32 -> f16

    Both sides pass on both GPUs. The f64 tests skip there (no Float64). Probe lines: RTX 4090 f16->f32 emulated (8184 of 262144), f32->f16 emulated (98484 of 220032); UHD 770 f16->f32 emulated (4088), f32->f16 native (0 of 220032).

  • RADV, Radeon 860M (Mesa 26.2.5, Fedora 44, GCC 13.3), by @Lander0606 on f2300fd2d2 (the toward-zero fix, before it was made conditional on float16NarrowNans) against its base main 4e43321bd6, ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1, validation layer 1.4.341, three runs each:

    main this PR
    focused set, with and without the layer 59/59 61/61
    lavapipe, with the layer 59 pass, 2 skipped 61 pass, 2 skipped
    full ^agc (-j8) 1029 of 1030 1031 of 1032

    Every device creation logs f32 to f16 NaN results: native (0 of 220032 probe results differ); the three programs of the probe test match on all 280,480 inputs. No VUID- line, 53 / 54 layer insertions. The only full-suite failure is agc_driver_tessellation (Mesa 26.2.5 crash) on both trees. Probe time 89-115 ms. The rerun on 6e17eb4b75 is offered and will be posted in the comments; the change since f2300fd2d2 only affects devices without float16NarrowNans.

  • Serializer and probe tests on this head: request_serializer, agc_shader_memory (both updated for format 54), agc_driver_float16_conversion_probe and _spirv pass.

  • Full agc suite on the RTX 4090, on 9f386f3a29 before the rebase (ctest -R "^agc" -E "^agc_driver_bda_device$" -j12): 1061 of 1063 passed; the 2 failures (agc_host_import_cut_lifetime, agc_driver_depth_plane_partial_store) also fail on main. Every test that opens a device now runs the probe.

  • Size, Grand Theft Auto V compute shaders (the requests from perf(shader): compute v_pk_fma_f16 and v_pk_fmac_f16 with OpFmaKHR #11265, saved on the RTX 4090, replayed with agc_shader_replay --spv on this head; with no flag the output is word-for-word main's). On current main 78 of them recompile; 0x25b390800 no longer does (reads or writes a converted float image with 16-bit data, which is not implemented, from main's eb68ad3 / ede33d5, the same with and without this PR):

    target words (78 requests) change
    main, and this PR on NVIDIA (identical modules) 1,337,873 0
    f32 -> f16 native (Intel's and RADV's probe result) 1,320,617 -1.3 %
    both directions native (no device selects it with this PR alone) 1,313,059 -1.9 %

    Per shader, f32 -> f16 native: 0x25b393000 (RCAS) 90,558 -> 73,594 (-18.7 %), both 66,544 (-26.5 %); 5 of 78 shaders change with f32 -> f16 native, 7 with both. On 5b5d24cb22, where 0x25b390800 still recompiled, it went 503,403 -> 419,089 (-16.7 %) with f32 -> f16 native.

  • Startup cost: the probe takes 60-80 ms when run alone (150 ms with the four float modes on either GPU, 236 ms on Intel while 4 tests ran in parallel), on every device creation.

  • In game (performance form), current main 1db077e876, RTX 4090 (NVIDIA 616.92), no-change control: the open-world load of Grand Theft Auto V from the same save, APS5_TRACE_SECONDS=40:80, APS5_MIMALLOC=1, an empty ANYPS5_SHADER_CACHE_DIR per run, in the order base, PR, base again. On plain main the game stops before the menu (GTA V (PPSA04264) stops before the menu: color export format 4 into an unsigned integer target is unsupported #11513), then ~60 s into Story (GTA V (PPSA04264) stops when the save loads: compute shader reads or writes a converted float image with 16-bit data #11425), so both arms carry fix(shader): load and store 16-bit data of converted packed images #11580 and a revert of fix(libSceAgcDriver): export raw 32-bit values into UINT color targets as integers #9789 and nothing else: base 0eb521ce4e, PR a02cac6c3d (= base + 2b25bd1641), on the fork as test/cvt5-base / test/cvt5-pr. Traces, summaries and full digests (current main's trace_digest.py): fork release perf-11351-20261029.

    run frames p50 / p90 / p99 ms longest Vulkan.ComputePipeline (0x25b390800) all compute pipelines
    base 16.8 / 34.6 / 123.2 7543.9 ms 35, 9798 ms
    this PR 16.8 / 33.6 / 203.2 7521.8 ms 34, 9760 ms
    base again 16.8 / 33.5 / 131.9 7261.6 ms 33, 9479 ms

    On this GPU the probe keeps today's path, so the modules are main's and the pair is neutral; the probe itself took 138 ms at device creation. The 17.9-18.7 s max frame of each run is the load's Driver.Packet.memory_wait, not a compile. The first base trace dropped queue worker 0x0 events after 78.4 s, after its compile slice (+55.0 s).

{"commit":"0eb521ce4ed3","dirty":false,"env":{"APS5_MIMALLOC":"1","APS5_TRACE_DIR":"","APS5_TRACE_SECONDS":"40:80"},"gpu":"NVIDIA GeForce RTX 4090","driver":"NVIDIA 616.92","os":"Windows 10.0.26200","cpu":"13th Gen Intel(R) Core(TM) i9-13900K","cpu_threads":32,"memory_mib":65295,"title_id":"PPSA04264","title":"Grand Theft Auto V","content_version":"01.005.000","resolution":"3840x2160","window":{"spec":"seconds 40:80","first_present":416,"ms":80021.538},"presents":2006,"frame_ms":{"p50":16.819,"p90":34.585,"p99":123.235,"max":17859.073},"gpu_busy_ms_per_present":3.029,"worker_busy_pct":{"queue worker 0x0":72.895,"queue worker 0x38":23.607,"queue worker 0x20":9.176,"queue worker 0x30":4.826,"queue worker 0x28":4.224},"top_phases_ms_per_frame":{"Driver.Packet":45.128,"Driver.Packet.memory_wait":16.790,"VideoOut.Flip":13.457,"Graphics.Draw":11.570,"VideoOut.Flip.vblank_wait":11.530,"Graphics.Draw.draw_and_resource_release":10.694,"Driver.Packet.rendering_wait":9.274,"Driver.Packet.draw":9.198},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":78.429,"events_lost":32143,"totals_full":false}},"trace":"aps5-trace-0eb521ce4ed3-6904.json.gz"}
{"commit":"a02cac6c3d21","dirty":false,"env":{"APS5_MIMALLOC":"1","APS5_TRACE_DIR":"","APS5_TRACE_SECONDS":"40:80"},"gpu":"NVIDIA GeForce RTX 4090","driver":"NVIDIA 616.92","os":"Windows 10.0.26200","cpu":"13th Gen Intel(R) Core(TM) i9-13900K","cpu_threads":32,"memory_mib":65295,"title_id":"PPSA04264","title":"Grand Theft Auto V","content_version":"01.005.000","resolution":"3840x2160","window":{"spec":"seconds 40:80","first_present":455,"ms":80038.353},"presents":1897,"frame_ms":{"p50":16.805,"p90":33.589,"p99":203.153,"max":18680.495},"gpu_busy_ms_per_present":2.523,"worker_busy_pct":{"queue worker 0x0":72.994,"queue worker 0x38":1.010,"queue worker 0x20":28.604,"queue worker 0x28":10.702,"queue worker 0x30":2.442},"top_phases_ms_per_frame":{"Driver.Packet":48.503,"Driver.Packet.memory_wait":18.055,"VideoOut.Flip":17.665,"VideoOut.Flip.vblank_wait":15.721,"Graphics.Draw":13.106,"Graphics.Draw.draw_and_resource_release":12.376,"Driver.Packet.draw":11.764,"Driver.Draw":11.742},"trace_dropped":false,"trace":"aps5-trace-a02cac6c3d21-3276.json.gz"}


**What is and is not measured.** The changed path is taken on Intel and RADV, and on neither do we have a title running: this PR's measured effect is the module size above and the probe's correctness on three drivers, not a frame-time or pipeline-creation gain. The RTX 4090 pair only shows that devices which keep today's path are unaffected. Not tested: MoltenVK.

### Checklist
- [x] Based on current `main`; no other open PR implements the same functions
- [x] One topic per PR; follow-ups go in a new PR
- [x] No comments in code except [technical debt](https://github.com/boykopovar/AnyPS5/blob/main/docs/dev/CONVENTIONS.md)
- [x] Unimplemented paths throw (`NotImplemented_nid_no_patch`); silent stubs are listed under Silent stubs in their library's [technical debt](https://github.com/boykopovar/AnyPS5/tree/main/docs/dev/debt) file
- [x] No notes, investigation `.md` files or images added to the repository (attach them to this PR)
- [x] New third-party code is a submodule built from source
- [x] Generic behaviour, not specific to one title
- [x] Depends on: none
- [x] Fixes: none
- [x] Unblocks: none
- [x] GPUs tested: NVIDIA GeForce RTX 4090 (616.92, Windows 11), Intel UHD Graphics 770 (101.6129, Windows 11); AMD Radeon 860M (RADV, Mesa 26.2.5, Fedora 44) by @Lander0606
- [x] AI-assisted: yes (Claude Code)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01PHJtpJ4hw3KWJhobipK8ia




@github-actions github-actions Bot added the perf Performance change label Oct 26, 2026
@tibzejoker

Copy link
Copy Markdown
Contributor Author

AMD runs would be the most useful check here: on RADV both directions are expected to match RDNA, which no GPU I have can show. If you try it, the line to look for at device creation is [float-controls] f16 to f32 NaN results: ...; f32 to f16 NaN results: ..., and ctest -R agc_driver_float16_conversion_probe prints the mismatch counts per class. @tablefrogpillow @wachi35676, in case you have a moment, as on #10980.

@MarcZX10

Copy link
Copy Markdown
Contributor

I verified the release contains both summary assets, both traces and both digest outputs. I reran tools/trace_digest.py against each trace with its matching summary; the digest contents match after normalizing the Windows line endings. One interpretation point for the performance claim: the GTA V captures are on the RTX 4090, where the probe retains the existing emulation path, so these captures validate the no-change control and do not measure gameplay impact on a device that takes the native conversion path. The reported Intel shader-size results provide evidence for that path, but an in-title before/after run on a device where the probe enables native conversion would make the runtime benefit clearer if such a setup is available.

@tibzejoker

Copy link
Copy Markdown
Contributor Author

@MarcZX10 thanks for rerunning the digests. Agreed on the reading: the RTX 4090 pair is only the no-change control. I can't produce an in-title run on a native-path device here: the only one I have is the UHD 770, and Grand Theft Auto V's largest affected shader (0x25b390800) needs Float64, which that device lacks, so the title doesn't run on it. Replaying the NVIDIA pipeline captures on it is refused too (captured SPIR-V version exceeds enabled device support). So the evidence for the native path stays the probe results and the size table until someone runs it on AMD (where both directions are expected to switch) or on an Intel device that runs a title; I'll add any such run to the body.

@github-actions

github-actions Bot commented Oct 26, 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 7642 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L14-15, L4539
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L8180, L8301, L8420, L8422, L8450, L8619, L8781, L8784-8785, L8799-8800, L8854-8855
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp L56-58, L71-72, L222
core/shader/recompiler/CacheKey.hpp L381
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp L901, L945, L954, L1016
core/shader/recompiler/Recompiler.hpp L364
core/shader/recompiler/tests/RequestSerializerTests.cpp L331-332, L378-379, L410-411, L550-551, L566-567, L593, L634-635, L651-652, L654-655, L666, L736-738, L789-790, L801-802, L831-832, L846-849, L908-910, L932-933, L951-953, L964-965, L970-971
PR 9508 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L14-15, L4539
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L8180, L8301, L8420, L8422, L8450, L8619, L8781, L8784-8785, L8799-8800, L8854-8855
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp L56-58, L71-72, L222
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp L901, L945, L954, L1016
core/shader/recompiler/tests/RequestSerializerTests.cpp L331-332, L378-379, L410-411, L550-551, L566-567, L593, L634-635, L651-652, L654-655, L666, L736-738, L789-790, L801-802, L831-832, L846-849, L908-910, L932-933, L951-953, L964-965, L970-971
PR 11551 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L8180, L8301, L8420, L8422, L8450, L8617-8619, L8854-8855
core/shader/recompiler/tests/RequestSerializerTests.cpp L319, L366, L399, L536, L566-567, L593, L620, L652, L666, L802, L909-910, L929, L952, L965
PR 14561 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L8180, L8301, L8420, L8422, L8450, L8854-8855
core/shader/recompiler/tests/RequestSerializerTests.cpp L319, L366, L399, L536, L566-567, L593, L620, L652, L666, L802, L909-910, L929, L952, L965
PR 14871 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L4539
PR 15458 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp L8180, L8301, L8420-8422, L8449-8450, L8853-8855
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp L901, L945, L954, L1016
core/shader/recompiler/tests/RequestSerializerTests.cpp L331-332, L378-379, L410-411, L550-551, L566-567, L593, L634-635, L666, L789-790, L801-802, L831-832, L846-847, L932-933, L964-965
PR 15719 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L14, L574-575, L2702
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp L56-57, L222, L266
core/shader/recompiler/CacheKey.hpp L381
core/shader/recompiler/Recompiler.hpp L364
docs/dev/ARCHITECTURE.md L236
docs/dev/BUILD.md L222
PR 15859 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp L574
PR 15917 core/shader/recompiler/CacheKey.hpp L381
core/shader/recompiler/Recompiler.cpp L694
core/shader/recompiler/Recompiler.hpp L364
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp L48

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 1368 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 1395 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 1835 docs/dev/BUILD.md
PR 1896 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md
PR 4040 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 4472 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 5021 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
docs/dev/BUILD.md
PR 5371 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
PR 5609 core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 5925 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/ARCHITECTURE.md
PR 6186 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md
PR 6187 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6188 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/shader/recompiler/Recompiler.hpp
PR 6192 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6209 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6235 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 6280 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6412 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/ARCHITECTURE.md
PR 6416 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 6481 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6488 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 6804 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 6808 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 6924 core/shader/recompiler/Recompiler.cpp
docs/dev/ENVIRONMENT.md
PR 7275 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 7410 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 7449 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 7457 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md
PR 7508 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 7514 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md
PR 7604 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md
PR 7643 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 7684 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
docs/dev/ARCHITECTURE.md
PR 7689 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
PR 8004 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/ENVIRONMENT.md
PR 8484 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md
PR 8592 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 9012 docs/dev/ENVIRONMENT.md
PR 9020 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 9289 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 9335 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 9345 docs/dev/ENVIRONMENT.md
PR 9356 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 9387 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 9748 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 9852 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/shader/recompiler/Recompiler.hpp
docs/dev/ENVIRONMENT.md
PR 10043 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 10049 core/shader/recompiler/Recompiler.hpp
PR 10193 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 10233 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
PR 10359 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
PR 10442 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 10652 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 10678 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 10757 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
docs/dev/ENVIRONMENT.md
PR 10894 docs/dev/ENVIRONMENT.md
PR 10920 core/libs/prx/libSceAgcDriver/CMakeLists.txt
PR 11435 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/BUILD.md
docs/dev/ENVIRONMENT.md
PR 11436 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/BUILD.md
docs/dev/ENVIRONMENT.md
PR 12324 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp
docs/dev/ENVIRONMENT.md
PR 12544 docs/dev/ENVIRONMENT.md
PR 12828 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 12849 docs/dev/ENVIRONMENT.md
PR 12863 docs/dev/ENVIRONMENT.md
PR 12904 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 12970 docs/dev/ENVIRONMENT.md
PR 13148 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
PR 13486 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/SpirvBackend/src/SpirvAlu/SpirvAluEmitterMath.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 13793 docs/dev/ENVIRONMENT.md
PR 13809 docs/dev/ENVIRONMENT.md
PR 13863 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 13920 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 13928 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 13929 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 14051 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md
PR 14137 docs/dev/BUILD.md
PR 14217 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 14218 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tools/ShaderReplay.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
PR 14344 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ENVIRONMENT.md
PR 14944 core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
PR 15059 docs/dev/ENVIRONMENT.md
PR 15136 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/BUILD.md
docs/dev/ENVIRONMENT.md
PR 15169 core/libs/prx/libSceAgcDriver/CMakeLists.txt
core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 15529 docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 15548 core/libs/prx/libSceAgcDriver/Execution/src/VulkanDevice.cpp
core/libs/prx/libSceAgcDriver/tests/ShaderMemory.cpp
core/shader/recompiler/CacheKey.hpp
core/shader/recompiler/ControlFlow/src/RequestSerializer.cpp
core/shader/recompiler/Recompiler.cpp
core/shader/recompiler/Recompiler.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitter.hpp
core/shader/recompiler/SpirvBackend/include/SpirvBackend/SpirvEmitterState.hpp
core/shader/recompiler/SpirvBackend/src/SpirvEmitter.cpp
core/shader/recompiler/SpirvBackend/src/SpirvModuleEmitter.cpp
core/shader/recompiler/tests/RequestSerializerTests.cpp
docs/dev/ARCHITECTURE.md
docs/dev/ENVIRONMENT.md
PR 15570 core/libs/prx/libSceAgcDriver/CMakeLists.txt
docs/dev/ENVIRONMENT.md

@tibzejoker

Copy link
Copy Markdown
Contributor Author

On the overlap table: none of these implements the same thing. #9193, #10069, #10194, #10652, #10846 and #11297 add their own field, probe or flag next to the lines this PR adds (SpirvTarget and the cache key, the probe block in the VulkanDevice constructor, ARCHITECTURE.md, agc_shader_replay's options), so whichever merges first, the other side is a rebase that keeps both. I'll rebase this one when any of them lands.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head 1081e2351a4b81d84ad1ce2ad627e6d29ab8368f. I found one blocking replay correctness issue:

VulkanDevice::Target() now sets float16WidenNans and float16NarrowNans, and those values control which SPIR-V the live driver emits. Shader captures go through Driver::dumpRequest() and RequestSerializer::Serialize(), but the serializer remains at format version 46 and writes neither field; Deserialize() likewise leaves both false. A captured request from a device that selected the native path therefore silently replays with the emulated NaN repair unless the user manually supplies the new agc_shader_replay flags. Those flags are a useful override, but they do not preserve the captured request's selected target behavior.

Please append both fields in a versioned serializer update and add round-trip coverage (including backward compatibility for older request versions). Keep the CLI switches if they are useful for explicit overrides.

The branch is also about 142 main commits behind its merge base. The current-main merge preview is clean; the two shared paths have unrelated adjacent changes in CMakeLists.txt and docs/dev/BUILD.md. Please sync to current main and rerun conventions and the focused AGC checks against the refreshed base. The existing GPU and trace results are useful historical evidence, but they were produced from the older base.

@Lander0606

Copy link
Copy Markdown
Contributor

@tibzejoker, a RADV run: head 1081e2351a against its base main 14c99b52ac, without merging onto current main. On this device the probe keeps today's path in both directions, but neither reason is a NaN result:

  • f16 -> f32 is never probed on RADV;
  • f32 -> f16 fails only in the toward-zero program, because the driver removes its rounding correction.

With NoContraction on one OpFConvert, f32 -> f16 matches in every probe result, and RADV takes the native path.

Setup

  • Radeon 860M (RDNA 3.5, RADV KRACKAN1), Mesa 26.2.5, Fedora 44, kernel 7.2.11.
  • Built in an Ubuntu 24.04 container with GCC 13.3: Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON.

Probe on RADV

Every device creation in the focused set logs the same line (53 per run):

[float-controls] f16 to f32 NaN results: emulated (no native conversion); f32 to f16 NaN results: emulated (17382 of 220032 probe results differ, first 0x33000001: 0x00000000 emulated, 0x00010001 native)

The probe takes 88-118 ms (median 92) without the validation layer, and about 105 ms with it.

agc_driver_float16_conversion_probe gives:

v_cvt_f16_f32 native vs emulated: 0 of 280480 differ (quiet NaN 0, signalling NaN 0, not NaN 0); the device does not use the native result
v_cvt_pkrtz_f16_f32 native vs emulated: 140763 of 280480 differ (quiet NaN 0, signalling NaN 0, not NaN 140763), first 0x33000001: emulated 0x00000000, native 0x00010001; the device does not use the native result
v_cvt_f16_f32 then v_cvt_f32_f16 native vs emulated: 0 of 280480 differ (quiet NaN 0, signalling NaN 0, not NaN 0); the device does not use the native result
  1. f16 -> f32 isn't probed.

    • RADV reports shaderDenormPreserveFloat16 = true, but denormBehaviorIndependence = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY: AMD shares the f16 and f64 denormal mode.
    • float16DenormPreserve needs INDEPENDENCE_ALL (VulkanDevice.cpp:1474-1475), and the widen direction is probed only when it is set.
    • So on RADV that direction stays emulated, whatever the probe would find. The "both native" row (-9.2 %) can't happen on RADV as main stands.
  2. f32 -> f16: the NaN results already match RDNA.

    • v_cvt_f16_f32 and the round trip match in all 280,480 inputs, every NaN class included.
    • All 140,763 v_cvt_pkrtz_f16_f32 mismatches are non-NaN values rounded to nearest even instead of toward zero. That's the count you saw on NVIDIA.
    • Why: EmitF32ToF16BitsTowardZero corrects the nearest-even half when |f32(half)| > |value|. Without the NaN repair, half is the OpFConvert result itself, and the correction disappears.
    • The NIR: in RADV's final NIR (RADV_DEBUG=nir), the native pkrtz program has no f2f32, flt or isub left after the f2f16. The emulated program still has all three.
    • Not SPIRV-Tools: APS5_SPIRV_OPT=none gives the same 140,763.
  3. With NoContraction on the widening conversion: I tested this one-line change locally, then removed it again.

    -    const auto widened = Unary(state, spv::OpFConvert, TypeF32(state), half);
    +    const auto widened = Exact(state, Unary(state, spv::OpFConvert, TypeF32(state), half));

    On the 860M, with this change:

    • Probe: every device creation logs f32 to f16 NaN results: native (0 of 220032 probe results differ). In the probe test, v_cvt_pkrtz_f16_f32 has 0 of 280,480 mismatches.
    • Focused set: 61/61 without and with the validation layer, no VUID- line. All f16 tests now run with the native f32 -> f16 result.
    • Full ^agc run: 1029 of 1030 pass. The one failure is agc_driver_tessellation, the Mesa 26.2.5 crash that also fails on main.
    • lavapipe: the probe still logs no native conversion in either direction.
    • Not checked: NVIDIA, which keeps the emulated path for its canonical NaN anyway, and Intel.

Focused tests, main against this PR

Command: ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 ctest -j1 -V -R "^agc.*(f16|float16|convert|pack)" -E "^agc_driver_bda_device$". Three runs without and three with VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (1.4.341) and VK_LOADER_DEBUG=layer.

main 14c99b52ac this PR 1081e2351a
RADV, without the layer 59/59, 59/59, 59/59 61/61, 61/61, 61/61
RADV, with the layer 59/59, 59/59, 59/59 61/61, 61/61, 61/61
lavapipe (Mesa 26.2.5), with the layer 59 pass, 2 of them skipped 61 pass, 2 of them skipped
  • lavapipe skips: agc_driver_float16_native and agc_driver_packed_float16_native skip there on both trees.
  • lavapipe probe: it logs emulated (no native conversion) in both directions. CI therefore never runs the native code paths, so it can't catch a fold like the one above.
  • Validation: the layer was inserted 53 times per run on main and 54 on this PR. No log contains was not found but was requested by env var VK_INSTANCE_LAYERS, and no run logs a VUID- line.
  • Full ^agc run on RADV (without the layer, -j8): 1027 of 1028 pass on main and 1029 of 1030 on this PR. On both, the only failure is agc_driver_tessellation, with the same 15 skips.

These runs are on the old base that MarcZX10's review mentions. Once the refreshed head with the serializer change is pushed, I can rerun the same set on the 860M.

AI assisted: yes

@tibzejoker

Copy link
Copy Markdown
Contributor Author

@Lander0606 thank you, this is exactly the run the PR needed, and the NIR check pins it down. You're right on both points:

  • the toward-zero program loses its correction once the NaN rebuild between the two OpFConvert is gone (the same 140,763 count as on the RTX 4090, so it isn't a RADV quirk); I'm taking your NoContraction on the widening, with you as co-author of that commit;
  • the f16 -> f32 direction depends on float16DenormPreserve, which RADV's INDEPENDENCE_32_BIT_ONLY keeps off, so the "both native on RADV" row is wrong as main stands. I'll correct the body: on RADV only f32 -> f16 changes.

@MarcZX10 the serializer point is right too: the next push saves both fields in the request (format 47, older versions read them as false, round-trip coverage), keeps the replay flags as explicit overrides, and is rebased on current main with the focused set rerun.

@tibzejoker
tibzejoker force-pushed the perf/f16-convert-probe branch from 1081e23 to f2300fd Compare October 26, 2026 09:50
@tibzejoker

Copy link
Copy Markdown
Contributor Author

Pushed f2300fd2d2, rebased on main 4e43321bd6:

  • e9c60de5cc: both fields saved in recompile requests (format 47; 46 and older read them as false; round trips of the four combinations; agc_shader_memory's pinned version updated). The replay flags stay as explicit overrides. (@MarcZX10)
  • f2300fd2d2 (co-authored by @Lander0606): NoContraction on the widening fixed RADV but not the RTX 4090, which still folded the pair (same 140,763). The nearest half is now widened with integer operations (shift for normals, exact multiply by 2^-24 for denormals, infinity kept), so there is no f32 -> f16 -> f32 pair left: the forced-native v_cvt_pkrtz comparison is 0 of 280,480 on the UHD 770, and on the 4090 the only differences left are the 9,233 NaN inputs (its canonical NaN, which keeps it emulated). --verify-spirv now requires that program to have no widening OpFConvert.
  • Body corrected: on RADV only f32 -> f16 can switch (float16DenormPreserve needs independence ALL); sizes recomputed on this head (-5.5 % with f32 -> f16 native).
  • Focused set rerun on this head, both GPUs, validation layer: same results as before (4090 58/58 vs 60/60, UHD 770 same 2 unorm4444 failures on both, 0 VUID-).

@Lander0606, if you have time for the same 860M run on this head, the line to check is f32 to f16 NaN results: native (0 of 220032 ...).

@tibzejoker

Copy link
Copy Markdown
Contributor Author

A related question for AMD owners (@Lander0606, @tablefrogpillow, @wachi35676), separate from this PR: on RADV, float16DenormPreserve and float64DenormPreserve are always off because main requires denormBehaviorIndependence ALL, and RADV reports 32_BIT_ONLY. #2977 says why: the backend does not emit coupled execution modes for shared widths. But the only modes it declares for 16 and 64 bits are DenormPreserve, and RDNA itself keeps one denormal mode for f16 and f64 (FLOAT_MODE), so declaring DenormPreserve 16 and 64 together looks legal under 32_BIT_ONLY, and would let RADV take the native f16 paths (both directions of this PR's probe, packed f16 math, f16 interpolation).

I can't test it here (the RTX 4090 and UHD 770 report ALL). Test branch on my fork, on top of this PR: test/coupled-f16-f64-denorms (fe10c0205c, 25 lines). With APS5_COUPLED_F16_F64_DENORMS=1, a 32_BIT_ONLY device that reports shaderDenormPreserveFloat16 and shaderDenormPreserveFloat64 turns both on, and every module that declares one of the two modes declares the other; it logs [float-controls] f16 and f64 denormals share one mode on this device .... Without the variable nothing changes.

If you can, on that branch, with and without the variable (ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1, validation layer on):

  • ctest -R "^agc.*(f16|float16|f64|convert|pack|interpolation)" -E "^agc_driver_bda_device$": pass/fail list and any VUID- line;
  • the two [float-controls] lines (does f16 -> f32 now get probed, and with what result?).

If it holds on RADV, I'll propose it as its own PR with those results. Thanks!

@MarcZX10

Copy link
Copy Markdown
Contributor

Thanks for the substantial update. It addresses the serializer persistence issue (format 47, older-version defaults and four flag combinations) and the reported toward-zero fold by removing the f32→f16→f32 conversion pair. The reported RADV/NVIDIA findings and corrected path-specific result are useful.

Please refresh the branch from current main (5b5d24cb223ede690fe5eab1fe2f7a1736b801a5) before merge. This head is 2 commits ahead and 195 behind its merge base 14c99b52ace3; current main changed the shared AGC CMake file and docs/dev/BUILD.md, and the repository asks PR branches to be based on current main. I ran current-main conventions and git diff --check on the pushed head; both pass. The current hosted checks are policy/report checks, with product jobs skipped by path policy.

After rebasing, please rerun the focused serializer and AGC f16/SPIR-V checks on the exact new head. The linked performance release does contain both summary files, traces and digest outputs, but its changed-arm summary is for ancestor 1081e2351a4b, not this head f2300fd2d2; please refresh the paired capture and digest if the performance report is intended to describe the final head. The description also says the post-fix RADV run is pending, so please add that result when available or leave the RADV result explicitly pending. I have not independently run the GPU tests here.

@Lander0606

Copy link
Copy Markdown
Contributor

@tibzejoker, both runs on the 860M. @MarcZX10, the first part is the post-fix RADV run that the description lists as pending.

Setup

  • Same machine as before: Radeon 860M (RADV KRACKAN1), Mesa 26.2.5, Fedora 44.
  • Built in an Ubuntu 24.04 container with GCC 13.3: Release, BUILD_TESTING=ON, ANYPS5_ENABLE_SPIRV_TOOLS=ON.
  • Every run had ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1.
  • The validation layer is 1.4.341, with VK_LOADER_DEBUG=layer.

This PR at f2300fd2d2, against its base main 4e43321bd6, without merging onto current main

On RADV, f32 -> f16 now switches to native. Every device creation in the focused set logs this, 53 per run:

[float-controls] f16 to f32 NaN results: emulated (no native conversion); f32 to f16 NaN results: native (0 of 220032 probe results differ)

agc_driver_float16_conversion_probe gives:

v_cvt_f16_f32 native vs emulated: 0 of 280480 differ (quiet NaN 0, signalling NaN 0, not NaN 0); the device uses the native result
v_cvt_pkrtz_f16_f32 native vs emulated: 0 of 280480 differ (quiet NaN 0, signalling NaN 0, not NaN 0); the device uses the native result
v_cvt_f16_f32 then v_cvt_f32_f16 native vs emulated: 0 of 280480 differ (quiet NaN 0, signalling NaN 0, not NaN 0); the device uses the native result

The focused set is ctest -j1 -V -R "^agc.*(f16|float16|convert|pack)" -E "^agc_driver_bda_device$", run three times without and three times with VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation.

main 4e43321bd6 this PR f2300fd2d2
RADV, without the layer 59/59, 59/59, 59/59 61/61, 61/61, 61/61
RADV, with the layer 59/59, 59/59, 59/59 61/61, 61/61, 61/61
lavapipe, with the layer 59 pass, 2 of them skipped 61 pass, 2 of them skipped
RADV, full ^agc (-j8, without the layer) 1029 of 1030 1031 of 1032
  • Validation: the layer was inserted 53 times per run on main and 54 on this PR. No log contains was not found but was requested by env var VK_INSTANCE_LAYERS, and no run logs a VUID- line.
  • Full ^agc run: on both trees, the only failure is agc_driver_tessellation, the Mesa 26.2.5 crash, with the same 15 skips.
  • lavapipe: agc_driver_float16_native and agc_driver_packed_float16_native skip there on both trees. Its probe logs no native conversion in either direction.
  • Probe time: 89-115 ms (median 92) without the layer.

test/coupled-f16-f64-denorms at fe10c0205c

The set is ctest -j1 -V -R "^agc.*(f16|float16|f64|convert|pack|interpolation)" -E "^agc_driver_bda_device$": 76 tests, 15 more than above (the f64 tests, interpolation_modes and pixel_exec_interpolation).

without the variable APS5_COUPLED_F16_F64_DENORMS=1
RADV, with the layer 76/76, 76/76, 76/76 76/76, 76/76, 76/76
RADV, without the layer not run 76/76
RADV, full ^agc (-j8, without the layer) 1031 of 1032 1031 of 1032

[float-controls] lines on RADV, the same in every one of the 67 device creations per run:

Without the variable:

[float-controls] f16 to f32 NaN results: emulated (no native conversion); f32 to f16 NaN results: native (0 of 220032 probe results differ)

With the variable:

[float-controls] f16 and f64 denormals share one mode on this device: DenormPreserve 16 and 64 are declared together
[float-controls] f16 to f32 NaN results: native (0 of 262144 probe results differ); f32 to f16 NaN results: native (0 of 220032 probe results differ)

With the variable, agc_driver_float16_conversion_probe adds v_cvt_f32_f16 native vs emulated: 0 of 65536 differ (quiet NaN 0, signalling NaN 0, not NaN 0); the device uses the native result. It ends with f16 conversion probe tests passed (f16 to f32 compared, f32 to f16 compared).

  • f16 -> f32: RADV now probes this direction, and every result matches. With the variable, both directions are native.
  • f64 DenormPreserve on: the 13 f64 tests in the set pass with it, among them f64_fma_subnormals, f64_rounding_denormal_modes and div_fixup_f64_denormal_modes. So do the two interpolation tests.
  • Validation: no run logs a VUID- line. The layer was inserted 68 times per run, and no log contains the not-found line.
  • Full ^agc run: with and without the variable, the only failure is agc_driver_tessellation, with the same 15 skips as above.
  • Probe time with the variable: 118-138 ms (median 120) without the layer, against about 92 ms without the variable. Probing f16 -> f32 adds about 28 ms per device creation.
  • lavapipe, with the variable and the layer: no share one mode line, because that device doesn't report 32_BIT_ONLY. 76 pass, 3 of them skipped: f64_fma_subnormals, float16_native and packed_float16_native.

A limit of the zero VUID- result. I checked whether the layer would catch an uncoupled declaration:

  • I made a local change, since removed, that drops the f64 half of EmitF16DenormPreserve. Modules without f64 then declare only DenormPreserve 16.
  • With the variable and the layer, agc_driver_float16_conversion_probe still logged no VUID- line.
  • The layer has VUID-RuntimeSpirv-denormBehaviorIndependence-06289, but here it doesn't flag a missing 64-bit mode. So the zero count above doesn't by itself show that the modes are coupled.
  • What does show it is the code: on this branch, the only 16- and 64-bit DenormPreserve declarations are in EmitF16DenormPreserve and EmitF64DenormPreserve (git grep ExecutionModeDenorm), and each of the two declares the other.

Not checked: SPIR-V size or performance with the variable, and no title was run.

AI assisted: yes

anyps5-pr11351-radv-860m-logs.zip

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed exact head f2300fd. The serializer blocker is resolved: format 47 stores both flags, older requests default them to false, four flag combinations round-trip, truncation is rejected, and the cache key includes both flags. The new RADV 860M results on this exact head also address the previously pending focused GPU run. Current main advanced beyond the branch base, but none of the 42 intervening main paths overlap the PR's changed files and the merge preview is clean, so I found no new source-integration issue.

One required performance-report item remains. This PR is labeled , but its attached summary pair is for main commit and PR commit , not the final head . That trace pair also uses an RTX 4090 where the report says both native flags stay disabled, so it checks that the tested scene does not regress but does not measure the optimization. Please provide the required same-title/scene/machine main-and-final-head captures with output from a run that exercises the native path, or update the performance claim and follow the repository's reporting rule for the resulting scope. Please also bring the new RADV 860M exact-head result from the discussion into the Tested section, which still describes that rerun as pending.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed exact head f2300fd2d20dc81095448ef7fe920f711f00a7f8. The serializer blocker is resolved: format 47 stores both flags, older requests default them to false, four flag combinations round-trip, truncation is rejected, and the cache key includes both flags. The new RADV 860M results on this exact head also address the previously pending focused GPU run. Current main advanced beyond the branch base, but none of the 42 intervening main paths overlap the PR's changed files and the merge preview is clean, so I found no new source-integration issue.

One required performance-report item remains. This PR is labeled perf, but its attached summary pair is for main commit 14c99b52ace3 and PR commit 1081e2351a4b, not the final head f2300fd2d2. That trace pair also uses an RTX 4090 where the report says both native flags stay disabled, so it checks that the tested scene does not regress but does not measure the optimization. Please provide the required same-title, same-scene, same-machine main-and-final-head captures with tools/trace_digest.py output from a run that exercises the native path, or update the performance claim and follow the repository's reporting rule for the resulting scope. Please also bring the new RADV 860M exact-head result from the discussion into the Tested section, which still describes that rerun as pending.

@tibzejoker
tibzejoker force-pushed the perf/f16-convert-probe branch from f2300fd to 20a660b Compare October 26, 2026 11:10
@tibzejoker

Copy link
Copy Markdown
Contributor Author

@MarcZX10 refreshed: head 20a660bea4 on main 5b5d24cb22.

  • One change on top of the previous push: the integer widening of the toward-zero pack is now used only with float16NarrowNans. Without it the NaN rebuild already separates the two conversions, so the module stays main's; the unconditional version cost NVIDIA +0.35 % words for nothing. The 79 GTA V requests are now word-for-word identical to main on the RTX 4090 (1,835,161), -5.5 % with f32 -> f16 native, -8.8 % with both.
  • Rerun on this exact head: focused set on both GPUs with the validation layer (4090 58/58 vs 60/60; UHD 770 the same 2 unorm4444 failures on both; 0 VUID-), request_serializer, agc_shader_memory, the probe test and its SPIR-V check.
  • New load-window pair on this head and its base: perf-f16-convert-probe-20261026b, summaries and digests in the body. The RADV rerun on this head is marked pending.

@tibzejoker

Copy link
Copy Markdown
Contributor Author

For the AMD question above: test/coupled-f16-f64-denorms is now on this PR's current head (1869b55184 on 20a660bea4), so one 860M run of that branch covers both: without APS5_COUPLED_F16_F64_DENORMS it is this PR, with it the coupled modes.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed exact head 20a660bea49eb726e84a3ebfe4a3a92a28e2b7b4 against current main 4e38e2388219e065eba52461f2e59234fcb57b13. Two blockers remain:

  1. Current-main serializer integration. Since the branch was refreshed from 5b5d24cb22, main added ColorExportPacking::Uint and updated readColorExportPacking to accept it. This head still caps that decoder at Unorm4_4_4_4; after merging current main, valid requests using Uint would be rejected unless the new bound is retained alongside format 47’s two f16 flags. main also changed the shared AGC CMake and SPIR-V module-emitter files. Please merge current main, preserve both changes, and rerun request_serializer plus the focused f16 tests on the resulting head.

  2. Performance evidence does not exercise the optimized path. The body’s final-head GTA V pair is on an RTX 4090 where both native flags remain disabled and the replayed modules are word-for-word unchanged. That is useful as a no-regression control, but does not measure the claimed native-conversion optimization. The body also still says the RADV 860M rerun on this head is pending, although later comments report it. Please provide a same-title/main/final-head trace and digest on a device where the probe selects the changed path, or get maintainer direction for an applicable tooling/performance report and update the claim accordingly. Move the exact-head RADV result into Tested as well.

The policy checks pass, but the PR’s product jobs are skipped by path policy; these integration and GPU checks therefore need evidence on the refreshed head before approval.

@tibzejoker

Copy link
Copy Markdown
Contributor Author

@Lander0606 thank you, that settles both questions: on RADV this PR now takes native f32 -> f16 with 0 differences, and with the coupled modes both directions are native, all 76 f16/f64/interpolation tests pass and the f64 denormal tests still hold. Your check of the layer (it doesn't flag an uncoupled declaration) is useful too; I'll put that in the coupled PR's body and add a SPIR-V check that every module declaring one of the two modes declares the other, rather than rely on the layer. I'll open the coupling as its own PR with your numbers.

@MarcZX10 understood on both points: I'll merge current main (keeping ColorExportPacking::Uint next to format 47), rerun request_serializer and the focused set on the resulting head, move the RADV result into Tested, and reword the performance claim: here the only device that takes the changed path is the UHD 770, which can't run a title. @Lander0606, if the 860M can run any title, a main vs this PR load-window pair (APS5_TRACE_SECONDS, empty ANYPS5_SHADER_CACHE_DIR) would be the evidence MarcZX10 asks for; otherwise I'll ask the maintainers which report fits a change that only shows on AMD/Intel.

@Lander0606

Copy link
Copy Markdown
Contributor

@tibzejoker, I have no title to run on the 860M, so I can't give that load-window pair. Once the head with current main is pushed, I can rerun the same focused set and the probe test on RADV on that exact head, and the coupled branch on top of it.

@tibzejoker

Copy link
Copy Markdown
Contributor Author

@Lander0606 thanks, understood. I'll ping you here once the head with current main is pushed.

@tibzejoker
tibzejoker force-pushed the perf/f16-convert-probe branch from 20a660b to 6e17eb4 Compare October 26, 2026 16:17
@tibzejoker

Copy link
Copy Markdown
Contributor Author

@adriadam10 @MarcZX10 rebased onto current main 9090972b7e. The new head is 32cc90dee4.

  • Format 53, not 52: after your review, main took 52 too, with a5fef8c439 (hostInterpolationFirst, mrfelek). So the two f16 NaN fields are now written after that flag as 53:
    • Deserialize reads them with version >= 53u, accepts up to 53 and still rejects 50;
    • versions 52 and older read both fields as false;
    • the "future" request is 54 (request_serializer), and the unsupported list in agc_shader_memory is now 0 / 50 / 54.
    • I re-applied our tail delta on main's side of both test files, following the shape a5fef8c439 used for its own byte, plus our four-combination round trip and a 52 → 53 upgrade check in the merged-hull point fixture. 0ac8ccd805 (unsupported 51) was dropped, since that bound moved to 54 in the serializer commit. The docs line and the serializer commit message now say 53.
  • Conflicts: besides the serializer, only CacheKey.hpp and Recompiler.hpp, next to hostInterpolationFirst. I kept both sides. The VulkanDevice.cpp conflict MarcZX10 saw against 8a4fc62318 no longer shows on this base.
  • Focused set, same command as the body. Validation layer inserted in every run (84 / 85), ANYPS5_NO_SHADER_CACHE=1:
GPU main 9090972b7e this PR VUID- lines
RTX 4090 (616.92) 95/95 97/97 0 / 0
UHD 770 (101.6129) 94/95 96/97 0 / 0

On both trees the one UHD failure is agc_driver_packed_unorm4444_multisample_partial_write. request_serializer and agc_shader_memory pass, and the probe lines are unchanged.

  • check_conventions.py --base upstream/main passes. The body's Tested section points to this head and base.

I also updated the note on #11483: it takes 54 once this lands.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Nov 2, 2026
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head 32cc90d merged onto main 9090972 · tested 2026-11-03 01:26 UTC · 29 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 2,708 passed · 6 failed (0 new, 3 also fail on main, 3 unstable on main) · 45 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 2,759 of 3,607 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (982 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.2 s, ⚠️ agc_driver_graphics 34.1 s, ⚠️ agc_driver_graphics_maps_fallback 33.1 s
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 3 of the last 10 main runs
agc_submit_progress: failed in 7 of the last 10 main runs
agc_submit_progress_no_timeline: failed in 6 of the last 10 main runs
Failing on main too (3, not counted against this PR)
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (1, not in the main baseline's validation pass)
agc_driver_float16_conversion_probe
Validation IDs already present on main (4 IDs in 516 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (516 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 508 more
VUID-vkCmdCopyImage-srcImage-01548 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_prepared_exports
Skipped (45)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_dcc: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_deferred: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_main: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_fps_limit: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_o
Reproduce
git fetch origin 32cc90dee4ff391b0c1bc87716d3d5b38291b15d 9090972b7e91fd266819cbd77a8b058e177b5682
git checkout 9090972b7e91fd266819cbd77a8b058e177b5682 && git merge --no-ff 32cc90dee4ff391b0c1bc87716d3d5b38291b15d
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

@tibzejoker

Copy link
Copy Markdown
Contributor Author

@adriadam10 @MarcZX10 rebased again onto main 1e658521a0. The new head is b0a7aef374. Two changes since my last comment:

  • Format 54: main took 53 meanwhile, with fe18496c95 (shaderImageMinLod). The two f16 NaN fields are now written after that flag as 54: read with version >= 54u, accepted up to 54, 50 still rejected, and 53 or older read both as false. The "future" request is 55 and the unsupported list in agc_shader_memory is 0 / 50 / 55. As before, our 2-byte tail was re-applied on main's side of both test files, in the shape fe18496c95 used for its own byte. The other conflicts were only the SpirvTarget field list and the cache key, next to shaderImageMinLod, and I kept both sides. fix(shader): declare f16 and f64 DenormPreserve together when their modes are shared #11483 will take 55; I updated its note.
  • Windows CI failure fixed: the hosted Windows job failed on agc_driver_float16_conversion_probe_spirv. That build leaves the execution tests out, so the test printed skipped, this build leaves the test out with ANYPS5_AGC_EXECUTION_TESTS and returned 77. Our registration had no SKIP_RETURN_CODE 77, unlike main's other _spirv registrations (for example agc_driver_f16_to_f32_unpack_spirv), so CTest counted the skip as a failure. The fragment now declares it (folded into the first commit).

Focused set, same command as the body. Validation layer inserted in every run (84 / 85), ANYPS5_NO_SHADER_CACHE=1:

GPU main 1e658521a0 this PR VUID- lines
RTX 4090 (616.92) 95/95 97/97 0 / 0
UHD 770 (101.6129) 94/95 96/97 0 / 0

The one UHD failure is agc_driver_packed_unorm4444_multisample_partial_write on both trees. request_serializer, agc_shader_memory, agc_driver_float16_conversion_probe and _spirv pass. check_conventions.py passes, and the body points to this head and base.

AI-assisted: yes (Claude Code)

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head b0a7aef merged onto main 1e65852 · tested 2026-11-03 19:10 UTC · 28 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 2,774 passed · 7 failed (0 new, 3 also fail on main, 4 unstable on main) · 48 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 2,829 of 3,818 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (941 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.1 s
Unstable on main (4, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 4 of the last 10 main runs
agc_driver_submit_progress: failed in 5 of the last 10 main runs
agc_submit_progress: failed in 6 of the last 10 main runs
agc_submit_progress_no_timeline: failed in 5 of the last 10 main runs
Failing on main too (3, not counted against this PR)
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (1, not in the main baseline's validation pass)
agc_driver_float16_conversion_probe
Validation IDs already present on main (4 IDs in 518 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (518 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 510 more
VUID-vkCmdCopyImage-srcImage-01548 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (2 tests): agc_driver_prepared_exports, agc_driver_srgb8_color_target
Skipped (48)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_stencil_ref_export: skipped, the device lacks VK_EXT_shader_stencil_export
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_dcc: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_deferred: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop_main: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not co
Reproduce
git fetch origin b0a7aef374da828141e276fd95cca2760e0e25ed 1e658521a0a599872612bb91949311e2956b5283
git checkout 1e658521a0a599872612bb91949311e2956b5283 && git merge --no-ff b0a7aef374da828141e276fd95cca2760e0e25ed
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Nov 3, 2026
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ AMD GPU test: passed

PR head b0a7aef merged onto main 1e65852 · tested 2026-11-03 21:06 UTC · 38 min

GPU AMD Radeon RX 6300 (RADV NAVI24), driver Mesa 25.2.8-0ubuntu0.24.04.4, Vulkan 1.4.318
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-42-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 2,760 passed · 10 failed (0 new, 9 also fail on main, 1 unstable on main) · 59 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 2,829 of 3,818 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (941 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.3 s, ⚠️ agc_driver_image_sample_unnormalized 56.3 s, ⚠️ agc_driver_lazy_resolved_abi 46.1 s, ⚠️ agc_driver_indirect_thread_dimensions 35.8 s, ⚠️ public_headers 35.7 s
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 7 of the last 9 main runs
Failing on main too (9, not counted against this PR)
agc_driver_image_table
agc_driver_native_depth_bda_clear
agc_driver_native_multisample_depth
agc_driver_store_over_untracked
agc_driver_submit_progress
agc_submit_progress
agc_submit_progress_no_timeline
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (1, not in the main baseline's validation pass)
agc_driver_float16_conversion_probe
Validation IDs already present on main (4 IDs in 518 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (518 tests): agc_driver, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, agc_driver_bda_span_reads, and 510 more
VUID-vkCmdCopyImage-srcImage-01548 (4 tests): agc_driver_depth_clear_hle, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (4 tests): agc_driver_depth_clear_hle, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (2 tests): agc_driver_prepared_exports, agc_driver_srgb8_color_target
Skipped (59)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_copied_writer_label_order: skipped, the device reports a minStorageBufferOffsetAlignment of 4, so the dispatch binds its record at +0x1004 in place and nothing is written back; the test needs an alignment above 4
agc_driver_float16_unused_nan_payloads: skipped, the device has no native f16 conversions with RTE rounding and kept f16 denormals
agc_driver_image_table_vouched_lookups: skipped, the device reports 4 of 4 host-imported pages written after a GPU read, so a watched imported table cannot be vouched for
agc_driver_linear_target_direct_write_completion: skipped, the device does not keep host imports write-watched, so no completion stamp over the target is tracked
agc_driver_ngg_vertex_wave_reduction: skipped, s3 describes a 32-lane wave only on 32-lane subgroups, and the device has 64 lanes
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_driver_unit_shadow_budget: skipped, the device does not import watched host memory for unit shadows
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_idle_publish_wait: skipped, the device reports 4 of 4 host-imported pages written after a GPU read, so a forced watch of the import reads its submissions as CPU stores
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_shadowed_key_stores: skipped, the device imports no watched host memory under a unit shadow
agc_small_tiled_shadow_label: skipped, host imports are unavailable: the test block is not imported and watched
agc_storage_clear_hand_over: skipped, the device imports no watched host memory for the clear-key hand-over
agc_storage_pending_key_refresh: skipped, refreshes over a pending key store are not testable here
agc_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video dr
Reproduce
git fetch origin b0a7aef374da828141e276fd95cca2760e0e25ed 1e658521a0a599872612bb91949311e2956b5283
git checkout 1e658521a0a599872612bb91949311e2956b5283 && git merge --no-ff b0a7aef374da828141e276fd95cca2760e0e25ed
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 12 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 16 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

tibzejoker and others added 5 commits November 4, 2026 19:26
…robe matches RDNA

Native OpFConvert and UnpackHalf2x16 round and handle denormals as RDNA does
under RoundingModeRTE and DenormPreserve 16, but Vulkan leaves the NaN they
return to the driver, so every conversion rebuilds RDNA's NaN with integer
selects (about 55 words per f32 to f16 conversion, 29 per f16 to f32).

ProbeFloat16Conversions runs when the device is created: v_cvt_f32_f16 over
all 65,536 halves and v_cvt_f16_f32, v_cvt_pkrtz_f16_f32 and a round trip
over every NaN payload class, signalling NaNs, denormals, ties and overflow,
under four float modes, each compiled with the rebuilt NaN and with the
native result, inputs read from a buffer. SpirvTarget::float16WidenNans and
float16NarrowNans are set per direction only when every result matches; both
are in the recompile cache key. APS5_NO_NATIVE_F16_NANS skips the probe.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PHJtpJ4hw3KWJhobipK8ia
…ults

--f16-widen-nans and --f16-narrow-nans set float16WidenNans and
float16NarrowNans on a saved request's target, as --robust2 does for its
feature, so the SPIR-V of a device whose probe matched can be measured.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PHJtpJ4hw3KWJhobipK8ia
SpirvTarget::float16WidenNans and float16NarrowNans shape the emitted
SPIR-V, but the request serializer did not write them, so a request saved
on a device whose probe matched replayed with the emulated NaN rebuild.
Format version 54 writes both flags after the shader image minimum LOD flag;
versions 53 and older read them as false. agc_shader_replay's --f16-widen-nans
and --f16-narrow-nans still force them on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PHJtpJ4hw3KWJhobipK8ia
…integer arithmetic

The toward-zero pack corrects the nearest-even half when it widens back
above the input. Once the f32 to f16 NaN rebuild is skipped, that half is
the OpFConvert result itself and RADV and NVIDIA fold the f32 -> f16 ->
f32 pair, so the correction disappeared (140,763 of 280,480 probe inputs
rounded to nearest even). NoContraction on the widening is enough on RADV
but not on NVIDIA. With float16NarrowNans the half is now widened with
integer operations (exact multiply for denormals), which no driver can
fold; without it the NaN rebuild still separates the two conversions and
the module is unchanged.

Co-authored-by: Lander0606 <109523124+Lander0606@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PHJtpJ4hw3KWJhobipK8ia
…N fields

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@tibzejoker
tibzejoker force-pushed the perf/f16-convert-probe branch from b0a7aef to 6740167 Compare November 4, 2026 18:39
@tibzejoker

Copy link
Copy Markdown
Contributor Author

@adriadam10 @MarcZX10 rebased onto main 9ab6a281ea. The new head is 6740167447, and it is still format 54: main's serializer is still at 53.

The conflicts were all "keep both sides" next to code that landed meanwhile:

  • main's new f32 denormal preserve probe, ProbeFloat32DenormPreserve, and its FloatProbeTolerance.cpp, in VulkanDevice.cpp and CMakeLists.txt. The f16 conversion probe now runs after it. In ARCHITECTURE.md our section says "also runs a probe" instead of "a second probe", because the preserve probe is now the second one.
  • agc_shader_replay's --shader-fma from perf(shader): compute v_pk_fma_f16 and v_pk_fmac_f16 with OpFmaKHR #11265, next to our --f16-widen-nans and --f16-narrow-nans, including the usage line.

I re-ran the focused set with the same command as the body. The validation layer was inserted in every run (84 / 85) with ANYPS5_NO_SHADER_CACHE=1.

GPU main 9ab6a281ea this PR VUID- lines
RTX 4090 (616.92) 95/95 97/97 0 / 0
UHD 770 95/95 97/97 0 / 0

The earlier Intel unorm4444 failure is gone on both sides on this main. The probe lines are unchanged. check_conventions.py passes. The body has the new head and numbers.

AI-assisted: yes (Claude Code)

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Nov 4, 2026
@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ NVIDIA GPU test: passed

PR head 6740167 merged onto main 9ab6a28 · tested 2026-11-04 20:54 UTC · 39 min

GPU NVIDIA RTX 2000 Ada Generation, driver 595.99.02, Vulkan 1.4.329
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-38-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 2,852 passed · 7 failed (0 new, 3 also fail on main, 4 unstable on main) · 50 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 2,909 of 3,909 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (985 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.2 s, ⚠️ agc_driver_indirect_arguments_pending_producer 34.3 s, ⚠️ agc_driver_indirect_thread_dimensions 33.9 s, ⚠️ agc_driver_lazy_resolved_abi 31.6 s
Unstable on main (4, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 3 of the last 10 main runs
agc_driver_submit_progress: failed in 3 of the last 10 main runs
agc_submit_progress: failed in 4 of the last 10 main runs
agc_submit_progress_no_timeline: failed in 3 of the last 10 main runs
Failing on main too (3, not counted against this PR)
agc_driver_image_table
guest_mmap_executable
guest_socket_options_multicast
Validated but not compared (1, not in the main baseline's validation pass)
agc_driver_float16_conversion_probe
Validation IDs already present on main (13 IDs in 549 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (549 tests): agc_driver, agc_driver_address_draw_space_reuse, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, and 541 more
VUID-VkShaderModuleCreateInfo-pCode-08737 (8 tests): agc_driver_dpp16_operands, agc_driver_dpp8_pk_fmac, agc_driver_dx10_clamp, agc_driver_float16_fma_rounding, agc_driver_float16_unused_nan_payloads, agc_driver_packed_alu, agc_driver_packed_f16_denormal_modes, agc_driver_packed_float16_native
VUID-VkShaderModuleCreateInfo-pCode-08739 (8 tests): agc_driver_dpp16_operands, agc_driver_dpp8_pk_fmac, agc_driver_dx10_clamp, agc_driver_float16_fma_rounding, agc_driver_float16_unused_nan_payloads, agc_driver_packed_alu, agc_driver_packed_f16_denormal_modes, agc_driver_packed_float16_native
VUID-VkShaderModuleCreateInfo-pCode-08741 (8 tests): agc_driver_dpp16_operands, agc_driver_dpp8_pk_fmac, agc_driver_dx10_clamp, agc_driver_float16_fma_rounding, agc_driver_float16_unused_nan_payloads, agc_driver_packed_alu, agc_driver_packed_f16_denormal_modes, agc_driver_packed_float16_native
VUID-vkCmdCopyImage-srcImage-01548 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (7 tests): agc_driver_depth_clear_hle, agc_driver_depth_plane_buffer_memory, agc_driver_depth_plane_partial_store, agc_driver_depth_plane_sampling, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_srgb8_color_target
VUID-VkPipelineShaderStageCreateInfo-module-parameter (1 test): agc_driver_float16_unused_nan_payloads
VUID-VkPipelineShaderStageCreateInfo-pSpecializationInfo-06849 (1 test): agc_driver_float16_unused_nan_payloads
VUID-VkSamplerCreateInfo-addressModeU-01079 (1 test): agc_driver_image_gather_volume
VUID-VkSamplerCreateInfo-addressModeU-parameter (1 test): agc_driver_image_gather_volume
VUID-VkSamplerCreateInfo-addressModeV-parameter (1 test): agc_driver_image_gather_volume
VUID-VkSamplerCreateInfo-addressModeW-parameter (1 test): agc_driver_image_gather_volume
Skipped (50)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_gcn_display_present: skipped, no display: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
agc_driver_sample_order_grid_reference: skipped, the device does not keep depth drawn at custom sample locations at those locations, even after a transition that names them: the composite of uniform renders holds the guest's depth in 0 of 3005 sloped samples, so no path can be compared with it bit for bit
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_stencil_ref_export: skipped, the device lacks VK_EXT_shader_stencil_export
agc_driver_vertex_elected_atomic_max: skipped, the device runs vertex programs in subgroups, so they keep their cross-lane reductions
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_controls: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_cpuflip_in_order: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_dcc: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_deferred: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_eop: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
vide
Reproduce
git fetch origin 674016744723b1856bd34f01f4fdcd208cd885e7 9ab6a281ea61c9e62a7eb07eb4cef8f19ede1c5c
git checkout 9ab6a281ea61c9e62a7eb07eb4cef8f19ede1c5c && git merge --no-ff 674016744723b1856bd34f01f4fdcd208cd885e7
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 32 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 4 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

@TechLevelZero

Copy link
Copy Markdown
Contributor

✅ AMD GPU test: passed

PR head 6740167 merged onto main b611e63 · tested 2026-11-05 00:46 UTC · 43 min

GPU AMD Radeon RX 6300 (RADV NAVI24), driver Mesa 25.2.8-0ubuntu0.24.04.4, Vulkan 1.4.318
Host Ubuntu 26.04.1 LTS, kernel 7.0.0-42-generic, container ubuntu:24.04
Logs build and test logs for this run
Build ✅ passed (Release, -DANYPS5_ENABLE_SPIRV_TOOLS=ON)
Tests ✅ 2,872 passed · 10 failed (0 new, 9 also fail on main, 1 unstable on main) · 60 skipped (ANYPS5_REQUIRE_VULKAN=1)
Test setup CPU-only tests without a GPU; GPU tests (and any CPU-only test that failed or skipped without one) once on the GPU with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1; main ran the same way
Test selection 2,942 of 3,946 tests run: the ones this change can reach, chosen by tools/select_tests.py from main's build graph
Vulkan validation ✅ no new validation IDs vs main (992 tests run on the GPU)
Slow tests (>30 s, GPU tests timed with validation layers) ⚠️ agc_driver_pipeline_journal 120.3 s, ⚠️ agc_driver_image_sample_unnormalized 88.9 s, ⚠️ agc_driver_lazy_resolved_abi 64.2 s, ⚠️ agc_driver_indirect_thread_dimensions 49.7 s, ⚠️ agc_driver_indexed_copy 47.4 s
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)
agc_driver_pipeline_journal: failed in 9 of the last 10 main runs
Failing on main too (9, not counted against this PR)
agc_driver_image_gather_volume
agc_driver_image_table
agc_driver_native_depth_bda_clear
agc_driver_native_multisample_depth
agc_driver_submit_progress
agc_submit_progress
agc_submit_progress_no_timeline
guest_mmap_executable
guest_socket_options_multicast
Passed on retry (1, failed in the parallel run, passed when re-run with a 360 s timeout; not counted against this PR)
agc_driver_emulated_color_compare: Timeout in the parallel run; also passed only on retry in 41 other runs in the last 7 days
Validated but not compared (1, not in the main baseline's validation pass)
agc_driver_float16_conversion_probe
Validation IDs already present on main (4 IDs in 558 tests)
VUID-VkDeviceCreateInfo-pNext-pNext (558 tests): agc_driver, agc_driver_address_draw_space_reuse, agc_driver_address_passes, agc_driver_alias_copy_label, agc_driver_alpha_to_coverage, agc_driver_array_layer_target, agc_driver_bc_block_copy, agc_driver_bda_anchor_reads, and 550 more
VUID-vkCmdCopyImage-srcImage-01548 (4 tests): agc_driver_depth_clear_hle, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-vkCmdCopyImage-srcImage-01551 (4 tests): agc_driver_depth_clear_hle, agc_driver_depth_storage_dispatch, agc_driver_depth_surface_from_storage, agc_driver_dispatch_move_depth
VUID-VkPipelineColorBlendStateCreateInfo-pAttachments-00605 (1 test): agc_driver_srgb8_color_target
Skipped (60)
agc_driver_bda_reads_shadowed_results: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_bda_reads_shadowed_results_per_build: skipped, the device reports watched host memory written when it imports or reads it
agc_driver_copied_writer_label_order: skipped, the device reports a minStorageBufferOffsetAlignment of 4, so the dispatch binds its record at +0x1004 in place and nothing is written back; the test needs an alignment above 4
agc_driver_float16_unused_nan_payloads: skipped, the device has no native f16 conversions with RTE rounding and kept f16 denormals
agc_driver_gcn_display_present: skipped, no display: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
agc_driver_image_table_vouched_lookups: skipped, the device reports 4 of 4 host-imported pages written after a GPU read, so a watched imported table cannot be vouched for
agc_driver_linear_target_direct_write_completion: skipped, the device does not keep host imports write-watched, so no completion stamp over the target is tracked
agc_driver_ngg_vertex_wave_reduction: skipped, s3 describes a 32-lane wave only on 32-lane subgroups, and the device has 64 lanes
agc_driver_scattered_runs: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_sparse_dma_buf_import: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_driver_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_driver_unit_shadow_budget: skipped, the device does not import watched host memory for unit shadows
agc_host_import_sparse: skipped, host imports are unavailable: /dev/udmabuf is not accessible
agc_idle_publish_wait: skipped, the device reports 4 of 4 host-imported pages written after a GPU read, so a forced watch of the import reads its submissions as CPU stores
agc_import_settle_initial_dcc: skipped, the device has no deferred settle of host imports: imports under 1 MiB wait for one only on Windows
agc_shadowed_key_stores: skipped, the device imports no watched host memory under a unit shadow
agc_small_tiled_shadow_label: skipped, host imports are unavailable: the test block is not imported and watched
agc_storage_clear_hand_over: skipped, the device imports no watched host memory for the clear-key hand-over
agc_storage_pending_key_refresh: skipped, refreshes over a pending key store are not testable here
agc_unit_shadow: skipped, the device does not import watched host memory for unit shadows
agc_unit_shadow_completion_store: skipped, the device reports watched host memory written when it imports or reads it
guest_http_uri_locale: 
guest_net_ctl: skipped, the host has no IPv4 address
guest_video_out_color_space: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_hdr: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_high_frame_rate: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_output_mode: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_resolution_status: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
guest_video_out_wqhd_detection: skipped, no display or Vulkan device: SDL_InitSubSystem(VIDEO | GAMECONTROLLER) failed: wayland,x11 not available
video_out_flip_aftergpu: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platform
video_out_flip_backtoback: skipped, no display or Vulkan device: DisplayWindow: Vulkan support is either not configured in SDL or not available in current SDL video driver (offscreen) or platf
Reproduce
git fetch origin 674016744723b1856bd34f01f4fdcd208cd885e7 b611e634f7fc024f0c13e342d96de744448ef1d9
git checkout b611e634f7fc024f0c13e342d96de744448ef1d9 && git merge --no-ff 674016744723b1856bd34f01f4fdcd208cd885e7
git submodule update --init --recursive
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON -DANYPS5_ENABLE_SPIRV_TOOLS=ON
cmake --build build && cmake --build build --target libs
VK_DRIVER_FILES=/nonexistent/icd.json ctest --test-dir build -E '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 12 --output-on-failure
ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^(agc|shader|recompiler|videoout|video_out|guest_video_out|vulkan)|gpu' --timeout 120 --parallel 16 --output-on-failure
# failures are then re-run alone: --timeout 360 --parallel 2; new validation IDs: the test alone, twice, --parallel 1

Automated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs.

@adriadam10
adriadam10 dismissed MarcZX10’s stale review November 6, 2026 10:27

Dismissing a stale review: the requested changes were addressed after it (new head) and the merge queue blocks on it. Please request changes again if anything is still open.

@adriadam10
adriadam10 merged commit 07fae3d into boykopovar:main Nov 6, 2026
16 of 17 checks passed
@adriadam10

Copy link
Copy Markdown
Collaborator

Re-checked on the current head against current main: the merge is clean, serializer format 54 follows main's 53 (50 still rejected, 55 unsupported), the probe and emitter are the code already reviewed, and the Windows build, conventions, and the NVIDIA and AMD CI runs on this head are green; merged.

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

Labels

agc libSceAgc* build docs perf Performance change shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants