rr: add FSR Ray Regeneration, exact RDNA3 inference and motion experiments

Add an experimental FSR Ray Regeneration backend for D3D12 RR requests:
- Convert depth, motion, normals and albedos into AMD denoiser inputs.
- Split and recompose diffuse/specular signals, then run Super Sampling.
- Add stability/detail controls, demodulation guards and halo limiting.
- Handle AMD provider discovery under NVIDIA GPU spoofing.
- Add runtime probes, synthetic reference scenes and per-dispatch profiling.

Add exact gfx11 DLSS-RR inference using f16 cooperative matrices:
- Reproduce FP8 conversions, accumulation and camera reprojection arithmetic.
- Widen model weights and avoid requiring VK_EXT_shader_float8.
- Extend model building, replay tools and descriptor metadata.

Expand motion preprocessing and experimental AW2 native-motion support:
- Add tiled LDS dilation, padded allocation handling and thin-only sky fill.
- Order dilation with input waits and NGX on the selected stream.
- Add jitter-aligned native composition, hybrid routing and wire history repair.
- Add prepared masks, sparse repair and independent motion/repair controls.

Add optional fused R11G11B10 input/output conversion, sampled stage timings
and profile summarization. Extend configuration, packaging, documentation,
FidelityFX headers and CPU/GPU regression coverage.
This commit is contained in:
ayo committed 2026-10-16 04:55:25 -04:00
1 parent 17c1828f97
commit 34e6b0fe71
83 files changed
+11300 -195

No files matched your search

+83
View File
@@ -0,0 +1,83 @@
"""Prepared geometry keeps rendered output and readable temporal state exact."""
import os
from pathlib import Path
import random
import struct
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
@unittest.skipUnless(os.environ.get('D4R_RUN_GPU_TESTS') == '1', 'opt-in GPU test')
class PreparedWireGpuTests(unittest.TestCase):
def test_prepared_matches_reference_with_poisoned_invalid_history(self):
runner = os.environ['D4R_DUMP_RUNNER']
kernel = ROOT/'build/wine-nvcuda/generated'/(os.environ.get('D4R_GPU_ARCH', 'gfx1101')+'.hsaco')
w,h,rw,rh=65,67,21,22
pitch,dp,mp,cp,idp=w*8+16,w*4+12,w*4+20,rw*8+16,rw*4+12
pixels=w*h
rng=random.Random(746)
rgba=lambda: struct.pack('<4e',rng.uniform(.05,1),rng.uniform(.05,1),rng.uniform(.05,1),.5)
current=b''.join(b''.join(rgba() for _ in range(w))+b'\xa5'*16 for _ in range(h))
source=b''.join(struct.pack('<4e',.125,.125,.125,.75)*rw+b'\xa5'*16 for _ in range(rh))
previous=bytearray(b''.join(struct.pack('<4e',.125,.125,.125,.75)*w+b'\xa5'*16 for _ in range(h)))
ages=bytes(rng.choice((0,3,4,15,16,255)) for _ in range(pixels))
previous_depth=bytearray(struct.pack('<f',.5)*pixels)
for i,age in enumerate(ages):
if age==255:
y,x=divmod(i,w)
previous[y*pitch+x*8:y*pitch+x*8+8]=struct.pack('<4H',0x7e00,0x7e00,0x7e00,0x7e00)
previous_depth[i*4:i*4+4]=struct.pack('<f',float('nan'))
for flags in (0,1,2,3):
for jitter in ((0.,0.),(.25,-.25),(-1.,1.)):
for pattern in ('sky','flat','wire'):
with self.subTest(flags=flags,jitter=jitter,pattern=pattern), tempfile.TemporaryDirectory() as tmp:
d=Path(tmp);out=d/'out';out.mkdir()
z=[1. if pattern=='sky' else .5 if pattern=='flat' or x==32 else 1.
for y in range(h) for x in range(w)]
if pattern=='wire':z[10*w+31]=float('nan')
depth=b''.join(struct.pack('<'+'f'*w,*z[y*w:(y+1)*w])+b'\xa5'*12 for y in range(h))
arrays=[current,source,depth,b''.join(bytes(w*4)+b'\xa5'*20 for _ in range(h)),
bytes(previous),ages,bytes(previous_depth),b'\xa5'*(pitch*h),
b'\xa5'*(pixels+64),b'\xa5'*(pixels*4+64),
b''.join(struct.pack('<f',.5)*rw+b'\xa5'*12 for _ in range(rh)),
b'\xa5'*(pitch*h),b'\xa5'*(pixels+64),
b'\xa5'*(((w+31)//32)*h*4+64),b'\xa5'*(pixels+64),
b'\xa5'*(mp*h),bytes(1136),bytes(64)]
addresses=[(i+1)*0x100000000 for i in range(len(arrays))]
def reset():
for i,data in enumerate(arrays):(d/f'alloc-{i}.bin').write_bytes(data)
def launch(name,args,pointers,grid):
(d/'args.bin').write_bytes(args)
manifest=['kernel '+name,'launch '+' '.join(map(str,(*grid,1,256,1,1,0))),f'args {len(args)}']
for i,data in enumerate(arrays):manifest.append(f'alloc {i} {hex(addresses[i])} {len(data)}')
manifest += [f'pointer {offset} {allocation} 0' for offset,allocation in pointers]
(d/'manifest.txt').write_text('\n'.join(manifest)+'\n')
subprocess.run([runner,str(kernel),name,str(d),str(out),'1'],check=True,capture_output=True)
for i in range(len(arrays)):(d/f'alloc-{i}.bin').write_bytes((out/f'alloc-{i}.bin').read_bytes())
args=struct.pack('<17Q5I2fI',*addresses[:12],cp,dp,mp,pitch,idp,w,h,rw,rh,1,*jitter,flags)
base_pointers=[(i*8,i) for i in range(12)]
reset();launch('d4r_wire_history',args,base_pointers,((w+15)//16,(h+15)//16))
expected={i:(out/f'alloc-{i}.bin').read_bytes() for i in (7,8,9,11)}
reset()
native=struct.pack('<8Q4I2f2Q2I',addresses[2],addresses[3],addresses[16],addresses[17],addresses[15],
dp,mp,mp,w,h,rw,rh,*jitter,addresses[13],addresses[14],flags,0)
native_pointers=[(0,2),(8,3),(16,16),(24,17),(32,15),(88,13),(96,14)]
launch('d4r_native_motion_prepare',native,native_pointers,((w+31)//32,(h+31)//32))
prepared=args+struct.pack('<2Q',addresses[12],addresses[14])
launch('d4r_wire_history_preclassified',prepared,base_pointers+[(168,12),(176,14)],((w+15)//16,(h+15)//16))
launch('d4r_wire_history_apply',prepared[:176],base_pointers+[(168,12)],((w+15)//16,(h+15)//16))
actual={i:(out/f'alloc-{i}.bin').read_bytes() for i in range(len(arrays))}
self.assertEqual(actual[0],expected[7])
self.assertEqual(actual[8],expected[8])
for i in (1,2,3,4,5,6,10,16,17):self.assertEqual(actual[i],arrays[i])
for i in range(pixels):
if expected[8][i]!=255:
y,x=divmod(i,w);offset=y*pitch+x*8
self.assertEqual(actual[11][offset:offset+8],expected[11][offset:offset+8])
self.assertEqual(actual[9][i*4:i*4+4],expected[9][i*4:i*4+4])
for y in range(h):self.assertEqual(actual[11][y*pitch+w*8:(y+1)*pitch],b'\xa5'*16)
for i,start in ((8,pixels),(9,pixels*4),(12,pixels),(13,((w+31)//32)*h*4),(14,pixels)):
self.assertEqual(actual[i][start:],b'\xa5'*64)