feat: add d4r inference engines and Windows parity tooling

Add native K/M/RR inference engines, HIP kernels, replay and validation
harnesses, and Windows DLSS setup and runtime support. Include GPU
profiling tools, build and packaging scripts, platform integration
patches, and implementation documentation.
This commit is contained in:
ayo committed 2026-10-16 08:54:47 -04:00
1 parent 25493b3198
commit 7c5d3c9157
430 files changed
+76191

No files matched your search

+298
View File
@@ -0,0 +1,298 @@
#version 460
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require
#extension GL_EXT_shader_16bit_storage : require
// Ray Reconstruction hkpn output stage, preset E (no diamond-wallaby branch).
// One workgroup per 16x16 output tile. Stage 1 stages the render-space neighbourhood of
// the tile into shared memory (colour log, per-texel weights, anisotropy); stage 2 gathers
// a 5x5 elliptical kernel per output pixel and writes the two output surfaces.
// Parameter block (binding 0) holds NVIDIA's kernel argument block; word index = byte / 4.
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
layout(std430, binding = 0) readonly buffer Params { uint P[]; };
layout(std430, binding = 2) buffer Arena { uint A[]; };
layout(binding = 3) uniform sampler2D colourTex; // arg 176, 640x360 rgba16f
layout(binding = 5) uniform sampler2D exposureTex; // arg 200, 1x1 rgba16f
layout(binding = 8) uniform sampler2D albedoA; // arg 280, 640x360 rgba8unorm
layout(binding = 9) uniform sampler2D albedoB; // arg 288, 640x360 rgba8unorm
layout(binding = 11) uniform sampler2D decTex; // arg 448, 640x384 rgba16f
layout(rgba16f, binding = 12) uniform writeonly image2D outLog; // arg 224
layout(rgba16f, binding = 13) uniform writeonly image2D outLin; // arg 240
#define F_LOG2E uintBitsToFloat(0x3FB8AA3Bu)
#define F_2LOG2E uintBitsToFloat(0x4038AA3Bu)
#define F_LOG10_2 uintBitsToFloat(0x3E9A209Bu)
#define F_0_36 uintBitsToFloat(0x3EB851ECu)
#define F_100 uintBitsToFloat(0x42C80000u)
#define F_1E4 uintBitsToFloat(0x38D1B717u)
#define F_0_005 uintBitsToFloat(0x3BA3D70Au)
#define F_0_1 uintBitsToFloat(0x3DCCCCCDu)
#define F_1_7 uintBitsToFloat(0x3FD9999Au)
#define F_0_17 uintBitsToFloat(0x3E2E147Bu)
#define F_0_95 uintBitsToFloat(0x3F733333u)
#define F_0_6 uintBitsToFloat(0x3F19999Au)
#define F_9 uintBitsToFloat(0x41102CB4u)
// shared tile: 21 entries per row, up to 21x21 entries (render scale <= 1)
#define TILE_STRIDE 21
// binary16 numbers, stored as such: half the shared-memory traffic of the 5x5 gather
shared f16vec4 tLog[TILE_STRIDE * TILE_STRIDE]; // (L_R, L_G, L_B, alpha = 0) log-domain colour
shared f16vec4 tSig[TILE_STRIDE * TILE_STRIDE]; // (s0, s1, s2, s3) sigmoid of arena bytes 0..3
shared vec4 tAn[TILE_STRIDE * TILE_STRIDE]; // (p0, p1, p2, p3) anisotropy parameters
float pf(uint idx) { return uintBitsToFloat(P[idx]); }
// e4m3 byte -> float (exact); e4m3fn NaN for 0x7F/0xFF.
float e4m3(uint b) {
uint e = (b >> 3u) & 15u;
uint m = b & 7u;
if (e == 15u && m == 7u) return uintBitsToFloat(0x7FC00000u);
float v = (e == 0u) ? float(m) * uintBitsToFloat(0x3B000000u)
: (1.0 + float(m) * 0.125) * exp2(float(e) - 7.0);
return ((b & 128u) != 0u) ? -v : v;
}
// round to nearest even binary16, returned as f32: the hardware conversion (RNE), kept from being folded back to x by
// OR-ing an opaque zero into its bits (RADV folds a register-only f32 -> f16 -> f32)
// Beyond the binary16 range NVIDIA's arithmetic keeps a finite rounded value: that case takes the explicit rounding.
uint16_t zero16;
float f16rnSlow(float x) {
if (x == 0.0 || isnan(x) || isinf(x)) return x;
int e;
frexp(x, e);
int ee = max(e - 11, -24);
float q = uintBitsToFloat(uint(ee + 127) << 23);
return roundEven(x / q) * q;
}
float f16rn(float x) {
if (abs(x) >= 65504.0) return f16rnSlow(x);
return float(uint16BitsToFloat16(float16BitsToUint16(float16_t(x)) | zero16));
}
// Sigmoid as evaluated in binary16 on this lowering: r = f16(2^(-x*log2e)), den = f16(1+r),
// s = f16(1/den), with one Newton step for small s and the observed fix-ups of r.
float sig16(float e) {
float x = f16rn(e);
float r = f16rn(exp2(-x * F_LOG2E));
uint hb = uint(float16BitsToUint16(float16_t(r)));
if (hb == 0x1F79u || hb == 0x25CFu) {
r = f16rn(r - 0.0009765625);
} else if (hb == 0xC13Bu) {
r = f16rn(r + 0.00006103515625);
} else if (hb == 0xC1EFu) {
r = f16rn(r + 0.000030517578125);
}
float d32 = f16rn(1.0 + r);
float rc = 1.0 / d32;
float s16 = f16rn(rc);
uint sb = uint(float16BitsToUint16(float16_t(s16))) & 0x7FFFu;
if (sb != 0u && sb < 0x8Fu) {
float ee = fma(-d32, s16, 1.0);
s16 = f16rn(fma(rc, ee, s16));
}
return s16;
}
// tanh as evaluated: polynomial for small |x|, exponential form otherwise.
float tanhApprox(float x) {
float ax = abs(x);
float x2 = x * x;
float q = fma(uintBitsToFloat(0x3C80F082u), x2, uintBitsToFloat(0xBD563CAEu));
q = fma(q, x2, uintBitsToFloat(0x3E085941u));
q = fma(q, x2, uintBitsToFloat(0xBEAAA9EDu));
q = fma(q, x2, 0.0);
float small = fma(q, x, x);
float ex = exp2(ax * F_2LOG2E);
float big = fma(1.0 / (ex + 1.0), -2.0, 1.0);
if (ax >= F_9) big = 1.0;
float bigSigned = uintBitsToFloat((floatBitsToUint(x) & 0x80000000u) | floatBitsToUint(big));
return (ax >= F_0_6) ? bigSigned : small;
}
// round half away from zero
int roundAway(float v) {
return int(trunc(v + ((v < 0.0) ? -0.5 : 0.5)));
}
void main() {
zero16 = uint16_t(P[0] >> 24u); // the output width is below 2^24
// ---- parameters (byte offsets / 4) ----
uint outW = P[0];
uint outH = P[1];
float sx = pf(6u); // 24: render/out scale x
float sy = pf(7u); // 28
float ox = pf(10u); // 40: jitter offset x
float oy = pf(11u); // 44
float expScale = pf(37u); // 148
uint decMaxX = P[14] - 1u; // 56: dec0 width
uint decMaxY = P[15] - 1u; // 60: dec0 height
uint colMaxX = P[35]; // 140: colour/albedo max x
uint colMaxY = P[36]; // 144: colour/albedo max y
uint arenaBase = P[64]; // 256: arena offset
uint arenaPitch = P[4]; // 16: render width (640)
// ---- tile origin / size in render space ----
uvec2 wg = gl_WorkGroupID.xy;
float tileX = ox + fma(float(wg.x * 16u) + 0.5, sx, -0.5);
float tileY = oy + fma(float(wg.y * 16u) + 0.5, sy, -0.5);
int c0 = int(floor(tileX)) - 2;
int r0 = int(floor(tileY)) - 2;
int tw = int(ceil(16.0 * sx)) + 5;
int th = int(ceil(16.0 * sy)) + 5;
// ---- stage 1: tile load ----
uint total = uint(tw * th);
for (uint idx = gl_LocalInvocationIndex; idx < total; idx += 256u) {
int col = int(idx) % tw;
int row = int(idx) / tw;
int ix = clamp(c0 + col, 0, int(decMaxX));
int iy = clamp(r0 + row, 0, int(decMaxY));
vec3 d = texelFetch(decTex, ivec2(ix, iy), 0).rgb;
int ax = min(ix, int(colMaxX));
int ay = min(iy, int(colMaxY));
vec3 alb = texelFetch(albedoA, ivec2(ax, ay), 0).rgb
+ texelFetch(albedoB, ivec2(ax, ay), 0).rgb;
float albSum = (alb.r + alb.g) + alb.b;
if (albSum != 0.0) {
d.r *= max(alb.r, F_0_005);
d.g *= max(alb.g, F_0_005);
d.b *= max(alb.b, F_0_005);
}
vec3 lg;
lg.r = f16rn(F_0_36 * (log2(max(fma(d.r, F_100, 1.0), F_1E4)) * F_LOG10_2));
lg.g = f16rn(F_0_36 * (log2(max(fma(d.g, F_100, 1.0), F_1E4)) * F_LOG10_2));
lg.b = f16rn(F_0_36 * (log2(max(fma(d.b, F_100, 1.0), F_1E4)) * F_LOG10_2));
uint wordIdx = (arenaBase >> 2u) + uint(arenaPitch * uint(iy) + uint(ix)) * 2u;
uint lo = A[wordIdx];
uint hi = A[wordIdx + 1u];
vec4 sg = vec4(sig16(e4m3(lo & 0xFFu)),
sig16(e4m3((lo >> 8u) & 0xFFu)),
sig16(e4m3((lo >> 16u) & 0xFFu)),
sig16(e4m3(lo >> 24u)));
vec4 an = vec4(e4m3(hi & 0xFFu),
e4m3((hi >> 8u) & 0xFFu),
e4m3((hi >> 16u) & 0xFFu),
e4m3(hi >> 24u));
uint se = uint(row * TILE_STRIDE + col);
tLog[se] = f16vec4(lg, 0.0);
tSig[se] = f16vec4(sg);
tAn[se] = an;
}
barrier();
// ---- stage 2: per output pixel ----
uvec2 pix = gl_GlobalInvocationID.xy;
if (pix.x >= outW || pix.y >= outH) return;
float expo = texelFetch(exposureTex, ivec2(0, 0), 0).r;
float e41 = ((expo == 0.0) ? 1.0 : expo) * expScale;
float fx = (float(pix.x) + 0.5) * sx;
float fy = (float(pix.y) + 0.5) * sy;
float cx = fx + ox;
float cy = fy + oy;
// colour fetch: log of exposure-scaled colour at the nearest render texel
int ux = clamp(roundAway((fx - 0.5) + ox), 0, int(colMaxX));
int uy = clamp(roundAway((fy - 0.5) + oy), 0, int(colMaxY));
vec3 col = texelFetch(colourTex, ivec2(ux, uy), 0).rgb;
vec3 gcol;
gcol.r = F_0_36 * (log2(max(fma(col.r * e41, F_100, 1.0), F_1E4)) * F_LOG10_2);
gcol.g = F_0_36 * (log2(max(fma(col.g * e41, F_100, 1.0), F_1E4)) * F_LOG10_2);
gcol.b = F_0_36 * (log2(max(fma(col.b * e41, F_100, 1.0), F_1E4)) * F_LOG10_2);
// centre entry, anisotropy
float flx = floor(cx);
float fly = floor(cy);
int ix0 = int(flx) - c0;
int iy0 = int(fly) - r0;
float dx0 = (flx + 0.5) - cx;
float dy0 = (fly + 0.5) - cy;
float ks = (sy >= 0.5) ? 1.0 : (0.5 / sy);
vec4 an = tAn[iy0 * TILE_STRIDE + ix0];
float sa = fma(1.0 / (1.0 + exp2(-F_LOG2E * an.x)), F_1_7, F_0_17);
float sb = fma(1.0 / (1.0 + exp2(-F_LOG2E * an.y)), F_1_7, F_0_17);
float rho = F_0_95 * tanhApprox(an.z);
float sa2 = sa * sa;
float sb2 = sb * sb;
float denom = (sa2 * sb2) * (1.0 - rho * rho);
float invDenom = -(1.0 / denom);
float cross2 = rho * (2.0 * sqrt(sa2 * sb2));
// 5x5 gather
float sumw = 0.0;
vec3 accL = vec3(0.0);
vec4 accS = vec4(0.0);
for (int c = -2; c <= 2; c++) {
for (int r = -2; r <= 2; r++) {
float dx = ks * (dx0 + float(c));
float dy = ks * (dy0 + float(r));
uint se = uint((iy0 + r) * TILE_STRIDE + (ix0 + c));
precise float t_c = (cross2 * dx) * dy;
precise float t_b = dx * (sb2 * dx);
precise float t_a = dy * (sa2 * dy);
precise float num = (t_c - t_b) - t_a;
precise float Q = invDenom * num;
float w = exp2((Q * -0.5) * F_LOG2E);
sumw += w;
vec4 lv = vec4(tLog[se]);
vec4 sv = vec4(tSig[se]);
accL = fma(vec3(w), lv.rgb, accL);
accS = fma(vec4(w), sv, accS);
}
}
float inv = 1.0 / sumw;
vec3 Lm = accL * inv;
float S0 = accS.x * inv;
float S1 = accS.y * inv;
float S2 = accS.z * inv;
// blend weight
float q = F_0_1 / (sx * sy);
float t1 = sumw * q;
float t2 = S0 * t1;
float t3 = (sx * sy) * t2;
float t4 = 4.0 * t3;
float t5 = (sy < 0.5) ? t4 : t2;
float wgt = (t5 < 0.0) ? 0.0 : ((t5 > 1.0) ? 1.0 : t5);
float fA = fma(1.0 - S1, wgt, S1);
float fB = fma(1.0 - S2, wgt, S2);
// surface 224 (E): fA * D + (1 - fA) * gcol; D = Lm (f16 tile log channels),
// gcol = log of the exposure-scaled colour texel (PTX linear texel fetch path); D.a = 0 so aA = 1 - fA
vec3 cA = fma(Lm, vec3(fA), gcol * (1.0 - fA));
float aA = 1.0 - fA;
float sumA = cA.r + cA.g + cA.b + aA;
if (isnan(sumA) || isinf(sumA)) {
cA = Lm;
aA = 0.0;
}
imageStore(outLog, ivec2(pix), vec4(f16rn(cA.r), f16rn(cA.g), f16rn(cA.b), f16rn(aA)));
// surface 240 (E, PTX BB0_83): {R,G,B,1} of lin = (10^(clamp(c)/0.36)-1)/100/e41,
// c = fma(Lm, fB, gcol*(1-fB)); c = Lm when the sum is not finite; stored RNE f16
vec3 cB = fma(Lm, vec3(fB), gcol * (1.0 - fB));
float sumB = cB.r + cB.g + cB.b;
if (isnan(sumB) || isinf(sumB)) cB = Lm;
cB = clamp(cB, vec3(F_1E4), vec3(3.0));
// PTX divides by constants and takes lg2(10) with the hardware approximations at run time; keep the
// constants opaque so the compiler cannot fold them with different rounding.
uint zero = P[0] >> 24u;
float c036 = uintBitsToFloat(0x3EB851ECu | zero);
float c100 = uintBitsToFloat(0x42C80000u | zero);
float lg10 = log2(uintBitsToFloat(0x41200000u | zero));
float rc036 = 1.0 / c036;
float rc100 = 1.0 / c100;
float rce41 = 1.0 / e41;
precise vec3 lin = (exp2((cB * rc036) * lg10) - 1.0) * rc100 * rce41;
imageStore(outLin, ivec2(pix), vec4(float(float16_t(lin.r)), float(float16_t(lin.g)), float(float16_t(lin.b)), 1.0));
}