engine: SR reconstruction samples the history once when both candidates have one vector
post_m.comp (presets M and L) blends the history along the two most likely of three motion candidates and sampled it once per candidate (five bilinear taps; L also expands each sample to linear light). Where the motion is uniform the two candidates usually have the same vector: the same position, so the same bicubic sample or the same fallback colour (a NaN vector never compares equal, +0 and -0 give the same position). That case now takes the first candidate's value. Every output frame byte-identical (M and L, HDR and LDR; 1280x720 -> 1440p, 1114x626 -> 1080p for the compact tile tier, 1920x1080 -> 1440p for the 15x15 tier, the stress inputs), and so is everything D4R_M_DUMP writes, the history, half history and packed image included. Taking 0.99 times the first sample there instead changes every frame of every input, the reset frames too. Only post_m*.spv / post_l*.spv change. RX 9070 XT, d4r-m 720p -> 1440p, interleaved, reconstruction stage: uniform motion 325 -> 288 us (L 401 -> 354), compact tier at 1114x626 -> 1080p 219 -> 193 (L 275 -> 244); random motion unchanged (377 -> 374, L 404 -> 401). Frame 1570 -> 1541 us (L 2299 -> 2249) on the uniform-motion frames. Signed-off-by: itchyfeetleech <[email protected]>
This commit is contained in:
1 parent
9c9145ac02
commit
8c0635242b
1 file changed
+9
-2
+9
-2
@@ -214,6 +214,9 @@ void main()
|
||||
// the fallback colour is only fetched where the history sample leaves the image or the history was reset:
|
||||
// the value is the same either way, so computing it in the branch saves the fetch on ordinary pixels
|
||||
const bool out1 = q1.x < 0.0 || q1.y < 0.0 || q1.x > size.x || q1.y > size.y || p.reset != 0u;
|
||||
// the second candidate often has the first one's vector (where the motion is uniform): the same position,
|
||||
// so the first one's sample or fallback (a NaN is never equal, and +0 and -0 give the same position)
|
||||
const bool same = all(equal(second.xy, big.xy));
|
||||
#if PRESET_L
|
||||
// linear light: a sample's expansion (when the previous exposure is positive) or the colour texel
|
||||
const vec3 h1 = out1 ? texelFetch(colorTex, colourTexel(near), 0).rgb : historyLinear(q1, p.expoPrev == 0.0 ? 1.0 : p.expoPrev);
|
||||
@@ -221,7 +224,9 @@ void main()
|
||||
if (b2 > 0.0)
|
||||
{
|
||||
const vec2 q2 = centre + second.xy;
|
||||
if (q2.x < 0.0 || q2.y < 0.0 || q2.x > size.x || q2.y > size.y || p.reset != 0u)
|
||||
if (same)
|
||||
h2 = h1;
|
||||
else if (q2.x < 0.0 || q2.y < 0.0 || q2.x > size.x || q2.y > size.y || p.reset != 0u)
|
||||
h2 = out1 ? h1 : texelFetch(colorTex, colourTexel(near), 0).rgb;
|
||||
else h2 = historyLinear(q2, p.expoPrev == 0.0 ? 1.0 : p.expoPrev);
|
||||
}
|
||||
@@ -232,7 +237,9 @@ void main()
|
||||
if (b2 > 0.0)
|
||||
{
|
||||
const vec2 q2 = centre + second.xy;
|
||||
if (q2.x < 0.0 || q2.y < 0.0 || q2.x > size.x || q2.y > size.y || p.reset != 0u)
|
||||
if (same)
|
||||
h2 = h1;
|
||||
else if (q2.x < 0.0 || q2.y < 0.0 || q2.x > size.x || q2.y > size.y || p.reset != 0u)
|
||||
h2 = out1 ? h1 : compress(e2 * texelFetch(colorTex, colourTexel(near), 0).rgb);
|
||||
else h2 = history(q2);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user