Expand Windows GPU support, add native FSR RR, and improve SR interop

Add a native D3D12 FSR Ray Regeneration route for gfx1200/gfx1201,
using the game's device and queue with embedded HLSL guide preparation
and output composition. Preserve the vkd3d compatibility route for
RDNA3 and expose explicit route overrides and diagnostics.

Improve Windows runtime compatibility:
- Retry rejected application-ID initialization with a project identity.
- Defer expensive RR backend creation until feature creation.
- Recover from transient submission failures without disabling later frames.
- Add shared-buffer export fallbacks through explicit heaps and a private
  device on the same adapter.
- Safely evict old RR descriptor sets when input views change.
- Treat requested RR presets as hints when a configured model is available.
- Expand SR/RR input formats and handle diffuse/specular hit distances,
  packed normals, depth-stencil resources, and unused FSR guides.

Reduce SR overhead by batching output downloads and format conversion
under one completion wait. Optimize strict M enc2/tube attention with
bounded FP32 accumulation and the original FP64 fallback for ambiguous
rounding cases.

Extend RDNA4 tooling with gfx1200/gfx1201 native FP8 RR model builds,
capability checks, architecture-aware deployment, and experimental K/M
kernel paths. Require matching model and runtime arithmetic families.

Add optional embedded FSR shader optimizations keyed by shader hash and
exact original SPIR-V contents. Preserve reflected metadata and record
optimizer provenance, artifact hashes, and cache identity.

Simplify Windows installation with automatic backend dependency downloads,
download progress and ETA, backed-up absolute OptiScaler library paths,
and recovery from interrupted RR model builds.

Add build-kernels.bat and a kernels-only build matrix for all eleven
registered RDNA targets, with code-object target validation and SHA256
manifests. Expand conversion probes, numerical stress tests, temporal
benchmark tooling, installer/deployment tests, and setup documentation.

Document synthetic regression and timing results, experimental build
options, and remaining RDNA4 hardware validation requirements.
This commit is contained in:
ayo committed 2026-10-17 07:40:34 -04:00
1 parent a617c818de
commit ac4ee6c225
67 files changed
+3147 -326

No files matched your search

+96 -1
View File
@@ -1,5 +1,66 @@
# Native Windows FSR Ray Regeneration
## Native D3D12 route for RDNA4 (2026-10-17)
The source now selects **native D3D12 on gfx1200/gfx1201** when
`[RayReconstruction] Backend = fsr`. AMD's original denoiser receives the game's
real D3D12 device and records on its queue. D3D12 compute shaders perform the
guide conversion and composition on that same device. This route does not load
the vkd3d core, the amdxc shim, or Vulkan; it does not redirect AMD's driver lookup
or apply the RDNA3 compiler workaround.
Guides are copied into shader-readable textures on the same device, including
depth resources that deny shader reads. This retains subrect and guide-format
handling while removing the shared cross-API packet. Composition goes directly
to the internal SR stage, or copies into the game's output without SR. RGBA32F
output widens the completed half image on the GPU. Evaluation remains synchronous:
one completion wait retires the denoiser list before resource reuse and SR; this
is not an asynchronous backend. AMD's denoiser/context may still compile shaders
on first use. No RDNA4 timing or quality improvement has been measured.
RDNA3 keeps the existing vkd3d compatibility route below. Diagnostic environment
`D4R_FSR_RR_DEVICE=auto|native|vkd3d` overrides selection; `auto` is the default.
Native provider/context failures are reported explicitly. An override can select
the compatibility route for diagnosis. Readiness checks require only AMD's
denoiser DLL for native D3D12, and retain the extra payload requirements for vkd3d.
The dependency installer permits omitting that payload only for explicitly
RDNA4-only packages; mixed packages still require it. The native adapter compiles
its embedded conversion shaders with Windows' system `d3dcompiler_47.dll`.
Validation on the available RX 7700 XT (gfx1101):
- Six native conversion tests pass, including WARP, hardware depth, depth-stencil
with denied shader reads, subrects with sentinel padding, invalid-normal sky
passthrough, and exact half-to-float output widening. Each case checks all
4,355 pixels against independent expected values. These tests do **not** execute
AMD's denoiser. Native D3D12 float-to-half stores use their specified truncation;
cross-backend bit equality is not asserted.
- All 22 CTest checks, 13 RR Python tests and 13 installer tests pass.
- The automatic RDNA3 compatibility route passes 24 moving frames with guide and
output format switching, typeless D32S8 depth and exact same-frame widening
(`build/fsr-native-rdna3-compat-formats-v1/`). Another 24 frames pass dynamic
render extents, retained creation-sized resources, SR-bound rejection and SR
output (`build/fsr-native-rdna3-compat-dynamic-sr-v1/`).
- Explicit native selection on gfx1101 without the compatibility DLLs reaches
AMD's provider query and returns `no FSR Ray Regeneration provider for this
device`, as expected. It does not silently switch routes.
- The gfx1200/gfx1201 shims and gfx1201 native conversion probe compile successfully. **Full native
RDNA4 denoising, SR handoff, temporal quality, real games and performance still
require hardware validation.** Existing installed packages were not replaced.
Run the conversion checks with:
```powershell
cmake --build BUILD --target d4r_fsr_rr_native_probe
ctest --test-dir BUILD -R fsr_rr_native --output-on-failure
```
For an RDNA4 synthetic integration run, use a matching target shim/probe and
`tools/windows/test_fsr_rr_ngx.py --device native` with its usual fixture/runtime
arguments. That mode removes compatibility DLLs from the private staged runtime
and verifies the logged route. Include ordinary SR and dynamic-resolution runs
before claiming end-to-end validation.
## Status (2026-10-17): runs on RDNA3 through vkd3d-proton; synthetic validation only
`[RayReconstruction] Backend = fsr` answers a game's DLSS RR request (NGX feature 13) with AMD's FSR Ray
@@ -13,7 +74,7 @@ Windows drivers therefore offer no provider. Linux gets one through vkd3d-proton
fallback and a Proton `amdxc64.dll` shim. The Windows route reproduces that:
1. **vkd3d-proton for Windows** (`tools/windows/build_fsr_payload.py`): vkd3d-proton `3dfc6f07` plus dxil-spirv
PR 307 (`f9f6294f`) and `-Denable_extended_emulation=true`, built with llvm-mingw clang; two libc++ include
PR 307 (`f9f6294f`) and `-Denable_extended_emulation=true`, built with llvm-mingw clang; local Windows
patches in `patches/vkd3d-proton-windows/`. The shipped `d4r\fsr\d4r_vkd3d_core.dll` is `d3d12core.dll`
renamed and loaded by path; `IVKD3DCoreInterface::CreateDevice` is called directly (the IDL has no base
interface, so it is vtable slot 0). `DXIL_SPIRV_CONFIG=wmma_rdna3_workaround` is set in-process.
@@ -133,6 +194,40 @@ Evidence: `build/fsr-perf-720-{baseline-v2,baseline-repeat-v1,unroll-v2,wave32-v
the shipped payload stays `build/fsr-payload-v1`. The two third-party source files edited for experiments
were restored; pre-existing libc++ include fixes remain. Linux denoiser performance parity is still open.
## Local shader optimization payload (2026-10-17)
The payload builder now preserves dxil-spirv's reflected shader metadata when replacing compute shaders.
An earlier replacement path returned before reflecting the required wave size; even a byte-identical
replacement could therefore change the output. Patch `0003-preserve-meta-for-shader-overrides.patch`
moves all replacement to the existing late path.
Optional local optimizations use `--shader-dump DIR --spirv-opt PATH --optimize-shader HASH` (repeat
the final argument for each measured shader). `--shader-variant DIR` adds another exact original
translation, such as the existing NGX rounding-mode variant, without changing its arithmetic settings.
The builder runs `spirv-opt --target-env=vulkan1.3 -O`,
validates each result, and embeds the original and optimized modules in the private core. A replacement
requires both the DXIL shader hash and a byte-for-byte match of the original translation. Different
translator options, resource layouts, or devices that produce different SPIR-V retain their original
translation. No precision-widening flag or change to FP8 conversion/quantization is added.
The source inputs, generated header, optimizer hash, and output hashes are saved in `shader-sources/`
and `fsr-payload.json`. The cache build ID incorporates local patches and the optimization manifest,
so the new core rejects the old payload's compiled shader cache. No external shader folder or global
override environment is needed at runtime. `D4R_FSR_DISABLE_BUILTIN_SHADERS=1` selects an unmodified
control; use a separate cache directory when comparing this control with enabled replacements.
On this RX 7700 XT, applying `-O` to every shader helps some layers and hurts others. The local payload
selects seven measured winners: `09749b7dfc3a7804`, `430ab44dc42ba8b5`, `5bec91d51f1d2038`,
`c7a9797f50bb6526`, `e34e88f998f02da9`, `e7d13b75c921986c`, and `f8459f275005d65e`.
At 1280x720 with two direct signals and NGX's existing arithmetic settings, the probe GPU median is
34.374 -> 32.846 ms (4.4% lower). Full NGX late-frame denoiser medians are 31.58 -> 30.88 ms and
31.81 -> 31.04 ms on a repeat (2.2-2.4% lower). NGX tail RMSE changes by +0.41% / +0.33%, within the
existing run-to-run noise; all seven replacements activate. These are synthetic GPU timings, not game FPS.
This is a modest Windows optimization, not Linux performance parity. Actual loop expansion and
straight-line cooperative-matrix component conversion did not improve the measured result beyond `-O`
and are not included. Full measurements and deployment details are in
`C:\Users\ayo\Desktop\d4r-windows-fsr-results-20261017-0333\SUMMARY-selected-O.md`.
## History: the investigation before the vkd3d route
## Corrected provider descriptor recheck
+10
View File
@@ -114,6 +114,16 @@ compatibility; actual targets follow the selected architecture.
One command compiles all eleven targets without GPU workloads:
For just the K/M kernels, pixel conversion and two device probes, run
`build-kernels.bat` at the repository root after tool setup. It compiles 19
code objects for each target using the same CMake flags as the full build,
checks their actual ELF targets, and writes per-object SHA256 hashes to
`build/windows-kernels/matrix-build.json`. Outputs are separate under
`dist/windows-kernels-<target>`. No ZLUDA, NVIDIA DLL or GPU execution is
required. This does not produce an installable game release.
For the complete host diagnostics and kernels:
```powershell
.\scripts\windows\build-windows-gpu-matrix.ps1 -ZludaRoot "$PWD\dist\zluda-windows-final"
```
+2
View File
@@ -1,5 +1,7 @@
# Windows K performance work
Latest K/M follow-up: [Windows SR optimization](windows-sr-optimization.md) records output batching, bounded strict M attention, the local v20 package, and exact final-loader checks. Linux parity remains unverified.
## Current optimization pass: strict DS exchange, 1080p and 1440p (2026-10-17)
After the position-layer barrier fix, the explicit gfx11 DS cross-half exchange passes the strict gate.
+84
View File
@@ -0,0 +1,84 @@
# RDNA 4 optimization candidates (2026-10-17)
These changes expose target-specific paths for gfx1200 and gfx1201. The available
GPU is an RX 7700 XT (gfx1101), so **no RDNA 4 speedup or output equivalence has
been measured**. Compilation and instruction checks do not establish either.
Existing packages and games were not updated.
## Paths
- **K:** `build-native-k-experiment.ps1 -F16Wmma` exposes the existing gfx12 native
FP16-accumulator WMMA implementation. It requires the strict K baseline, rejects
gfx11 and incompatible packed-accumulator storage, and records the selection in
candidate metadata. It remains experimental pending layer and temporal-frame
equality checks. The default kernel arithmetic is unchanged.
- **M:** `build-native-m-fp8.ps1 -GpuArch gfx1200|gfx1201` builds the existing native
FP8 path for either target, including optional hardware packing and token lanes.
The ISA gate requires FP8 WMMA instructions. The separate strict FP16 candidate
builder now supports both gfx12 targets with native lane exchange; gfx11-only
LDS/DS flags are excluded. Neither candidate is selected automatically.
- **DLSS RR D/E:** the Windows model builder now accepts `--gpu-arch gfx1200|gfx1201`.
It uses the existing native FP8 cooperative-matrix shaders, omits gfx11's widened
weight copies and records `arithmetic gfx12`. Every native network shader must
declare Float8EXT, Float8CooperativeMatrixEXT and CooperativeMatrixKHR.
The Windows Vulkan bridge enables and requires the float8 extension/features on
gfx12. Model deployment requires matching runtime `gpu-target.json`; the bridge
rejects a model from the other arithmetic family. Exact conversion decorations
remain enabled; relaxed arithmetic is not introduced. The NGX regression helper
accepts the same `--gpu-arch` to select its format module and native directory.
- **FSR RR:** gfx12 no longer receives `wmma_rdna3_workaround` by default. The local
dxil-spirv implementation applies gfx11-specific column mapping and FP16 RTZ
under that setting. gfx11 retains it. Explicit process overrides survive; lookup
uses the Windows environment rather than the C runtime's stale snapshot.
This removes an inappropriate target setting; native FSR execution and its
performance still depend on the target Vulkan driver's capabilities.
A subsequent change now selects direct D3D12 on gfx12 by default, bypassing
this compatibility route entirely. See [native route status](windows-fsr-rr.md).
AMD documents RDNA 4's native FP8 matrix support in its
[matrix-core guide](https://gpuopen.com/learn/using_matrix_core_amd_rdna4/).
That hardware capability does not establish Windows Vulkan driver support.
## Build examples
Use a fresh ignored output directory for each candidate. Replace DLL paths with
the locally supplied pinned binaries. Do not install candidates before validating
their outputs and paired timings on the target GPU.
```powershell
scripts/windows/build-native-k-experiment.ps1 -GpuArch gfx1201 -Layer enc1 -F16Wmma -OutputDirectory build/my-k-gfx1201
scripts/windows/build-native-m-fp8.ps1 -GpuArch gfx1201 -DlssDll PATH/nvngx_dlss.dll -HardwarePacking -TokenLanes -OutputDirectory build/my-m-gfx1201
python tools/windows/build_rr_model.py --gpu-arch gfx1201 --preset D --dll PATH/nvngx_dlssd.dll --output build/my-rr-d-gfx1201
```
Use gfx1200 consistently for that target. Build the shim/probe with the matching
`D4R_GPU_ARCH`. Deployment can stage a verified private model with
`deploy_rr_model.py --model MODEL --runtime RUNTIME`; selection still requires
`--enable` or an explicit model path. No relaxed model is built by this recipe.
## Checks performed
- K enc1 FP16 WMMA candidates compile for both targets. All eleven baseline K and
five baseline M objects additionally compile for gfx1201.
- All five M native FP8 modules compile for both targets, with native WMMA and
hardware packing instructions verified by the builder. Strict FP16 M candidate
sets also compile for both targets.
- Complete D/gfx1201 and E/gfx1200 RR models compile. All eleven native network
stages per model pass the SPIR-V native FP8 capability gate.
- The shim and standalone RR runner build for gfx1201; the gfx1101 shim, probe and
runner also rebuild successfully.
- 13 RR Python tests and 16 existing CTest checks pass on gfx1101. Some legacy
CTest names contain gfx1201/gfx12; these runs used the configured gfx1101 target.
- Native DLSS RR passes six synthetic camera/reset frames against the existing
reference, byte-for-byte. Evidence: `build/rdna4-opt-rr-rdna3-regression-v3/`.
- FSR RR passes 24 moving-camera synthetic frames with exact same-frame output
widening. Tail RMSE is approximately 0.1066 versus noisy input 0.4862. The log
confirms gfx1101 still selects `wmma_rdna3_workaround`. Evidence:
`build/rdna4-opt-fsr-rdna3-regression-v3/`.
The additional NGX `--contracts --without-sr` run fails at
`RR advertised on unsupported WARP adapter`, before inference. That capability
contract is unresolved; the successful six-frame run does not clear it.
Candidate artifacts remain under `build/rdna4-opt-*`. RDNA 4 layer/frame equality,
real-game quality, GPU timings and paired performance comparisons remain open.
+63
View File
@@ -0,0 +1,63 @@
# Windows K/M optimization (2026-10-17)
The local gfx1101 v20 package reduces SR interop overhead and the cost of strict M attention. Linux performance parity remains unverified. Measurements below are synthetic CPU interop times, including NGX, copies and synchronization; they are not GPU kernel times or game frame times.
## Changes
- The output CUDA array download and optional HIP format conversion now share one ordered legacy-stream batch. One whole-context completion precedes the D3D12 output signal. NGX's all-stream completion still precedes the batch. Output diagnostics insert their own completion before inspecting the canonical image.
- M enc2 and tube layers first sum their 16 FP16 products in FP32. Each product is exact in FP32. An error bound larger than gamma(16), including magnitude-sum error, determines whether the result is safely inside one FP16 rounding interval. Ambiguous intervals, cancellation, overflow and nonfinite cases retain the original sequential FP64 dot. Quantization, weights, rounding and tensor layouts are unchanged. Other M layers retain FP64 because the candidate regressed their replay timings.
- The local v20 package enables the existing `BatchInputCopies` setting. The source INI and parser fallback remain false; older installations retain their selection. This local package targets the tested RX 7700 XT only.
- The standalone engine build script now requests Release. This did not improve measured K frame timing and is not counted as a speedup.
## Final package checks
Final candidates use the packaged loader, rebuilt optimized shim and the actual CMake-built M objects. Controls use v19's shim and native objects. Runs alternate control/candidate/candidate/control, with 24 temporal frames per process and four warmup frames excluded from timing. All output hashes match exactly across all four processes. All frames pass the harness's finite-output check.
K render sizes are 1280x720 and 1706x960; M render sizes are 960x540 and 1280x720.
| Preset and mode | Output | v19 CPU interop median | v20 CPU interop median | Reduction |
|---|---|---:|---:|---:|
| K Quality | 1920x1080 | 3.190 ms | 3.063 ms | 4.0% |
| K Quality | 2560x1440 | 4.651 ms | 4.606 ms | 1.0% |
| M Performance | 1920x1080 | 11.107 ms | 10.251 ms | 7.7% |
| M Performance | 2560x1440 | 18.372 ms | 17.186 ms | 6.5% |
The small K 1440p difference is within observed run variation; do not treat it as a demonstrated GPU speedup. Earlier isolated input-batching runs measured 3.187 -> 3.092 ms and 4.690 -> 4.496 ms, with 128 exact frames per size. CPU load and synchronization make these timings variable.
Packed-format checks add 64 exact K frames per profile at 1280x720. R11G11B10 output measured 2.705 -> 2.566 ms, and BGRA8 output measured 2.726 -> 2.341 ms. Both native packed bytes and decoded half-image bytes are compared. These exercise the deferred output conversion as well as input batching. These format-specific timings must not be projected to other formats or games.
Final package evidence:
- `build/sr-opt-final-K-1920x1080-v1/summary.json`
- `build/sr-opt-final-K-2560x1440-v1/summary.json`
- `build/sr-opt-final-M-1920x1080-v1/summary.json`
- `build/sr-opt-final-M-2560x1440-v1/summary.json`
- `build/sr-opt-final-K-packed-v1/summary.json`
- `build/sr-opt-final-K-unorm-v1/summary.json`
The final package passes 512 exact temporal frames across these cases. This is same-GPU regression evidence, not NVIDIA reference-quality validation. Other GPUs, M Quality, real games and RR behavior were not validated in this pass.
## Numerical and build checks
`build/m-opt-pv-stress-v2/summary.json` records 262,144 GPU dots with zero differing FP16 bits against the original FP64 sum. Inputs include signed products over the finite FP16 exponent range, cancellation, every finite FP16 magnitude, rounding midpoints and tiny signed perturbations. All five synthetic M layer replays also match every allocation byte. Only enc2/tube improved sufficiently to select the bounded path.
Reproduce the dot check:
```powershell
$sdk = '.tools/therock-10.2.0a20260929/_rocm_sdk_core'
& "$sdk/lib/llvm/bin/clang++.exe" -x hip -std=c++17 --offload-arch=gfx1101 `
--offload-device-only --no-gpu-bundle-output -mno-wavefrontsize64 -nogpuinc -nogpulib `
-O3 -DD4R_DEVICE_ONLY_MINIMAL tools/windows/exact_pv_probe.hip -o build/exact_pv_probe.hsaco
python tools/windows/test_exact_pv.py --probe build/windows-rdna4-therock-gfx1101/d4r_native_replay_probe.exe `
--hip-root $sdk --module build/exact_pv_probe.hsaco --output-dir build/exact-pv-fresh-run
```
`scripts/windows/build-native-m-experiment.ps1` builds strict M candidates without installing them. `-ReferencePv` restores the FP64-only control. K's experimental builder also accepts `-LaneExchange native`; it matched the tested 1080p case but provided no gain. K DS exchange remains selected. M LDS/DS flag comparisons provided no gain. Release versus unoptimized standalone K runners matched all five frame products but showed no timing improvement. Standalone K remains roughly 1.85 ms at 1080p and 2.91 ms at 1440p, above the reported Linux targets.
`build/sr-opt-player-config-v1/summary.json` passes the INI/environment and loader-selection checks. Both relevant CMake builds pass. Python compilation and PowerShell parsing pass for the changed tools.
The texture builder additionally accepts M folded post variants and an experimental `--wave64` / `-Wave64` option. It verifies the emitted wave64 target feature and retains strict arithmetic. Such objects contain NVIDIA-derived code and stay in ignored local build directories; they are excluded from v20.
The tested M HDR/render-motion post variant passes another 96 exact frames per resolution (`build/m-post-wave64-{1920x1080,2560x1440}-v1/`). Its CPU interop difference is small and varies between runs; it is not promoted. Enc0/dec0/post/downsample still use the translated texture path in v20. Matching Linux's broader native texture coverage and reducing cross-API overhead remain open work.
Accepted transient raw readbacks were hashed before pruning; summaries, logs, hashes and first-frame previews remain. Inventories are `build/sr-opt-readback-cleanup-v1.json` and `build/sr-opt-readback-cleanup-v2.json`. Earlier work and user data were not pruned.