Engine: native presets K and M in the D3D12 shim, wider game coverage
A standalone Vulkan inference engine (engine/) for DLSS presets K and M that runs from weights extracted from the user's own nvngx_dlss.dll, with d4r's own input, network and reconstruction shaders or the native HIP network layers, recorded into the game's command list by the shim. Opt-in ([Engine] Enabled / D4R_ENGINE=1); anything uncovered falls back to the CUDA/ZLUDA path with the reason logged. Byte-identical to NGX's CUDA backend under the phase-capable reference (1706x960 -> 2560x1440, native HIP network, eleven frames, RX 9070 XT): - K render- and display-resolution motion vectors, HDR and LDR - K game-supplied exposure and automatic exposure with any pre-exposure and exposure scale (one residual: effective exposure exactly 2 or 4) - K and M with the DLSS indicator's inverted-axis parameters - M with any exposure settings (NGX ignores them for M) K packages need the current compile_k.py (marker D4RO0003). Also: HIP shared buffers are pooled across feature recreation (ROCm leaks destroyed imports), hipnet.bin must match the preset, M-only games do not load the K model, install_d4r_runtime.sh stages k, k-ldr, m, m-ldr with hip/, the activation table has a generator (gen_activation_m.py), and package_release.sh can bundle the engine's shaders (never its weights). Signed-off-by: woutermans <[email protected]>
This commit is contained in:
1 parent
16cfc1f063
commit
e0d1549a21
82 files changed
+13335
-96
No files matched your search
@@ -0,0 +1,44 @@
|
||||
# K input kernel (hiluma_engine_input_depthinv_mvlo_hdr_v2_rel) - reverse-engineering notes
|
||||
P = parameter block (248 bytes). Textures: 176 history colour (Y,Co,Cg,a compressed; linear), 184 motion, 192 depth, 200/208/216 exposure (1x1).
|
||||
Filter modes are NGX's own (cuTexObjectCreate): 168, 176 and 224 linear, the others point; all clamped, normalized coordinates.
|
||||
200 = current exposure, 208 = previous exposure, 216 = current exposure.
|
||||
## entry
|
||||
a = tex208 (0 -> 1), b = tex200 (0 -> 1), c = tex216 (0 -> 1)
|
||||
f152 = P144*a ; f158 = P144*b ; f1 = P156*f158 (0 -> 1) ; f2 = (P148*c)/f158 ; f3 = f158/f152
|
||||
One thread per 2x2-pixel sub-block: gx = 16*ctaid.x + tid.x, gy = 16*ctaid.y + tid.y ;
|
||||
X = 4*(gx>>2) + 2*(tid.x&1), Y = 4*gy + (tid.x&2) -> token (gx>>2, gy), sub index = (tid.x&1) + 2*((tid.x>>1)&1)
|
||||
f4 = X+.5, f5 = Y+.5 ; (ix,iy) = roundHalfAway((f4,f5)*P40 - .5 + P24)
|
||||
depth (tex192) at (ix,iy) and the four diagonal neighbours, each clamped as v > 0 ? min(P88 + v, P88 + P96) : P88
|
||||
same dilation rule as the output kernel -> (dx,dy) ; mv = texelFetch(tex184, clampfn(P104 + (ix+dx,iy+dy))), max = P104 + P112
|
||||
q = (f4,f5) + P8*(mv + P16) ; hist = textureLod(tex176, q*P120) (f22..f25) ; P136 loaded (f201,f202)
|
||||
## the four pixels j of the sub-block: (X,Y), (X+1,Y), (X,Y+1), (X+1,Y+1)
|
||||
each: nearest render texel, dilated motion mv_j (as above), q_j = pixel + .5 + P8*(mv_j + P16), hist_j = textureLod(tex176, q_j*P120)
|
||||
lin_j = hist_j.rgb * expandK(hist_j.r) * f3 -> shared W[j][tid.y*16+tid.x] (3 floats)
|
||||
local[j] = ((token centre in px) + P8*(mv_j + P16)) * P128, token centre = 4*(X/4 + .5), 4*(Y/4 + .5)
|
||||
invalid |= reset(P32 u8) || q_j*P136 outside [0,1] (accumulated over the four pixels: p3)
|
||||
r32 = 1 - subY ; r44 = r32 + X ; r45 = subX + Y
|
||||
## BB12: current colour statistics, 3x3 render texels around the sub-block centre
|
||||
(cx,cy) = roundHalfAway((X+1, Y+1)*P40 - .5 + P24) ; colour tex168, clamp origin P72, max P72+P80 ; f481 = P160
|
||||
per tap (order (-1,-1),(0,-1),(1,-1),(-1,0),(0,0),(1,0),(-1,1),(0,1),(1,1)): rgb = f1*max(c,0) ; Y,Co,Cg as in the output kernel
|
||||
wA = max(1/(Y+1), P160) ; S += wA*(Y,Co,Cg)
|
||||
t = log2(12*max(Y,0)+1)*.6931472 / (max(Y,0)+1e-6) ; L = (Y,Co,Cg)*t ; running min and max of L over the taps
|
||||
after the 9 taps: m = S/9 ; avg = m / max(1 - m.Y, P160) ; A = avg * t(avg.Y) (t as above: log compression)
|
||||
halfr = .5*(max - min) ; den = 8*(max - min) + 1 (per channel)
|
||||
for each j: Hl = lin_j * t(lin_j.Y) ; d = max(|A - Hl| - halfr, 0)/den ; e_j = min(2*d.Y + .5*d.Co + .5*d.Cg, 1)
|
||||
mismatch = .25 * sum_j e_j
|
||||
representative pixel of the sub-block: offset (1 - subY, subX), i.e. j' = 2*subX + (1 - subY)
|
||||
Yc = exposed luma (f1 * (.25R + .5G + .25B) of max(c,0)) of the colour texel nearest to that pixel
|
||||
feat = textureLod(tex224 (previous token feature, 4 ch), local[j'])
|
||||
if invalid: mismatch = 0, Yh = Yc, feat = 0 else Yh = lin_j'.Y
|
||||
featSum = sum of feat over the token's four threads (shfl bfly 3, then 1)
|
||||
tc = (f2*Yc) * max(1/(f2*Yc+1), P160) ; th = (f2*Yh) * max(1/(f2*Yh+1), P160)
|
||||
then a switch on the sub index
|
||||
## output: 4 f16 per sub-block into buffer P240 at ((tokY*P64 + tokX)*16 + sub*4) (16 channels per token: the network input)
|
||||
G(x) = x > .0031308 ? 1.055*x^(1/2.4) - .055 : 12.92*x (sRGB transfer)
|
||||
out0 = G(sat(tc)) ; out1 = G(sat(th)) ; out2 = .25*featSum[sub] (non-finite -> 0) ; out3 = mismatch (non-finite -> 0)
|
||||
No barrier: the shared array is only per-thread scratch.
|
||||
|
||||
## display-resolution motion (frame flag 4, `D4RO0003`)
|
||||
Vectors are output-sized and already in output pixels (scale 1 by default). Each output pixel j of a token uses its own
|
||||
vector: mv_j = mvScale*(tex184(clamp(X+j)) + mvOffs), with no diagonal depth dilation and no render-texel lookup.
|
||||
The rest (q_j, history fetch, local terms) is unchanged. The package must carry `D4RO0003`.
|
||||
Reference in new issue
Block a user