mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 16:19:19 +02:00
Some renaming
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
# This file is part of the FidelityFX SDK.
|
||||
#
|
||||
# Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files(the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions :
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
set(FRAMEINTERPOLATION_BASE_ARGS
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_UPSAMPLE_SAMPLERS_USE_DATA_HALF=0
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_ACCUMULATE_SAMPLERS_USE_DATA_HALF=0
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_REPROJECT_SAMPLERS_USE_DATA_HALF=1
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_POSTPROCESSLOCKSTATUS_SAMPLERS_USE_DATA_HALF=0
|
||||
# Upsample uses lanczos approximation
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_UPSAMPLE_USE_LANCZOS_TYPE=2
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(FRAMEINTERPOLATION_PERMUTATION_ARGS
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_LOW_RES_MOTION_VECTORS={0,1}
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_JITTER_MOTION_VECTORS={0,1}
|
||||
-DFFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH={0,1})
|
||||
|
||||
set(FRAMEINTERPOLATION_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/frameinterpolation")
|
||||
|
||||
if (NOT FRAMEINTERPOLATION_SHADER_EXT)
|
||||
set(FRAMEINTERPOLATION_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB FRAMEINTERPOLATION_SHADERS
|
||||
"shaders/frameinterpolation/*.${FRAMEINTERPOLATION_SHADER_EXT}")
|
||||
|
||||
# compile all the shaders
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${FRAMEINTERPOLATION_BASE_ARGS}" "${FRAMEINTERPOLATION_API_BASE_ARGS}" "${FRAMEINTERPOLATION_PERMUTATION_ARGS}" "${FRAMEINTERPOLATION_INCLUDE_ARGS}"
|
||||
"${FRAMEINTERPOLATION_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" FRAMEINTERPOLATION_PERMUTATION_OUTPUTS)
|
||||
|
||||
# add the header files they generate to the main list of dependencies
|
||||
add_shader_output("${FRAMEINTERPOLATION_PERMUTATION_OUTPUTS}")
|
||||
192
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation.h
vendored
Normal file
192
betterRenderer/thirdparty/fsr2/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation.h
vendored
Normal file
@@ -0,0 +1,192 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_H
|
||||
#define FFX_FRAMEINTERPOLATION_H
|
||||
|
||||
struct InterpolationSourceColor
|
||||
{
|
||||
FfxFloat32x3 fRaw;
|
||||
FfxFloat32x3 fLinear;
|
||||
FfxFloat32 fBilinearWeightSum;
|
||||
};
|
||||
|
||||
InterpolationSourceColor NewInterpolationSourceColor()
|
||||
{
|
||||
InterpolationSourceColor c;
|
||||
c.fRaw = FfxFloat32x3(0.0, 0.0, 0.0);
|
||||
c.fLinear = FfxFloat32x3(0.0, 0.0, 0.0);
|
||||
c.fBilinearWeightSum = 0.0;
|
||||
return c;
|
||||
}
|
||||
|
||||
InterpolationSourceColor SampleTextureBilinear(FfxBoolean isCurrent, FfxFloat32x2 fUv, FfxFloat32x2 fMotionVector, FfxInt32x2 texSize)
|
||||
{
|
||||
InterpolationSourceColor result = NewInterpolationSourceColor();
|
||||
|
||||
FfxFloat32x2 fReprojectedUv = fUv + fMotionVector;
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fReprojectedUv, texSize);
|
||||
|
||||
FfxFloat32x3 fColor = FfxFloat32x3(0.0, 0.0, 0.0);
|
||||
FfxFloat32 fWeightSum = 0.0f;
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) {
|
||||
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
if (IsInRect(iSamplePos, InterpolationRectBase(), InterpolationRectSize()))
|
||||
{
|
||||
FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex];
|
||||
|
||||
if (isCurrent)
|
||||
fColor += LoadCurrentBackbuffer(iSamplePos).rgb * fWeight;
|
||||
else
|
||||
fColor += LoadPreviousBackbuffer(iSamplePos).rgb * fWeight;
|
||||
fWeightSum += fWeight;
|
||||
}
|
||||
}
|
||||
|
||||
//normalize colors
|
||||
fColor = (fWeightSum != 0.0f) ? fColor / fWeightSum : FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
result.fRaw = fColor;
|
||||
result.fLinear = RawRGBToLinear(fColor);
|
||||
result.fBilinearWeightSum = fWeightSum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void updateInPaintingWeight(inout FfxFloat32 fInPaintingWeight, FfxFloat32 fFactor)
|
||||
{
|
||||
fInPaintingWeight = ffxSaturate(ffxMax(fInPaintingWeight, fFactor));
|
||||
}
|
||||
|
||||
void computeInterpolatedColor(FfxUInt32x2 iPxPos, out FfxFloat32x3 fInterpolatedColor, inout FfxFloat32 fInPaintingWeight)
|
||||
{
|
||||
const FfxFloat32x2 fUvInInterpolationRect = (FfxFloat32x2(iPxPos - InterpolationRectBase()) + 0.5f) / InterpolationRectSize();
|
||||
const FfxFloat32x2 fUvInScreenSpace = (FfxFloat32x2(iPxPos) + 0.5f) / DisplaySize();
|
||||
const FfxFloat32x2 fLrUvInInterpolationRect = fUvInInterpolationRect * (FfxFloat32x2(RenderSize()) / GetMaxRenderSize());
|
||||
|
||||
const FfxFloat32x2 fUvLetterBoxScale = FfxFloat32x2(InterpolationRectSize()) / DisplaySize();
|
||||
|
||||
// game MV are top left aligned, the function scales them to render res UV
|
||||
VectorFieldEntry gameMv;
|
||||
LoadInpaintedGameFieldMv(fUvInInterpolationRect, gameMv);
|
||||
|
||||
// OF is done on the back buffers which already have black bars
|
||||
VectorFieldEntry ofMv;
|
||||
SampleOpticalFlowMotionVectorField(fUvInScreenSpace, ofMv);
|
||||
|
||||
// Binarize disucclusion factor
|
||||
FfxFloat32x2 fDisocclusionFactor = FfxFloat32x2(FFX_EQUAL(ffxSaturate(SampleDisocclusionMask(fLrUvInInterpolationRect).xy), FfxFloat32x2(1.0, 1.0)));
|
||||
|
||||
InterpolationSourceColor fPrevColorGame = SampleTextureBilinear(false, fUvInScreenSpace, +gameMv.fMotionVector * fUvLetterBoxScale, DisplaySize());
|
||||
InterpolationSourceColor fCurrColorGame = SampleTextureBilinear(true, fUvInScreenSpace, -gameMv.fMotionVector * fUvLetterBoxScale, DisplaySize());
|
||||
|
||||
InterpolationSourceColor fPrevColorOF = SampleTextureBilinear(false, fUvInScreenSpace, +ofMv.fMotionVector * fUvLetterBoxScale, DisplaySize());
|
||||
InterpolationSourceColor fCurrColorOF = SampleTextureBilinear(true, fUvInScreenSpace, -ofMv.fMotionVector * fUvLetterBoxScale, DisplaySize());
|
||||
|
||||
FfxFloat32 fBilinearWeightSum = 0.0f;
|
||||
FfxFloat32 fDisoccludedFactor = 0.0f;
|
||||
|
||||
// Disocclusion logic
|
||||
{
|
||||
fDisocclusionFactor.x *= FfxFloat32(!gameMv.bNegOutside);
|
||||
fDisocclusionFactor.y *= FfxFloat32(!gameMv.bPosOutside);
|
||||
|
||||
// Inpaint in bi-directional disocclusion areas
|
||||
updateInPaintingWeight(fInPaintingWeight, FfxFloat32(length(fDisocclusionFactor) <= FFX_FRAMEINTERPOLATION_EPSILON));
|
||||
|
||||
FfxFloat32 t = 0.5f;
|
||||
t += 0.5f * (1 - (fDisocclusionFactor.x));
|
||||
t -= 0.5f * (1 - (fDisocclusionFactor.y));
|
||||
|
||||
fInterpolatedColor = ffxLerp(fPrevColorGame.fRaw, fCurrColorGame.fRaw, ffxSaturate(t));
|
||||
fBilinearWeightSum = ffxLerp(fPrevColorGame.fBilinearWeightSum, fCurrColorGame.fBilinearWeightSum, ffxSaturate(t));
|
||||
|
||||
fDisoccludedFactor = ffxSaturate(1 - ffxMin(fDisocclusionFactor.x, fDisocclusionFactor.y));
|
||||
|
||||
if (fPrevColorGame.fBilinearWeightSum == 0.0f)
|
||||
{
|
||||
fInterpolatedColor = fCurrColorGame.fRaw;
|
||||
fBilinearWeightSum = fCurrColorGame.fBilinearWeightSum;
|
||||
}
|
||||
else if (fCurrColorGame.fBilinearWeightSum == 0.0f)
|
||||
{
|
||||
fInterpolatedColor = fPrevColorGame.fRaw;
|
||||
fBilinearWeightSum = fPrevColorGame.fBilinearWeightSum;
|
||||
}
|
||||
if (fPrevColorGame.fBilinearWeightSum == 0 && fCurrColorGame.fBilinearWeightSum == 0)
|
||||
{
|
||||
fInPaintingWeight = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
FfxFloat32 ofT = 0.5f;
|
||||
|
||||
if (fPrevColorOF.fBilinearWeightSum > 0 && fCurrColorOF.fBilinearWeightSum > 0)
|
||||
{
|
||||
ofT = 0.5f;
|
||||
}
|
||||
else if (fPrevColorOF.fBilinearWeightSum > 0)
|
||||
{
|
||||
ofT = 0;
|
||||
} else {
|
||||
ofT = 1;
|
||||
}
|
||||
|
||||
const FfxFloat32x3 ofColor = ffxLerp(fPrevColorOF.fRaw, fCurrColorOF.fRaw, ofT);
|
||||
|
||||
FfxFloat32 fOF_Sim = NormalizedDot3(fPrevColorOF.fRaw, fCurrColorOF.fRaw);
|
||||
FfxFloat32 fGame_Sim = NormalizedDot3(fPrevColorGame.fRaw, fCurrColorGame.fRaw);
|
||||
|
||||
fGame_Sim = ffxLerp(ffxMax(FFX_FRAMEINTERPOLATION_EPSILON, fGame_Sim), 1.0f, ffxSaturate(fDisoccludedFactor));
|
||||
FfxFloat32 fGameMvBias = ffxPow(ffxSaturate(fGame_Sim / ffxMax(FFX_FRAMEINTERPOLATION_EPSILON, fOF_Sim)), 1.0f);
|
||||
|
||||
const FfxFloat32 fFrameIndexFactor = FfxFloat32(FrameIndexSinceLastReset() < 10);
|
||||
fGameMvBias = ffxLerp(fGameMvBias, 1.0f, fFrameIndexFactor);
|
||||
|
||||
fInterpolatedColor = ffxLerp(ofColor, fInterpolatedColor, ffxSaturate(fGameMvBias));
|
||||
}
|
||||
}
|
||||
|
||||
void computeFrameinterpolation(FfxInt32x2 iPxPos)
|
||||
{
|
||||
FfxFloat32x3 fColor = FfxFloat32x3(0, 0, 0);
|
||||
FfxFloat32 fInPaintingWeight = 0.0f;
|
||||
|
||||
if (IsInRect(iPxPos, InterpolationRectBase(), InterpolationRectSize()) == false || FrameIndexSinceLastReset() == 0)
|
||||
{
|
||||
// if we just reset or we are out of the interpolation rect, copy the current back buffer and don't interpolate
|
||||
fColor = LoadCurrentBackbuffer(iPxPos);
|
||||
}
|
||||
else
|
||||
{
|
||||
computeInterpolatedColor(iPxPos, fColor, fInPaintingWeight);
|
||||
}
|
||||
|
||||
StoreFrameinterpolationOutput(FfxInt32x2(iPxPos), FfxFloat32x4(fColor, fInPaintingWeight));
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_H
|
||||
@@ -0,0 +1,745 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ffx_frameinterpolation_resources.h"
|
||||
#include "ffx_core.h"
|
||||
|
||||
#define COUNTER_SPD 0
|
||||
#define COUNTER_FRAME_INDEX_SINCE_LAST_RESET 1
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// declare CBs and CB accessors
|
||||
///////////////////////////////////////////////
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION, std140) uniform cbFI_t
|
||||
{
|
||||
FfxInt32x2 renderSize;
|
||||
FfxInt32x2 displaySize;
|
||||
|
||||
FfxFloat32x2 displaySizeRcp;
|
||||
FfxFloat32 cameraNear;
|
||||
FfxFloat32 cameraFar;
|
||||
|
||||
FfxInt32x2 upscalerTargetSize;
|
||||
FfxInt32 Mode;
|
||||
FfxInt32 reset;
|
||||
|
||||
FfxFloat32x4 fDeviceToViewDepth;
|
||||
|
||||
FfxFloat32 deltaTime;
|
||||
FfxInt32 HUDLessAttachedFactor;
|
||||
FfxFloat32x2 UNUSED;
|
||||
|
||||
FfxFloat32x2 opticalFlowScale;
|
||||
FfxInt32 opticalFlowBlockSize;
|
||||
FfxUInt32 dispatchFlags;
|
||||
|
||||
FfxInt32x2 maxRenderSize;
|
||||
FfxInt32 opticalFlowHalfResMode;
|
||||
FfxInt32 NumInstances;
|
||||
|
||||
FfxInt32x2 interpolationRectBase;
|
||||
FfxInt32x2 interpolationRectSize;
|
||||
|
||||
FfxFloat32x3 debugBarColor;
|
||||
FfxUInt32 backBufferTransferFunction;
|
||||
|
||||
FfxFloat32x2 minMaxLuminance;
|
||||
FfxFloat32 fTanHalfFOV;
|
||||
FfxInt32 _pad1;
|
||||
|
||||
FfxFloat32x2 fJitter;
|
||||
FfxFloat32x2 fMotionVectorScale;
|
||||
} cbFI;
|
||||
|
||||
FfxFloat32x2 Jitter()
|
||||
{
|
||||
return cbFI.fJitter;
|
||||
}
|
||||
|
||||
FfxInt32x2 InterpolationRectBase()
|
||||
{
|
||||
return cbFI.interpolationRectBase;
|
||||
}
|
||||
|
||||
FfxInt32x2 InterpolationRectSize()
|
||||
{
|
||||
return cbFI.interpolationRectSize;
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
return cbFI.fMotionVectorScale;
|
||||
}
|
||||
|
||||
FfxInt32x2 RenderSize()
|
||||
{
|
||||
return cbFI.renderSize;
|
||||
}
|
||||
|
||||
FfxInt32x2 DisplaySize()
|
||||
{
|
||||
return cbFI.displaySize;
|
||||
}
|
||||
|
||||
FfxBoolean Reset()
|
||||
{
|
||||
return cbFI.reset == 1;
|
||||
}
|
||||
|
||||
FfxFloat32x4 DeviceToViewSpaceTransformFactors()
|
||||
{
|
||||
return cbFI.fDeviceToViewDepth;
|
||||
}
|
||||
|
||||
FfxInt32x2 GetOpticalFlowSize()
|
||||
{
|
||||
FfxInt32x2 iOpticalFlowSize = FfxInt32x2((1.0 / cbFI.opticalFlowScale) / FfxFloat32x2(cbFI.opticalFlowBlockSize.xx));
|
||||
|
||||
return iOpticalFlowSize;
|
||||
}
|
||||
|
||||
FfxInt32x2 GetOpticalFlowSize2()
|
||||
{
|
||||
return GetOpticalFlowSize() * 1;
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetOpticalFlowScale()
|
||||
{
|
||||
return cbFI.opticalFlowScale;
|
||||
}
|
||||
|
||||
FfxInt32 GetOpticalFlowBlockSize()
|
||||
{
|
||||
return cbFI.opticalFlowBlockSize;
|
||||
}
|
||||
|
||||
FfxInt32 GetHUDLessAttachedFactor()
|
||||
{
|
||||
return cbFI.HUDLessAttachedFactor;
|
||||
}
|
||||
|
||||
FfxUInt32 GetDispatchFlags()
|
||||
{
|
||||
return cbFI.dispatchFlags;
|
||||
}
|
||||
|
||||
FfxInt32x2 GetMaxRenderSize()
|
||||
{
|
||||
return cbFI.maxRenderSize;
|
||||
}
|
||||
|
||||
FfxInt32 GetOpticalFlowHalfResMode()
|
||||
{
|
||||
return cbFI.opticalFlowHalfResMode;
|
||||
}
|
||||
|
||||
FfxFloat32x3 GetDebugBarColor()
|
||||
{
|
||||
return cbFI.debugBarColor;
|
||||
}
|
||||
|
||||
FfxFloat32 TanHalfFoV()
|
||||
{
|
||||
return cbFI.fTanHalfFOV;
|
||||
}
|
||||
|
||||
FfxUInt32 BackBufferTransferFunction()
|
||||
{
|
||||
return cbFI.backBufferTransferFunction;
|
||||
}
|
||||
|
||||
FfxFloat32 MinLuminance()
|
||||
{
|
||||
return cbFI.minMaxLuminance[0];
|
||||
}
|
||||
|
||||
FfxFloat32 MaxLuminance()
|
||||
{
|
||||
return cbFI.minMaxLuminance[1];
|
||||
}
|
||||
|
||||
#endif // defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_INPAINTING_PYRAMID)
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_CB_INPAINTING_PYRAMID, std140) uniform cbInpaintingPyramid_t
|
||||
{
|
||||
FfxUInt32 mips;
|
||||
FfxUInt32 numWorkGroups;
|
||||
FfxUInt32x2 workGroupOffset;
|
||||
} cbInpaintingPyramid;
|
||||
|
||||
FfxUInt32 NumMips()
|
||||
{
|
||||
return cbInpaintingPyramid.mips;
|
||||
}
|
||||
FfxUInt32 NumWorkGroups()
|
||||
{
|
||||
return cbInpaintingPyramid.numWorkGroups;
|
||||
}
|
||||
FfxUInt32x2 WorkGroupOffset()
|
||||
{
|
||||
return cbInpaintingPyramid.workGroupOffset;
|
||||
}
|
||||
|
||||
#endif // defined(FFX_FRAMEINTERPOLATION_BIND_CB_INPAINTING_PYRAMID)
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// declare samplers
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
layout (set = 0, binding = 1000) uniform sampler s_LinearClamp;
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// declare SRVs and SRV accessors
|
||||
///////////////////////////////////////////////
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE) uniform texture2D r_previous_interpolation_source;
|
||||
|
||||
FfxFloat32x3 LoadPreviousBackbuffer(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_previous_interpolation_source, iPxPos, 0).rgb;
|
||||
}
|
||||
FfxFloat32x3 SamplePreviousBackbuffer(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return textureLod(sampler2D(r_previous_interpolation_source, s_LinearClamp), fUv, 0.0).xyz;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE) uniform texture2D r_current_interpolation_source;
|
||||
|
||||
FfxFloat32x3 LoadCurrentBackbuffer(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_current_interpolation_source, iPxPos, 0).rgb;
|
||||
}
|
||||
FfxFloat32x3 SampleCurrentBackbuffer(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return textureLod(sampler2D(r_current_interpolation_source, s_LinearClamp), fUv, 0.0).xyz;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_MOTION_VECTORS
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_MOTION_VECTORS) uniform texture2D r_dilated_motion_vectors;
|
||||
|
||||
FfxFloat32x2 LoadDilatedMotionVector(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_dilated_motion_vectors, iPxPos, 0).xy;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH) uniform texture2D r_dilated_depth;
|
||||
|
||||
FfxFloat32 LoadDilatedDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_dilated_depth, iPxPos, 0).x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME) uniform utexture2D r_reconstructed_depth_previous_frame;
|
||||
|
||||
FfxFloat32 LoadReconstructedDepthPreviousFrame(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return ffxAsFloat(texelFetch(r_reconstructed_depth_previous_frame, iPxInput, 0).x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME) uniform utexture2D r_reconstructed_depth_interpolated_frame;
|
||||
|
||||
FfxFloat32 LoadEstimatedInterpolationFrameDepth(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return ffxAsFloat(texelFetch(r_reconstructed_depth_interpolated_frame, iPxInput, 0).x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_DISOCCLUSION_MASK
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_DISOCCLUSION_MASK) uniform texture2D r_disocclusion_mask;
|
||||
|
||||
FfxFloat32x4 LoadDisocclusionMask(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_disocclusion_mask, iPxPos, 0);
|
||||
}
|
||||
FfxFloat32x4 SampleDisocclusionMask(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return textureLod(sampler2D(r_disocclusion_mask, s_LinearClamp), fUv, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_Y)
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_X) uniform utexture2D r_game_motion_vector_field_x;
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_Y) uniform utexture2D r_game_motion_vector_field_y;
|
||||
|
||||
FfxUInt32x2 LoadGameFieldMv(FFX_PARAMETER_IN FfxInt32x2 iPxSample)
|
||||
{
|
||||
FfxUInt32 packedX = texelFetch(r_game_motion_vector_field_x, iPxSample, 0).x;
|
||||
FfxUInt32 packedY = texelFetch(r_game_motion_vector_field_y, iPxSample, 0).x;
|
||||
|
||||
return FfxUInt32x2(packedX, packedY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y)
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X) uniform utexture2D r_optical_flow_motion_vector_field_x;
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y) uniform utexture2D r_optical_flow_motion_vector_field_y;
|
||||
|
||||
FfxUInt32x2 LoadOpticalFlowFieldMv(FFX_PARAMETER_IN FfxInt32x2 iPxSample)
|
||||
{
|
||||
FfxUInt32 packedX = texelFetch(r_optical_flow_motion_vector_field_x, iPxSample, 0).x;
|
||||
FfxUInt32 packedY = texelFetch(r_optical_flow_motion_vector_field_y, iPxSample, 0).x;
|
||||
|
||||
return FfxUInt32x2(packedX, packedY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW) uniform itexture2D r_optical_flow;
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
FfxFloat32x2 LoadOpticalFlow(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_optical_flow, iPxPos, 0).xy * GetOpticalFlowScale();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_UPSAMPLED
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_UPSAMPLED) uniform texture2D r_optical_flow_upsampled;
|
||||
|
||||
FfxFloat32x2 LoadOpticalFlowUpsampled(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_optical_flow_upsampled, iPxPos, 0).xy;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_CONFIDENCE
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_CONFIDENCE) uniform utexture2D r_optical_flow_confidence;
|
||||
|
||||
FfxFloat32 LoadOpticalFlowConfidence(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_optical_flow_confidence, iPxPos, 0).y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION) uniform utexture2D r_optical_flow_global_motion;
|
||||
|
||||
FfxUInt32 LoadOpticalFlowGlobalMotion(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_optical_flow_global_motion, iPxPos, 0).x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_SCENE_CHANGE_DETECTION
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_SCENE_CHANGE_DETECTION) uniform utexture2D r_optical_flow_scd;
|
||||
|
||||
FfxUInt32 LoadOpticalFlowSceneChangeDetection(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_optical_flow_scd, iPxPos, 0).x;
|
||||
}
|
||||
|
||||
FfxBoolean HasSceneChanged()
|
||||
{
|
||||
#define SCD_OUTPUT_HISTORY_BITS_SLOT 1
|
||||
//if (FrameIndex() <= 5) // threshold according to original OpenCL code
|
||||
//{
|
||||
// return 1.0;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
// Report that the scene is changed if the change was detected in any of the
|
||||
// 4 previous frames (0xfu - covers 4 history bits).
|
||||
return ((texelFetch(r_optical_flow_scd, FfxInt32x2(SCD_OUTPUT_HISTORY_BITS_SLOT, 0), 0).x) & 0xfu) != 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_DEBUG
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_DEBUG) uniform texture2D r_optical_flow_debug;
|
||||
|
||||
FfxFloat32x4 LoadOpticalFlowDebug(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_optical_flow_debug, iPxPos, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OUTPUT
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_OUTPUT) uniform texture2D r_output;
|
||||
|
||||
FfxFloat32x4 LoadFrameInterpolationOutput(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return texelFetch(r_output, iPxInput, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID) uniform texture2D r_inpainting_pyramid;
|
||||
|
||||
FfxFloat32x4 LoadInpaintingPyramid(FFX_PARAMETER_IN FfxInt32 mipLevel, FFX_PARAMETER_IN FfxUInt32x2 iPxInput)
|
||||
{
|
||||
return texelFetch(r_inpainting_pyramid, FfxInt32x2(iPxInput), mipLevel);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_PRESENT_BACKBUFFER
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_PRESENT_BACKBUFFER) uniform texture2D r_present_backbuffer;
|
||||
|
||||
FfxFloat32x4 LoadPresentBackbuffer(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return texelFetch(r_present_backbuffer, iPxInput, 0);
|
||||
}
|
||||
FfxFloat32x4 SamplePresentBackbuffer(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return textureLod(sampler2D(r_present_backbuffer, s_LinearClamp), fUv, 0.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_COUNTERS
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_COUNTERS) readonly buffer FrameInterpolationCounters_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} r_counters;
|
||||
|
||||
FfxUInt32 LoadCounter(FFX_PARAMETER_IN FfxInt32 iPxPos)
|
||||
{
|
||||
return r_counters.data[iPxPos];
|
||||
}
|
||||
|
||||
FfxUInt32 FrameIndexSinceLastReset()
|
||||
{
|
||||
return LoadCounter(COUNTER_FRAME_INDEX_SINCE_LAST_RESET);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_DEPTH)
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_DEPTH) uniform texture2D r_input_depth;
|
||||
|
||||
FfxFloat32 LoadInputDepth(FfxInt32x2 iPxPos)
|
||||
{
|
||||
return texelFetch(r_input_depth, iPxPos, 0).x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
layout (set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_MOTION_VECTORS) uniform texture2D r_input_motion_vectors;
|
||||
|
||||
FfxFloat32x2 LoadInputMotionVector(FfxInt32x2 iPxDilatedMotionVectorPos)
|
||||
{
|
||||
FfxFloat32x2 fSrcMotionVector = texelFetch(r_input_motion_vectors, iPxDilatedMotionVectorPos, 0).xy;
|
||||
|
||||
FfxFloat32x2 fUvMotionVector = fSrcMotionVector * MotionVectorScale();
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_JITTERED_MOTION_VECTORS
|
||||
fUvMotionVector -= MotionVectorJitterCancellation();
|
||||
#endif
|
||||
|
||||
return fUvMotionVector;
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// declare UAVs and UAV accessors
|
||||
///////////////////////////////////////////////
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_OUTPUT
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_OUTPUT /* app controlled format */) uniform image2D rw_output;
|
||||
|
||||
FfxFloat32x4 RWLoadFrameinterpolationOutput(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_output, iPxPos);
|
||||
}
|
||||
|
||||
void StoreFrameinterpolationOutput(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x4 val)
|
||||
{
|
||||
imageStore(rw_output, iPxPos, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_MOTION_VECTORS
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_MOTION_VECTORS, rg16f) uniform image2D rw_dilated_motion_vectors;
|
||||
|
||||
FfxFloat32x2 RWLoadDilatedMotionVectors(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_dilated_motion_vectors, iPxPos).xy;
|
||||
}
|
||||
|
||||
void StoreDilatedMotionVectors(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x2 val)
|
||||
{
|
||||
imageStore(rw_dilated_motion_vectors, iPxPos, FfxFloat32x4(val, 0.0, 0.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_DEPTH
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_DEPTH, r32f) uniform image2D rw_dilated_depth;
|
||||
|
||||
FfxFloat32 RWLoadDilatedDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_dilated_depth, iPxPos).x;
|
||||
}
|
||||
|
||||
void StoreDilatedDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32 val)
|
||||
{
|
||||
imageStore(rw_dilated_depth, iPxPos, FfxFloat32x4(val, 0.0, 0.0, 0.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME, r32ui) uniform uimage2D rw_reconstructed_depth_previous_frame;
|
||||
|
||||
FfxFloat32 RWLoadReconstructedDepthPreviousFrame(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return ffxAsFloat(imageLoad(rw_reconstructed_depth_previous_frame, iPxPos).x);
|
||||
}
|
||||
|
||||
void UpdateReconstructedDepthPreviousFrame(FfxInt32x2 iPxSample, FfxFloat32 fDepth)
|
||||
{
|
||||
FfxUInt32 uDepth = ffxAsUInt32(fDepth);
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH
|
||||
imageAtomicMax(rw_reconstructed_depth_previous_frame, iPxSample, uDepth);
|
||||
#else
|
||||
imageAtomicMin(rw_reconstructed_depth_previous_frame, iPxSample, uDepth); // min for standard, max for inverted depth
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME, r32ui) uniform uimage2D rw_reconstructed_depth_interpolated_frame;
|
||||
|
||||
FfxFloat32 RWLoadReconstructedDepthInterpolatedFrame(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return ffxAsFloat(imageLoad(rw_reconstructed_depth_interpolated_frame, iPxPos).x);
|
||||
}
|
||||
|
||||
void StoreReconstructedDepthInterpolatedFrame(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32 value)
|
||||
{
|
||||
FfxUInt32 uDepth = ffxAsUInt32(value);
|
||||
imageStore(rw_reconstructed_depth_interpolated_frame, iPxPos, FfxUInt32x4(uDepth, 0, 0, 0));
|
||||
}
|
||||
|
||||
void UpdateReconstructedDepthInterpolatedFrame(FfxInt32x2 iPxSample, FfxFloat32 fDepth)
|
||||
{
|
||||
FfxUInt32 uDepth = ffxAsUInt32(fDepth);
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH
|
||||
imageAtomicMax(rw_reconstructed_depth_interpolated_frame, iPxSample, uDepth);
|
||||
#else
|
||||
imageAtomicMin(rw_reconstructed_depth_interpolated_frame, iPxSample, uDepth); // min for standard, max for inverted depth
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_DISOCCLUSION_MASK
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_DISOCCLUSION_MASK, rg8) uniform image2D rw_disocclusion_mask;
|
||||
|
||||
FfxFloat32x2 RWLoadDisocclusionMask(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_disocclusion_mask, iPxPos).xy;
|
||||
}
|
||||
|
||||
void StoreDisocclusionMask(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x2 val)
|
||||
{
|
||||
imageStore(rw_disocclusion_mask, iPxPos, FfxFloat32x4(val, 0.0, 0.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_Y)
|
||||
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_X, r32ui) uniform uimage2D rw_game_motion_vector_field_x;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_Y, r32ui) uniform uimage2D rw_game_motion_vector_field_y;
|
||||
|
||||
FfxUInt32 RWLoadGameMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_game_motion_vector_field_x, iPxPos).x;
|
||||
}
|
||||
|
||||
void StoreGameMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
imageStore(rw_game_motion_vector_field_x, iPxPos, FfxUInt32x4(val, 0, 0, 0));
|
||||
}
|
||||
|
||||
FfxUInt32 RWLoadGameMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_game_motion_vector_field_y, iPxPos).x;
|
||||
}
|
||||
|
||||
void StoreGameMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
imageStore(rw_game_motion_vector_field_y, iPxPos, FfxUInt32x4(val, 0, 0, 0));
|
||||
}
|
||||
|
||||
void UpdateGameMotionVectorField(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32x2 packedVector)
|
||||
{
|
||||
imageAtomicMax(rw_game_motion_vector_field_x, iPxPos, packedVector.x);
|
||||
imageAtomicMax(rw_game_motion_vector_field_y, iPxPos, packedVector.y);
|
||||
}
|
||||
|
||||
FfxUInt32 UpdateGameMotionVectorFieldEx(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32x2 packedVector)
|
||||
{
|
||||
FfxUInt32 uPreviousValueX = imageAtomicMax(rw_game_motion_vector_field_x, iPxPos, packedVector.x);
|
||||
FfxUInt32 uPreviousValueY = imageAtomicMax(rw_game_motion_vector_field_y, iPxPos, packedVector.y);
|
||||
|
||||
const FfxUInt32 uExistingVectorFieldEntry = ffxMax(uPreviousValueX, uPreviousValueY);
|
||||
|
||||
return uExistingVectorFieldEntry;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y)
|
||||
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X, r32ui) uniform uimage2D rw_optical_flow_motion_vector_field_x;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y, r32ui) uniform uimage2D rw_optical_flow_motion_vector_field_y;
|
||||
|
||||
FfxUInt32 RWLoadOpticalflowMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_optical_flow_motion_vector_field_x, iPxPos).x;
|
||||
}
|
||||
void StoreOpticalflowMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
imageStore(rw_optical_flow_motion_vector_field_x, iPxPos, FfxUInt32x4(val, 0, 0, 0));
|
||||
}
|
||||
FfxUInt32 RWLoadOpticalflowMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return imageLoad(rw_optical_flow_motion_vector_field_y, iPxPos).x;
|
||||
}
|
||||
void StoreOpticalflowMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
imageStore(rw_optical_flow_motion_vector_field_y, iPxPos, FfxUInt32x4(val, 0, 0, 0));
|
||||
}
|
||||
void UpdateOpticalflowMotionVectorField(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32x2 packedVector)
|
||||
{
|
||||
imageAtomicMax(rw_optical_flow_motion_vector_field_x, iPxPos, packedVector.x);
|
||||
imageAtomicMax(rw_optical_flow_motion_vector_field_y, iPxPos, packedVector.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_COUNTERS
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_COUNTERS) coherent buffer FrameInterpolationRWCounters_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_counters;
|
||||
|
||||
FfxUInt32 RWLoadCounter(FFX_PARAMETER_IN FfxInt32 iPxPos)
|
||||
{
|
||||
return rw_counters.data[iPxPos];
|
||||
}
|
||||
|
||||
void StoreCounter(FFX_PARAMETER_IN FfxInt32 iPxPos, FFX_PARAMETER_IN FfxUInt32 counter)
|
||||
{
|
||||
rw_counters.data[iPxPos] = counter;
|
||||
}
|
||||
void AtomicIncreaseCounter(FFX_PARAMETER_IN FfxInt32 iPxPos, FFX_PARAMETER_OUT FfxUInt32 oldVal)
|
||||
{
|
||||
oldVal = atomicAdd(rw_counters.data[iPxPos], 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_0) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_1) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_2) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_3) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_4) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_5) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_6) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_7) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_8) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_9) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_10) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_11) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_12)
|
||||
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_0, rgba16f) uniform image2D rw_inpainting_pyramid0;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_1, rgba16f) uniform image2D rw_inpainting_pyramid1;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_2, rgba16f) uniform image2D rw_inpainting_pyramid2;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_3, rgba16f) uniform image2D rw_inpainting_pyramid3;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_4, rgba16f) uniform image2D rw_inpainting_pyramid4;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_5, rgba16f) coherent uniform image2D rw_inpainting_pyramid5;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_6, rgba16f) uniform image2D rw_inpainting_pyramid6;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_7, rgba16f) uniform image2D rw_inpainting_pyramid7;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_8, rgba16f) uniform image2D rw_inpainting_pyramid8;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_9, rgba16f) uniform image2D rw_inpainting_pyramid9;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_10, rgba16f) uniform image2D rw_inpainting_pyramid10;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_11, rgba16f) uniform image2D rw_inpainting_pyramid11;
|
||||
layout(set = 0, binding = FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_12, rgba16f) uniform image2D rw_inpainting_pyramid12;
|
||||
|
||||
|
||||
FfxFloat32x4 RWLoadInpaintingPyramid(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 index)
|
||||
{
|
||||
#define LOAD(idx) \
|
||||
if (index == idx) \
|
||||
{ \
|
||||
return imageLoad(rw_inpainting_pyramid##idx, iPxPos); \
|
||||
}
|
||||
LOAD(0);
|
||||
LOAD(1);
|
||||
LOAD(2);
|
||||
LOAD(3);
|
||||
LOAD(4);
|
||||
LOAD(5);
|
||||
LOAD(6);
|
||||
LOAD(7);
|
||||
LOAD(8);
|
||||
LOAD(9);
|
||||
LOAD(10);
|
||||
LOAD(11);
|
||||
LOAD(12);
|
||||
return FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
#undef LOAD
|
||||
}
|
||||
|
||||
void StoreInpaintingPyramid(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x4 outValue, FFX_PARAMETER_IN FfxUInt32 index)
|
||||
{
|
||||
#define STORE(idx) \
|
||||
if (index == idx) \
|
||||
{ \
|
||||
imageStore(rw_inpainting_pyramid##idx, iPxPos, outValue); \
|
||||
}
|
||||
|
||||
STORE(0);
|
||||
STORE(1);
|
||||
STORE(2);
|
||||
STORE(3);
|
||||
STORE(4);
|
||||
STORE(5);
|
||||
STORE(6);
|
||||
STORE(7);
|
||||
STORE(8);
|
||||
STORE(9);
|
||||
STORE(10);
|
||||
STORE(11);
|
||||
STORE(12);
|
||||
|
||||
#undef STORE
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,778 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "ffx_frameinterpolation_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic push
|
||||
#pragma dxc diagnostic ignored "-Wambig-lit-shift"
|
||||
#endif //__hlsl_dx_compiler
|
||||
#include "ffx_core.h"
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic pop
|
||||
#endif //__hlsl_dx_compiler
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
|
||||
#define COUNTER_SPD 0
|
||||
#define COUNTER_FRAME_INDEX_SINCE_LAST_RESET 1
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// declare CBs and CB accessors
|
||||
///////////////////////////////////////////////
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
cbuffer cbFI : FFX_DECLARE_CB(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
{
|
||||
FfxInt32x2 renderSize;
|
||||
FfxInt32x2 displaySize;
|
||||
|
||||
FfxFloat32x2 displaySizeRcp;
|
||||
FfxFloat32 cameraNear;
|
||||
FfxFloat32 cameraFar;
|
||||
|
||||
FfxInt32x2 upscalerTargetSize;
|
||||
FfxInt32 Mode;
|
||||
FfxInt32 reset;
|
||||
|
||||
FfxFloat32x4 fDeviceToViewDepth;
|
||||
|
||||
FfxFloat32 deltaTime;
|
||||
FfxInt32 HUDLessAttachedFactor;
|
||||
FfxFloat32x2 UNUSED;
|
||||
|
||||
FfxFloat32x2 opticalFlowScale;
|
||||
FfxInt32 opticalFlowBlockSize;
|
||||
FfxUInt32 dispatchFlags;
|
||||
|
||||
FfxInt32x2 maxRenderSize;
|
||||
FfxInt32 opticalFlowHalfResMode;
|
||||
FfxInt32 NumInstances;
|
||||
|
||||
FfxInt32x2 interpolationRectBase;
|
||||
FfxInt32x2 interpolationRectSize;
|
||||
|
||||
FfxFloat32x3 debugBarColor;
|
||||
FfxUInt32 backBufferTransferFunction;
|
||||
|
||||
FfxFloat32x2 minMaxLuminance;
|
||||
FfxFloat32 fTanHalfFOV;
|
||||
FfxInt32 _pad1;
|
||||
|
||||
FfxFloat32x2 fJitter;
|
||||
FfxFloat32x2 fMotionVectorScale;
|
||||
}
|
||||
|
||||
const FfxFloat32x2 Jitter()
|
||||
{
|
||||
return fJitter;
|
||||
}
|
||||
|
||||
const FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
return fMotionVectorScale;
|
||||
}
|
||||
|
||||
const FfxInt32x2 InterpolationRectBase()
|
||||
{
|
||||
return interpolationRectBase;
|
||||
}
|
||||
|
||||
const FfxInt32x2 InterpolationRectSize()
|
||||
{
|
||||
return interpolationRectSize;
|
||||
}
|
||||
|
||||
const FfxInt32x2 RenderSize()
|
||||
{
|
||||
return renderSize;
|
||||
}
|
||||
|
||||
const FfxInt32x2 DisplaySize()
|
||||
{
|
||||
return displaySize;
|
||||
}
|
||||
|
||||
const FfxBoolean Reset()
|
||||
{
|
||||
return reset == 1;
|
||||
}
|
||||
|
||||
FfxFloat32x4 DeviceToViewSpaceTransformFactors()
|
||||
{
|
||||
return fDeviceToViewDepth;
|
||||
}
|
||||
|
||||
FfxInt32x2 GetOpticalFlowSize()
|
||||
{
|
||||
FfxInt32x2 iOpticalFlowSize = (1.0f / opticalFlowScale) / FfxFloat32x2(opticalFlowBlockSize.xx);
|
||||
|
||||
return iOpticalFlowSize;
|
||||
}
|
||||
|
||||
FfxInt32x2 GetOpticalFlowSize2()
|
||||
{
|
||||
return GetOpticalFlowSize() * 1;
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetOpticalFlowScale()
|
||||
{
|
||||
return opticalFlowScale;
|
||||
}
|
||||
|
||||
FfxInt32 GetOpticalFlowBlockSize()
|
||||
{
|
||||
return opticalFlowBlockSize;
|
||||
}
|
||||
|
||||
FfxInt32 GetHUDLessAttachedFactor()
|
||||
{
|
||||
return HUDLessAttachedFactor;
|
||||
}
|
||||
|
||||
FfxUInt32 GetDispatchFlags()
|
||||
{
|
||||
return dispatchFlags;
|
||||
}
|
||||
|
||||
FfxInt32x2 GetMaxRenderSize()
|
||||
{
|
||||
return maxRenderSize;
|
||||
}
|
||||
|
||||
FfxInt32 GetOpticalFlowHalfResMode()
|
||||
{
|
||||
return opticalFlowHalfResMode;
|
||||
}
|
||||
|
||||
FfxFloat32x3 GetDebugBarColor()
|
||||
{
|
||||
return debugBarColor;
|
||||
}
|
||||
|
||||
FfxFloat32 TanHalfFoV()
|
||||
{
|
||||
return fTanHalfFOV;
|
||||
}
|
||||
|
||||
FfxUInt32 BackBufferTransferFunction()
|
||||
{
|
||||
return backBufferTransferFunction;
|
||||
}
|
||||
|
||||
FfxFloat32 MinLuminance()
|
||||
{
|
||||
return minMaxLuminance[0];
|
||||
}
|
||||
|
||||
FfxFloat32 MaxLuminance()
|
||||
{
|
||||
return minMaxLuminance[1];
|
||||
}
|
||||
|
||||
#endif // #if defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_INPAINTING_PYRAMID)
|
||||
cbuffer cbInpaintingPyramid : FFX_DECLARE_CB(FFX_FRAMEINTERPOLATION_BIND_CB_INPAINTING_PYRAMID)
|
||||
{
|
||||
FfxUInt32 mips;
|
||||
FfxUInt32 numWorkGroups;
|
||||
FfxUInt32x2 workGroupOffset;
|
||||
}
|
||||
|
||||
FfxUInt32 NumMips()
|
||||
{
|
||||
return mips;
|
||||
}
|
||||
FfxUInt32 NumWorkGroups()
|
||||
{
|
||||
return numWorkGroups;
|
||||
}
|
||||
FfxUInt32x2 WorkGroupOffset()
|
||||
{
|
||||
return workGroupOffset;
|
||||
}
|
||||
#endif // #if defined(FFX_FRAMEINTERPOLATION_BIND_CB_INPAINTING_PYRAMID)
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_ROOTSIG_STRINGIFY(p) FFX_FRAMEINTERPOLATION_ROOTSIG_STR(p)
|
||||
#define FFX_FRAMEINTERPOLATION_ROOTSIG_STR(p) #p
|
||||
#define FFX_FRAMEINTERPOLATION_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_FRAMEINTERPOLATION_ROOTSIG_STRINGIFY(FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_FRAMEINTERPOLATION_ROOTSIG_STRINGIFY(FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0), " \
|
||||
"StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_LINEAR, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"comparisonFunc = COMPARISON_NEVER, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK)" )]
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_INPAINTING_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_FRAMEINTERPOLATION_ROOTSIG_STRINGIFY(FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_FRAMEINTERPOLATION_ROOTSIG_STRINGIFY(FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0), " \
|
||||
"CBV(b1), " \
|
||||
"StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_LINEAR, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"comparisonFunc = COMPARISON_NEVER, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK)" )]
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_EMBED_ROOTSIG)
|
||||
#define FFX_FRAMEINTERPOLATION_EMBED_ROOTSIG_CONTENT FFX_FRAMEINTERPOLATION_ROOTSIG
|
||||
#define FFX_FRAMEINTERPOLATION_EMBED_INPAINTING_ROOTSIG_CONTENT FFX_FRAMEINTERPOLATION_INPAINTING_ROOTSIG
|
||||
#else
|
||||
#define FFX_FRAMEINTERPOLATION_EMBED_ROOTSIG_CONTENT
|
||||
#define FFX_FRAMEINTERPOLATION_EMBED_INPAINTING_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_FRAMEINTERPOLATION_EMBED_ROOTSIG
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// declare samplers
|
||||
///////////////////////////////////////////////
|
||||
|
||||
SamplerState s_LinearClamp : register(s0);
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// declare SRVs and SRV accessors
|
||||
///////////////////////////////////////////////
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE
|
||||
Texture2D<FfxFloat32x4> r_previous_interpolation_source : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_PREVIOUS_INTERPOLATION_SOURCE);
|
||||
|
||||
FfxFloat32x3 LoadPreviousBackbuffer(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_previous_interpolation_source[iPxPos].rgb;
|
||||
}
|
||||
FfxFloat32x3 SamplePreviousBackbuffer(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return r_previous_interpolation_source.SampleLevel(s_LinearClamp, fUv, 0).xyz;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE
|
||||
Texture2D<FfxFloat32x4> r_current_interpolation_source : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_CURRENT_INTERPOLATION_SOURCE);
|
||||
|
||||
FfxFloat32x3 LoadCurrentBackbuffer(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_current_interpolation_source[iPxPos].rgb;
|
||||
}
|
||||
FfxFloat32x3 SampleCurrentBackbuffer(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return r_current_interpolation_source.SampleLevel(s_LinearClamp, fUv, 0).xyz;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_MOTION_VECTORS
|
||||
Texture2D<FfxFloat32x2> r_dilated_motion_vectors : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_MOTION_VECTORS);
|
||||
|
||||
FfxFloat32x2 LoadDilatedMotionVector(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_dilated_motion_vectors[iPxPos].xy;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH
|
||||
Texture2D<FfxFloat32> r_dilated_depth : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_DILATED_DEPTH);
|
||||
|
||||
FfxFloat32 LoadDilatedDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_dilated_depth[iPxPos].x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME
|
||||
Texture2D<FfxUInt32> r_reconstructed_depth_previous_frame : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME);
|
||||
|
||||
FfxFloat32 LoadReconstructedDepthPreviousFrame(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return asfloat(r_reconstructed_depth_previous_frame[iPxInput]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME
|
||||
Texture2D<FfxUInt32> r_reconstructed_depth_interpolated_frame : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME);
|
||||
|
||||
FfxFloat32 LoadEstimatedInterpolationFrameDepth(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return asfloat(r_reconstructed_depth_interpolated_frame[iPxInput]);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_DISOCCLUSION_MASK
|
||||
Texture2D<FfxFloat32x4> r_disocclusion_mask : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_DISOCCLUSION_MASK);
|
||||
|
||||
FfxFloat32x4 LoadDisocclusionMask(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_disocclusion_mask[iPxPos];
|
||||
}
|
||||
FfxFloat32x4 SampleDisocclusionMask(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return r_disocclusion_mask.SampleLevel(s_LinearClamp, fUv, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_Y)
|
||||
Texture2D<FfxUInt32> r_game_motion_vector_field_x : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_X);
|
||||
Texture2D<FfxUInt32> r_game_motion_vector_field_y : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_Y);
|
||||
|
||||
FfxUInt32x2 LoadGameFieldMv(FFX_PARAMETER_IN FfxInt32x2 iPxSample)
|
||||
{
|
||||
FfxUInt32 packedX = r_game_motion_vector_field_x[iPxSample];
|
||||
FfxUInt32 packedY = r_game_motion_vector_field_y[iPxSample];
|
||||
|
||||
return FfxUInt32x2(packedX, packedY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y)
|
||||
Texture2D<FfxUInt32> r_optical_flow_motion_vector_field_x : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X);
|
||||
Texture2D<FfxUInt32> r_optical_flow_motion_vector_field_y : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y);
|
||||
|
||||
FfxUInt32x2 LoadOpticalFlowFieldMv(FFX_PARAMETER_IN FfxInt32x2 iPxSample)
|
||||
{
|
||||
FfxUInt32 packedX = r_optical_flow_motion_vector_field_x[iPxSample];
|
||||
FfxUInt32 packedY = r_optical_flow_motion_vector_field_y[iPxSample];
|
||||
|
||||
return FfxUInt32x2(packedX, packedY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW
|
||||
Texture2D<FfxInt32x2> r_optical_flow : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW);
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
FfxFloat32x2 LoadOpticalFlow(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_optical_flow[iPxPos] * GetOpticalFlowScale();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_UPSAMPLED
|
||||
Texture2D<FfxFloat32x2> r_optical_flow_upsampled : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_UPSAMPLED);
|
||||
|
||||
FfxFloat32x2 LoadOpticalFlowUpsampled(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_optical_flow_upsampled[iPxPos];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_CONFIDENCE
|
||||
Texture2D<FfxUInt32x2> r_optical_flow_confidence : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_CONFIDENCE);
|
||||
|
||||
FfxFloat32 LoadOpticalFlowConfidence(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_optical_flow_confidence[iPxPos].y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION
|
||||
Texture2D<FfxUInt32> r_optical_flow_global_motion : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION);
|
||||
|
||||
FfxUInt32 LoadOpticalFlowGlobalMotion(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_optical_flow_global_motion[iPxPos];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_SCENE_CHANGE_DETECTION
|
||||
Texture2D<FfxUInt32> r_optical_flow_scd : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_SCENE_CHANGE_DETECTION);
|
||||
|
||||
FfxUInt32 LoadOpticalFlowSceneChangeDetection(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_optical_flow_scd[iPxPos];
|
||||
}
|
||||
|
||||
FfxBoolean HasSceneChanged()
|
||||
{
|
||||
#define SCD_OUTPUT_HISTORY_BITS_SLOT 1
|
||||
//if (FrameIndex() <= 5) // threshold according to original OpenCL code
|
||||
//{
|
||||
// return 1.0;
|
||||
//}
|
||||
//else
|
||||
{
|
||||
// Report that the scene is changed if the change was detected in any of the
|
||||
// 4 previous frames (0xfu - covers 4 history bits).
|
||||
return (r_optical_flow_scd[FfxInt32x2(SCD_OUTPUT_HISTORY_BITS_SLOT, 0)] & 0xfu) != 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_DEBUG
|
||||
Texture2D<FfxFloat32x4> r_optical_flow_debug : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_DEBUG);
|
||||
|
||||
FfxFloat32x4 LoadOpticalFlowDebug(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_optical_flow_debug[iPxPos];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_OUTPUT
|
||||
Texture2D<FfxFloat32x4> r_output : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_OUTPUT);
|
||||
|
||||
FfxFloat32x4 LoadFrameInterpolationOutput(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return r_output[iPxInput];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID
|
||||
Texture2D<FfxFloat32x4> r_inpainting_pyramid : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID);
|
||||
|
||||
FfxFloat32x4 LoadInpaintingPyramid(FFX_PARAMETER_IN FfxInt32 mipLevel, FFX_PARAMETER_IN FfxUInt32x2 iPxInput)
|
||||
{
|
||||
return r_inpainting_pyramid.mips[mipLevel][iPxInput];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_PRESENT_BACKBUFFER
|
||||
Texture2D<FfxFloat32x4> r_present_backbuffer : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_PRESENT_BACKBUFFER);
|
||||
|
||||
FfxFloat32x4 LoadPresentBackbuffer(FFX_PARAMETER_IN FfxInt32x2 iPxInput)
|
||||
{
|
||||
return r_present_backbuffer[iPxInput];
|
||||
}
|
||||
FfxFloat32x4 SamplePresentBackbuffer(FFX_PARAMETER_IN FfxFloat32x2 fUv)
|
||||
{
|
||||
return r_present_backbuffer.SampleLevel(s_LinearClamp, fUv, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_SRV_COUNTERS
|
||||
StructuredBuffer<FfxUInt32> r_counters : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_COUNTERS);
|
||||
|
||||
FfxUInt32 LoadCounter(FFX_PARAMETER_IN FfxInt32 iPxPos)
|
||||
{
|
||||
return r_counters[iPxPos];
|
||||
}
|
||||
|
||||
const FfxUInt32 FrameIndexSinceLastReset()
|
||||
{
|
||||
return LoadCounter(COUNTER_FRAME_INDEX_SINCE_LAST_RESET);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_DEPTH)
|
||||
Texture2D<FfxFloat32> r_input_depth : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_DEPTH);
|
||||
FfxFloat32 LoadInputDepth(FfxInt32x2 iPxPos)
|
||||
{
|
||||
return r_input_depth[iPxPos];
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
Texture2D<FfxFloat32x4> r_input_motion_vectors : FFX_DECLARE_SRV(FFX_FRAMEINTERPOLATION_BIND_SRV_INPUT_MOTION_VECTORS);
|
||||
FfxFloat32x2 LoadInputMotionVector(FfxInt32x2 iPxDilatedMotionVectorPos)
|
||||
{
|
||||
FfxFloat32x2 fSrcMotionVector = r_input_motion_vectors[iPxDilatedMotionVectorPos].xy;
|
||||
|
||||
FfxFloat32x2 fUvMotionVector = fSrcMotionVector * MotionVectorScale();
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_JITTERED_MOTION_VECTORS
|
||||
fUvMotionVector -= MotionVectorJitterCancellation();
|
||||
#endif
|
||||
|
||||
return fUvMotionVector;
|
||||
}
|
||||
#endif
|
||||
///////////////////////////////////////////////
|
||||
// declare UAVs and UAV accessors
|
||||
///////////////////////////////////////////////
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_OUTPUT
|
||||
RWTexture2D<FfxFloat32x4> rw_output : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_OUTPUT);
|
||||
|
||||
FfxFloat32x4 RWLoadFrameinterpolationOutput(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_output[iPxPos];
|
||||
}
|
||||
|
||||
void StoreFrameinterpolationOutput(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x4 val)
|
||||
{
|
||||
rw_output[iPxPos] = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_MOTION_VECTORS
|
||||
RWTexture2D<FfxFloat32x2> rw_dilated_motion_vectors : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_MOTION_VECTORS);
|
||||
|
||||
FfxFloat32x2 RWLoadDilatedMotionVectors(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_dilated_motion_vectors[iPxPos];
|
||||
}
|
||||
|
||||
void StoreDilatedMotionVectors(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x2 val)
|
||||
{
|
||||
rw_dilated_motion_vectors[iPxPos] = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_DEPTH
|
||||
RWTexture2D<FfxFloat32> rw_dilated_depth : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_DILATED_DEPTH);
|
||||
|
||||
FfxFloat32 RWLoadDilatedDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_dilated_depth[iPxPos];
|
||||
}
|
||||
|
||||
void StoreDilatedDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32 val)
|
||||
{
|
||||
rw_dilated_depth[iPxPos] = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME
|
||||
RWTexture2D<FfxUInt32> rw_reconstructed_depth_previous_frame : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME);
|
||||
|
||||
FfxFloat32 RWLoadReconstructedDepthPreviousFrame(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return ffxAsFloat(rw_reconstructed_depth_previous_frame[iPxPos]);
|
||||
}
|
||||
|
||||
void UpdateReconstructedDepthPreviousFrame(FfxInt32x2 iPxSample, FfxFloat32 fDepth)
|
||||
{
|
||||
FfxUInt32 uDepth = ffxAsUInt32(fDepth);
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH
|
||||
InterlockedMax(rw_reconstructed_depth_previous_frame[iPxSample], uDepth);
|
||||
#else
|
||||
InterlockedMin(rw_reconstructed_depth_previous_frame[iPxSample], uDepth); // min for standard, max for inverted depth
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME
|
||||
RWTexture2D<FfxUInt32> rw_reconstructed_depth_interpolated_frame : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME);
|
||||
|
||||
FfxFloat32 RWLoadReconstructedDepthInterpolatedFrame(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return ffxAsFloat(rw_reconstructed_depth_interpolated_frame[iPxPos]);
|
||||
}
|
||||
|
||||
void StoreReconstructedDepthInterpolatedFrame(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32 value)
|
||||
{
|
||||
FfxUInt32 uDepth = ffxAsUInt32(value);
|
||||
rw_reconstructed_depth_interpolated_frame[iPxPos] = uDepth;
|
||||
}
|
||||
|
||||
void UpdateReconstructedDepthInterpolatedFrame(FfxInt32x2 iPxSample, FfxFloat32 fDepth)
|
||||
{
|
||||
FfxUInt32 uDepth = ffxAsUInt32(fDepth);
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH
|
||||
InterlockedMax(rw_reconstructed_depth_interpolated_frame[iPxSample], uDepth);
|
||||
#else
|
||||
InterlockedMin(rw_reconstructed_depth_interpolated_frame[iPxSample], uDepth); // min for standard, max for inverted depth
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_DISOCCLUSION_MASK
|
||||
RWTexture2D<FfxFloat32x2> rw_disocclusion_mask : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_DISOCCLUSION_MASK);
|
||||
|
||||
FfxFloat32x2 RWLoadDisocclusionMask(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_disocclusion_mask[iPxPos];
|
||||
}
|
||||
|
||||
void StoreDisocclusionMask(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x2 val)
|
||||
{
|
||||
rw_disocclusion_mask[iPxPos] = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_Y)
|
||||
|
||||
RWTexture2D<FfxUInt32> rw_game_motion_vector_field_x : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_X);
|
||||
RWTexture2D<FfxUInt32> rw_game_motion_vector_field_y : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_GAME_MOTION_VECTOR_FIELD_Y);
|
||||
|
||||
FfxUInt32 RWLoadGameMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_game_motion_vector_field_x[iPxPos];
|
||||
}
|
||||
|
||||
void StoreGameMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
rw_game_motion_vector_field_x[iPxPos] = val;
|
||||
}
|
||||
|
||||
FfxUInt32 RWLoadGameMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_game_motion_vector_field_y[iPxPos];
|
||||
}
|
||||
|
||||
void StoreGameMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
rw_game_motion_vector_field_y[iPxPos] = val;
|
||||
}
|
||||
|
||||
void UpdateGameMotionVectorField(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32x2 packedVector)
|
||||
{
|
||||
InterlockedMax(rw_game_motion_vector_field_x[iPxPos], packedVector.x);
|
||||
InterlockedMax(rw_game_motion_vector_field_y[iPxPos], packedVector.y);
|
||||
}
|
||||
|
||||
FfxUInt32 UpdateGameMotionVectorFieldEx(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32x2 packedVector)
|
||||
{
|
||||
FfxUInt32 uPreviousValueX = 0;
|
||||
FfxUInt32 uPreviousValueY = 0;
|
||||
InterlockedMax(rw_game_motion_vector_field_x[iPxPos], packedVector.x, uPreviousValueX);
|
||||
InterlockedMax(rw_game_motion_vector_field_y[iPxPos], packedVector.y, uPreviousValueY);
|
||||
|
||||
const FfxUInt32 uExistingVectorFieldEntry = ffxMax(uPreviousValueX, uPreviousValueY);
|
||||
|
||||
return uExistingVectorFieldEntry;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y)
|
||||
|
||||
RWTexture2D<FfxUInt32> rw_optical_flow_motion_vector_field_x : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X);
|
||||
RWTexture2D<FfxUInt32> rw_optical_flow_motion_vector_field_y : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y);
|
||||
|
||||
FfxUInt32 RWLoadOpticalflowMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_optical_flow_motion_vector_field_x[iPxPos];
|
||||
}
|
||||
void StoreOpticalflowMotionVectorFieldX(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
rw_optical_flow_motion_vector_field_x[iPxPos] = val;
|
||||
}
|
||||
FfxUInt32 RWLoadOpticalflowMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos)
|
||||
{
|
||||
return rw_optical_flow_motion_vector_field_y[iPxPos];
|
||||
}
|
||||
void StoreOpticalflowMotionVectorFieldY(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 val)
|
||||
{
|
||||
rw_optical_flow_motion_vector_field_y[iPxPos] = val;
|
||||
}
|
||||
void UpdateOpticalflowMotionVectorField(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32x2 packedVector)
|
||||
{
|
||||
InterlockedMax(rw_optical_flow_motion_vector_field_x[iPxPos], packedVector.x);
|
||||
InterlockedMax(rw_optical_flow_motion_vector_field_y[iPxPos], packedVector.y);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FFX_FRAMEINTERPOLATION_BIND_UAV_COUNTERS
|
||||
globallycoherent RWStructuredBuffer<FfxUInt32> rw_counters : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_COUNTERS);
|
||||
|
||||
FfxUInt32 RWLoadCounter(FFX_PARAMETER_IN FfxInt32 iPxPos)
|
||||
{
|
||||
return rw_counters[iPxPos];
|
||||
}
|
||||
|
||||
void StoreCounter(FFX_PARAMETER_IN FfxInt32 iPxPos, FFX_PARAMETER_IN FfxUInt32 counter)
|
||||
{
|
||||
rw_counters[iPxPos] = counter;
|
||||
}
|
||||
void AtomicIncreaseCounter(FFX_PARAMETER_IN FfxInt32 iPxPos, FFX_PARAMETER_OUT FfxUInt32 oldVal)
|
||||
{
|
||||
InterlockedAdd(rw_counters[iPxPos], 1, oldVal);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_0) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_1) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_2) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_3) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_4) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_5) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_6) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_7) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_8) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_9) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_10) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_11) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_12)
|
||||
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid0 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_0);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid1 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_1);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid2 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_2);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid3 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_3);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid4 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_4);
|
||||
globallycoherent RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid5 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_5);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid6 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_6);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid7 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_7);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid8 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_8);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid9 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_9);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid10 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_10);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid11 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_11);
|
||||
RWTexture2D<FfxFloat32x4> rw_inpainting_pyramid12 : FFX_DECLARE_UAV(FFX_FRAMEINTERPOLATION_BIND_UAV_INPAINTING_PYRAMID_MIPMAP_12);
|
||||
|
||||
|
||||
FfxFloat32x4 RWLoadInpaintingPyramid(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxUInt32 index)
|
||||
{
|
||||
#define LOAD(idx) \
|
||||
if (index == idx) \
|
||||
{ \
|
||||
return rw_inpainting_pyramid##idx[iPxPos]; \
|
||||
}
|
||||
LOAD(0);
|
||||
LOAD(1);
|
||||
LOAD(2);
|
||||
LOAD(3);
|
||||
LOAD(4);
|
||||
LOAD(5);
|
||||
LOAD(6);
|
||||
LOAD(7);
|
||||
LOAD(8);
|
||||
LOAD(9);
|
||||
LOAD(10);
|
||||
LOAD(11);
|
||||
LOAD(12);
|
||||
return 0;
|
||||
|
||||
#undef LOAD
|
||||
}
|
||||
|
||||
void StoreInpaintingPyramid(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxFloat32x4 outValue, FFX_PARAMETER_IN FfxUInt32 index)
|
||||
{
|
||||
#define STORE(idx) \
|
||||
if (index == idx) \
|
||||
{ \
|
||||
rw_inpainting_pyramid##idx[iPxPos] = outValue; \
|
||||
}
|
||||
|
||||
STORE(0);
|
||||
STORE(1);
|
||||
STORE(2);
|
||||
STORE(3);
|
||||
STORE(4);
|
||||
STORE(5);
|
||||
STORE(6);
|
||||
STORE(7);
|
||||
STORE(8);
|
||||
STORE(9);
|
||||
STORE(10);
|
||||
STORE(11);
|
||||
STORE(12);
|
||||
|
||||
#undef STORE
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
@@ -0,0 +1,445 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#if !defined(FFX_FRAMEINTERPOLATION_COMMON_H)
|
||||
#define FFX_FRAMEINTERPOLATION_COMMON_H
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_TEAR_LINES (1 << 0)
|
||||
#define FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_RESET_INDICATORS (1 << 1)
|
||||
#define FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_VIEW (1 << 2)
|
||||
|
||||
FFX_STATIC const FfxFloat32 FFX_FRAMEINTERPOLATION_EPSILON = 1e-03f;
|
||||
FFX_STATIC const FfxFloat32 FFX_FRAMEINTERPOLATION_FLT_MAX = 3.402823466e+38f;
|
||||
FFX_STATIC const FfxFloat32 FFX_FRAMEINTERPOLATION_FLT_MIN = 1.175494351e-38f;
|
||||
|
||||
FFX_STATIC const FfxFloat32 fReconstructedDepthBilinearWeightThreshold = FFX_FRAMEINTERPOLATION_EPSILON;
|
||||
|
||||
FfxFloat32 RGBToLuma(FfxFloat32x3 fLinearRgb)
|
||||
{
|
||||
return dot(fLinearRgb, FfxFloat32x3(0.2126f, 0.7152f, 0.0722f));
|
||||
}
|
||||
|
||||
FfxFloat32 LinearRec2020ToLuminance(FfxFloat32x3 linearRec2020RGB)
|
||||
{
|
||||
FfxFloat32 fY = 0.2627 * linearRec2020RGB.x + 0.678 * linearRec2020RGB.y + 0.0593 * linearRec2020RGB.z;
|
||||
return fY;
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxscRGBToLinear(FfxFloat32x3 value, FfxFloat32 minLuminance, FfxFloat32 maxLuminance)
|
||||
{
|
||||
FfxFloat32x3 p = value - ffxBroadcast3(minLuminance / 80.0f);
|
||||
return p / ffxBroadcast3((maxLuminance - minLuminance) / 80.0f);
|
||||
}
|
||||
|
||||
FfxFloat32x3 RawRGBToLinear(FfxFloat32x3 fRawRgb)
|
||||
{
|
||||
FfxFloat32x3 fLinearRgb;
|
||||
|
||||
switch (BackBufferTransferFunction())
|
||||
{
|
||||
case 0:
|
||||
fLinearRgb = ffxLinearFromSrgb(fRawRgb);
|
||||
break;
|
||||
case 1:
|
||||
fLinearRgb = ffxLinearFromPQ(fRawRgb) * (10000.0f / MaxLuminance());
|
||||
break;
|
||||
case 2:
|
||||
fLinearRgb = ffxscRGBToLinear(fRawRgb, MinLuminance(), MaxLuminance());
|
||||
break;
|
||||
}
|
||||
|
||||
return fLinearRgb;
|
||||
}
|
||||
|
||||
FfxFloat32 RawRGBToLuminance(FfxFloat32x3 fRawRgb)
|
||||
{
|
||||
FfxFloat32 fLuminance = 0.0f;
|
||||
|
||||
switch (BackBufferTransferFunction())
|
||||
{
|
||||
case 0:
|
||||
fLuminance = RGBToLuma(RawRGBToLinear(fRawRgb));
|
||||
break;
|
||||
case 1:
|
||||
fLuminance = LinearRec2020ToLuminance(RawRGBToLinear(fRawRgb));
|
||||
break;
|
||||
case 2:
|
||||
fLuminance = RGBToLuma(RawRGBToLinear(fRawRgb));
|
||||
break;
|
||||
}
|
||||
|
||||
return fLuminance;
|
||||
}
|
||||
|
||||
FfxFloat32 RawRGBToPerceivedLuma(FfxFloat32x3 fRawRgb)
|
||||
{
|
||||
FfxFloat32 fLuminance = RawRGBToLuminance(fRawRgb);
|
||||
|
||||
FfxFloat32 fPercievedLuminance = 0;
|
||||
if (fLuminance <= 216.0f / 24389.0f)
|
||||
{
|
||||
fPercievedLuminance = fLuminance * (24389.0f / 27.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
fPercievedLuminance = ffxPow(fLuminance, 1.0f / 3.0f) * 116.0f - 16.0f;
|
||||
}
|
||||
|
||||
return fPercievedLuminance * 0.01f;
|
||||
}
|
||||
|
||||
struct BilinearSamplingData
|
||||
{
|
||||
FfxInt32x2 iOffsets[4];
|
||||
FfxFloat32 fWeights[4];
|
||||
FfxInt32x2 iBasePos;
|
||||
};
|
||||
|
||||
BilinearSamplingData GetBilinearSamplingData(FfxFloat32x2 fUv, FfxInt32x2 iSize)
|
||||
{
|
||||
BilinearSamplingData data;
|
||||
|
||||
FfxFloat32x2 fPxSample = (fUv * iSize) - FfxFloat32x2(0.5f, 0.5f);
|
||||
data.iBasePos = FfxInt32x2(floor(fPxSample));
|
||||
FfxFloat32x2 fPxFrac = ffxFract(fPxSample);
|
||||
|
||||
data.iOffsets[0] = FfxInt32x2(0, 0);
|
||||
data.iOffsets[1] = FfxInt32x2(1, 0);
|
||||
data.iOffsets[2] = FfxInt32x2(0, 1);
|
||||
data.iOffsets[3] = FfxInt32x2(1, 1);
|
||||
|
||||
data.fWeights[0] = (1 - fPxFrac.x) * (1 - fPxFrac.y);
|
||||
data.fWeights[1] = (fPxFrac.x) * (1 - fPxFrac.y);
|
||||
data.fWeights[2] = (1 - fPxFrac.x) * (fPxFrac.y);
|
||||
data.fWeights[3] = (fPxFrac.x) * (fPxFrac.y);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
FfxFloat32 ConvertFromDeviceDepthToViewSpace(FfxFloat32 fDeviceDepth)
|
||||
{
|
||||
const FfxFloat32x4 deviceToViewDepth = DeviceToViewSpaceTransformFactors();
|
||||
return deviceToViewDepth[1] / (fDeviceDepth - deviceToViewDepth[0]);
|
||||
}
|
||||
|
||||
FfxFloat32x2 ComputeNdc(FfxFloat32x2 fPxPos, FfxInt32x2 iSize)
|
||||
{
|
||||
return fPxPos / FfxFloat32x2(iSize) * FfxFloat32x2(2.0f, -2.0f) + FfxFloat32x2(-1.0f, 1.0f);
|
||||
}
|
||||
|
||||
FfxFloat32x3 GetViewSpacePosition(FfxInt32x2 iViewportPos, FfxInt32x2 iViewportSize, FfxFloat32 fDeviceDepth)
|
||||
{
|
||||
const FfxFloat32x4 fDeviceToViewDepth = DeviceToViewSpaceTransformFactors();
|
||||
|
||||
const FfxFloat32 Z = ConvertFromDeviceDepthToViewSpace(fDeviceDepth);
|
||||
|
||||
const FfxFloat32x2 fNdcPos = ComputeNdc(iViewportPos, iViewportSize);
|
||||
const FfxFloat32 X = fDeviceToViewDepth[2] * fNdcPos.x * Z;
|
||||
const FfxFloat32 Y = fDeviceToViewDepth[3] * fNdcPos.y * Z;
|
||||
|
||||
return FfxFloat32x3(X, Y, Z);
|
||||
}
|
||||
#endif
|
||||
|
||||
FfxBoolean IsOnScreen(FfxInt32x2 pos, FfxInt32x2 size)
|
||||
{
|
||||
return all(FFX_LESS_THAN(FfxUInt32x2(pos), FfxUInt32x2(size)));
|
||||
}
|
||||
|
||||
FfxBoolean IsUvInside(FfxFloat32x2 fUv)
|
||||
{
|
||||
return (fUv.x > 0.0f && fUv.x < 1.0f) && (fUv.y > 0.0f && fUv.y < 1.0f);
|
||||
}
|
||||
|
||||
FfxBoolean IsInRect(FfxInt32x2 pos, FfxInt32x2 iRectCorner, FfxInt32x2 iRectSize)
|
||||
{
|
||||
return (pos.x >= iRectCorner.x && pos.x < (iRectSize.x + iRectCorner.x) && pos.y >= iRectCorner.y && pos.y < (iRectSize.y + iRectCorner.y));
|
||||
}
|
||||
|
||||
FfxFloat32 MinDividedByMax(const FfxFloat32 v0, const FfxFloat32 v1)
|
||||
{
|
||||
const FfxFloat32 m = ffxMax(v0, v1);
|
||||
return m != 0 ? ffxMin(v0, v1) / m : 0;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalizedDot3(const FfxFloat32x3 v0, const FfxFloat32x3 v1)
|
||||
{
|
||||
FfxFloat32 fMaxLength = ffxMax(length(v0), length(v1));
|
||||
|
||||
return fMaxLength > 0.0f ? dot(v0 / fMaxLength, v1 / fMaxLength) : 1.0f;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalizedDot2(const FfxFloat32x2 v0, const FfxFloat32x2 v1)
|
||||
{
|
||||
FfxFloat32 fMaxLength = ffxMax(length(v0), length(v1));
|
||||
|
||||
return fMaxLength > 0.0f ? dot(v0 / fMaxLength, v1 / fMaxLength) : 1.0f;
|
||||
}
|
||||
|
||||
FfxFloat32 CalculateStaticContentFactor(FfxFloat32x3 fCurrentInterpolationSource, FfxFloat32x3 fPresentColor)
|
||||
{
|
||||
const FfxFloat32x3 fFactor = ffxSaturate(FfxFloat32x3(
|
||||
ffxSaturate((1.0f - MinDividedByMax(fCurrentInterpolationSource.r, fPresentColor.r)) / 0.1f),
|
||||
ffxSaturate((1.0f - MinDividedByMax(fCurrentInterpolationSource.g, fPresentColor.g)) / 0.1f),
|
||||
ffxSaturate((1.0f - MinDividedByMax(fCurrentInterpolationSource.b, fPresentColor.b)) / 0.1f)
|
||||
));
|
||||
|
||||
return max(fFactor.x, max(fFactor.y, fFactor.z));
|
||||
}
|
||||
|
||||
//
|
||||
// MOTION VECTOR FIELD
|
||||
//
|
||||
|
||||
FFX_STATIC const FfxUInt32 MOTION_VECTOR_FIELD_ENTRY_BIT_COUNT = 32;
|
||||
|
||||
// Make sure all bit counts add up to MOTION_VECTOR_FIELD_ENTRY_BIT_COUNT
|
||||
FFX_STATIC const FfxUInt32 MOTION_VECTOR_FIELD_VECTOR_COEFFICIENT_BIT_COUNT = 16;
|
||||
FFX_STATIC const FfxUInt32 MOTION_VECTOR_FIELD_PRIORITY_LOW_BIT_COUNT = 5;
|
||||
FFX_STATIC const FfxUInt32 MOTION_VECTOR_FIELD_PRIORITY_HIGH_BIT_COUNT = 10;
|
||||
FFX_STATIC const FfxUInt32 MOTION_VECTOR_PRIMARY_VECTOR_INDICATION_BIT_COUNT = 1;
|
||||
|
||||
FFX_STATIC const FfxUInt32 MOTION_VECTOR_FIELD_PRIMARY_VECTOR_INDICATION_BIT = (1U << (MOTION_VECTOR_FIELD_ENTRY_BIT_COUNT - 1));
|
||||
|
||||
FFX_STATIC const FfxUInt32 PRIORITY_LOW_MAX = (1U << MOTION_VECTOR_FIELD_PRIORITY_LOW_BIT_COUNT) - 1;
|
||||
FFX_STATIC const FfxUInt32 PRIORITY_HIGH_MAX = (1U << MOTION_VECTOR_FIELD_PRIORITY_HIGH_BIT_COUNT) - 1;
|
||||
|
||||
FFX_STATIC const FfxUInt32 PRIORITY_LOW_OFFSET = MOTION_VECTOR_FIELD_VECTOR_COEFFICIENT_BIT_COUNT;
|
||||
FFX_STATIC const FfxUInt32 PRIORITY_HIGH_OFFSET = PRIORITY_LOW_OFFSET + MOTION_VECTOR_FIELD_PRIORITY_LOW_BIT_COUNT;
|
||||
FFX_STATIC const FfxUInt32 PRIMARY_VECTOR_INDICATION_OFFSET = PRIORITY_HIGH_OFFSET + MOTION_VECTOR_FIELD_PRIORITY_HIGH_BIT_COUNT;
|
||||
|
||||
struct VectorFieldEntry
|
||||
{
|
||||
FfxFloat32x2 fMotionVector;
|
||||
FfxFloat32 uHighPriorityFactor;
|
||||
FfxFloat32 uLowPriorityFactor;
|
||||
FfxBoolean bValid;
|
||||
FfxBoolean bPrimary;
|
||||
FfxBoolean bSecondary;
|
||||
FfxBoolean bInPainted;
|
||||
FfxFloat32 fVelocity;
|
||||
FfxBoolean bNegOutside;
|
||||
FfxBoolean bPosOutside;
|
||||
};
|
||||
|
||||
VectorFieldEntry NewVectorFieldEntry()
|
||||
{
|
||||
VectorFieldEntry vfe;
|
||||
vfe.fMotionVector = FfxFloat32x2(0.0, 0.0);
|
||||
vfe.uHighPriorityFactor = 0.0;
|
||||
vfe.uLowPriorityFactor = 0.0;
|
||||
vfe.bValid = false;
|
||||
vfe.bPrimary = false;
|
||||
vfe.bSecondary = false;
|
||||
vfe.bInPainted = false;
|
||||
vfe.fVelocity = 0.0;
|
||||
vfe.bNegOutside = false;
|
||||
vfe.bPosOutside = false;
|
||||
return vfe;
|
||||
}
|
||||
|
||||
FfxBoolean PackedVectorFieldEntryIsPrimary(FfxUInt32 packedEntry)
|
||||
{
|
||||
return ((packedEntry & MOTION_VECTOR_FIELD_PRIMARY_VECTOR_INDICATION_BIT) != 0);
|
||||
}
|
||||
|
||||
FfxUInt32x2 PackVectorFieldEntries(FfxBoolean bIsPrimary, FfxUInt32 uHighPriorityFactor, FfxUInt32 uLowPriorityFactor, FfxFloat32x2 fMotionVector)
|
||||
{
|
||||
const FfxUInt32 uPriority =
|
||||
(FfxUInt32(bIsPrimary) * MOTION_VECTOR_FIELD_PRIMARY_VECTOR_INDICATION_BIT)
|
||||
| ((uHighPriorityFactor & PRIORITY_HIGH_MAX) << PRIORITY_HIGH_OFFSET)
|
||||
| ((uLowPriorityFactor & PRIORITY_LOW_MAX) << PRIORITY_LOW_OFFSET);
|
||||
|
||||
FfxUInt32 packedX = uPriority | ffxF32ToF16(fMotionVector.x);
|
||||
FfxUInt32 packedY = uPriority | ffxF32ToF16(fMotionVector.y);
|
||||
|
||||
return FfxUInt32x2(packedX, packedY);
|
||||
}
|
||||
|
||||
void UnpackVectorFieldEntries(FfxUInt32x2 packed, out VectorFieldEntry vfElement)
|
||||
{
|
||||
vfElement.uHighPriorityFactor = FfxFloat32((packed.x >> PRIORITY_HIGH_OFFSET) & PRIORITY_HIGH_MAX) / PRIORITY_HIGH_MAX;
|
||||
vfElement.uLowPriorityFactor = FfxFloat32((packed.x >> PRIORITY_LOW_OFFSET) & PRIORITY_LOW_MAX) / PRIORITY_LOW_MAX;
|
||||
|
||||
vfElement.bPrimary = PackedVectorFieldEntryIsPrimary(packed.x);
|
||||
vfElement.bValid = (vfElement.uHighPriorityFactor > 0.0f);
|
||||
vfElement.bSecondary = vfElement.bValid && !vfElement.bPrimary;
|
||||
|
||||
// Reverse priority factor for secondary vectors
|
||||
if (vfElement.bSecondary)
|
||||
{
|
||||
vfElement.uHighPriorityFactor = 1.0f - vfElement.uHighPriorityFactor;
|
||||
}
|
||||
|
||||
vfElement.fMotionVector.x = ffxUnpackF32(packed.x).x;
|
||||
vfElement.fMotionVector.y = ffxUnpackF32(packed.y).x;
|
||||
vfElement.bInPainted = false;
|
||||
}
|
||||
|
||||
//
|
||||
// MOTION VECTOR FIELD
|
||||
//
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_INPAINTING_PYRAMID)
|
||||
FfxFloat32x4 ComputeMvInpaintingLevel(FfxFloat32x2 fUv, const FfxInt32 iMipLevel, const FfxInt32x2 iTexSize)
|
||||
{
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUv, iTexSize);
|
||||
|
||||
FfxFloat32 fSum = 0.0f;
|
||||
FfxFloat32x4 fColor = FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
|
||||
fColor.z = 0;
|
||||
|
||||
const FfxFloat32 fMaxPriorityFactor = 1.0f;
|
||||
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++)
|
||||
{
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
if (IsOnScreen(iSamplePos, iTexSize))
|
||||
{
|
||||
FfxFloat32x4 fSample = LoadInpaintingPyramid(iMipLevel, iSamplePos);
|
||||
|
||||
const FfxFloat32 fPriorityFactor = fSample.z;
|
||||
const FfxFloat32 fValidMvFactor = FfxFloat32(fSample.z > 0);
|
||||
const FfxFloat32 fSampleWeight = bilinearInfo.fWeights[iSampleIndex] * fValidMvFactor * fPriorityFactor;
|
||||
|
||||
fSum += fSampleWeight;
|
||||
fColor += fSample * fSampleWeight;
|
||||
}
|
||||
}
|
||||
|
||||
fColor /= (fSum > 0.0f) ? fSum : 1.0f;
|
||||
|
||||
return fColor;
|
||||
}
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_SRV_GAME_MOTION_VECTOR_FIELD_Y)
|
||||
|
||||
void LoadInpaintedGameFieldMv(FfxFloat32x2 fUv, out VectorFieldEntry vfElement)
|
||||
{
|
||||
FfxInt32x2 iPxSample = FfxInt32x2(fUv * RenderSize());
|
||||
FfxUInt32x2 packedGameFieldMv = LoadGameFieldMv(iPxSample);
|
||||
UnpackVectorFieldEntries(packedGameFieldMv, vfElement);
|
||||
|
||||
if (!vfElement.bValid)
|
||||
{
|
||||
//FfxFloat32x2 fUv = (FfxFloat32x2(iPxSample) + 0.5f) / RenderSize();
|
||||
FfxInt32x2 iTexSize = RenderSize();
|
||||
|
||||
FfxFloat32x4 fInPaintedVector = FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
|
||||
for (FfxInt32 iMipLevel = 0; iMipLevel < 11 && (fInPaintedVector.w == 0.0f); iMipLevel++)
|
||||
{
|
||||
iTexSize /= 2;
|
||||
|
||||
fInPaintedVector = ComputeMvInpaintingLevel(fUv, iMipLevel, iTexSize);
|
||||
}
|
||||
|
||||
vfElement.fMotionVector = fInPaintedVector.xy;
|
||||
vfElement.uHighPriorityFactor = fInPaintedVector.z;
|
||||
vfElement.uLowPriorityFactor = fInPaintedVector.w;
|
||||
vfElement.bInPainted = true;
|
||||
}
|
||||
|
||||
vfElement.bNegOutside = !IsUvInside(fUv - vfElement.fMotionVector);
|
||||
vfElement.bPosOutside = !IsUvInside(fUv + vfElement.fMotionVector);
|
||||
vfElement.fVelocity = length(vfElement.fMotionVector);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_SRV_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y) && \
|
||||
defined(FFX_FRAMEINTERPOLATION_BIND_CB_FRAMEINTERPOLATION)
|
||||
void SampleOpticalFlowMotionVectorField(FfxFloat32x2 fUv, out VectorFieldEntry vfElement)
|
||||
{
|
||||
const FfxFloat32 scaleFactor = 1.0f;
|
||||
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUv, FfxInt32x2(GetOpticalFlowSize2() * scaleFactor));
|
||||
|
||||
vfElement = NewVectorFieldEntry();
|
||||
|
||||
FfxFloat32 fWeightSum = 0.0f;
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++)
|
||||
{
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
if (IsOnScreen(iSamplePos, FfxInt32x2(GetOpticalFlowSize2() * scaleFactor)))
|
||||
{
|
||||
const FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex];
|
||||
|
||||
VectorFieldEntry fOfVectorSample = NewVectorFieldEntry();
|
||||
FfxInt32x2 packedOpticalFlowMv = FfxInt32x2(LoadOpticalFlowFieldMv(iSamplePos));
|
||||
UnpackVectorFieldEntries(packedOpticalFlowMv, fOfVectorSample);
|
||||
|
||||
vfElement.fMotionVector += fOfVectorSample.fMotionVector * fWeight;
|
||||
vfElement.uHighPriorityFactor += fOfVectorSample.uHighPriorityFactor * fWeight;
|
||||
vfElement.uLowPriorityFactor += fOfVectorSample.uLowPriorityFactor * fWeight;
|
||||
|
||||
fWeightSum += fWeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (fWeightSum > 0.0f)
|
||||
{
|
||||
vfElement.fMotionVector /= fWeightSum;
|
||||
vfElement.uHighPriorityFactor /= fWeightSum;
|
||||
vfElement.uLowPriorityFactor /= fWeightSum;
|
||||
}
|
||||
|
||||
vfElement.bNegOutside = !IsUvInside(fUv - vfElement.fMotionVector);
|
||||
vfElement.bPosOutside = !IsUvInside(fUv + vfElement.fMotionVector);
|
||||
vfElement.fVelocity = length(vfElement.fMotionVector);
|
||||
}
|
||||
#endif
|
||||
|
||||
FfxFloat32x3 Tonemap(FfxFloat32x3 fRgb)
|
||||
{
|
||||
return fRgb / (ffxMax(ffxMax(0.f, fRgb.r), ffxMax(fRgb.g, fRgb.b)) + 1.f).xxx;
|
||||
}
|
||||
|
||||
FfxFloat32x3 InverseTonemap(FfxFloat32x3 fRgb)
|
||||
{
|
||||
return fRgb / ffxMax(FFX_TONEMAP_EPSILON, 1.f - ffxMax(fRgb.r, ffxMax(fRgb.g, fRgb.b))).xxx;
|
||||
}
|
||||
|
||||
FfxInt32x2 ComputeHrPosFromLrPos(FfxInt32x2 iPxLrPos)
|
||||
{
|
||||
FfxFloat32x2 fSrcJitteredPos = FfxFloat32x2(iPxLrPos) + 0.5f - Jitter();
|
||||
FfxFloat32x2 fLrPosInHr = (fSrcJitteredPos / RenderSize()) * DisplaySize();
|
||||
FfxInt32x2 iPxHrPos = FfxInt32x2(floor(fLrPosInHr));
|
||||
return iPxHrPos;
|
||||
}
|
||||
#if FFX_HALF
|
||||
FFX_MIN16_I2 ComputeHrPosFromLrPos(FFX_MIN16_I2 iPxLrPos)
|
||||
{
|
||||
FFX_MIN16_F2 fSrcJitteredPos = FFX_MIN16_F2(iPxLrPos) + FFX_MIN16_F(0.5f) - FFX_MIN16_F2(Jitter());
|
||||
FFX_MIN16_F2 fLrPosInHr = (fSrcJitteredPos / FFX_MIN16_F2(RenderSize())) * FFX_MIN16_F2(DisplaySize());
|
||||
FFX_MIN16_I2 iPxHrPos = FFX_MIN16_I2(floor(fLrPosInHr));
|
||||
return iPxHrPos;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //!defined(FFX_FRAMEINTERPOLATION_COMMON_H)
|
||||
@@ -0,0 +1,121 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_COMPUTE_GAME_VECTOR_FIELD_INPAINTING_PYRAMID_H
|
||||
#define FFX_FRAMEINTERPOLATION_COMPUTE_GAME_VECTOR_FIELD_INPAINTING_PYRAMID_H
|
||||
|
||||
#include "ffx_frameinterpolation_common.h"
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Buffer definitions - global atomic counter
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 spdCounter;
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateR[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateG[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateB[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateA[16][16];
|
||||
|
||||
FfxFloat32x4 SpdLoadSourceImage(FfxInt32x2 tex, FfxUInt32 slice)
|
||||
{
|
||||
VectorFieldEntry gameMv;
|
||||
FfxUInt32x2 packedGameFieldMv = LoadGameFieldMv(tex);
|
||||
UnpackVectorFieldEntries(packedGameFieldMv, gameMv);
|
||||
|
||||
return FfxFloat32x4(gameMv.fMotionVector, gameMv.uHighPriorityFactor, gameMv.uLowPriorityFactor) * FfxFloat32(DisplaySize().x > 0);
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdLoad(FfxInt32x2 tex, FfxUInt32 slice)
|
||||
{
|
||||
return RWLoadInpaintingPyramid(tex, 5);
|
||||
}
|
||||
|
||||
void SpdStore(FfxInt32x2 pix, FfxFloat32x4 outValue, FfxUInt32 index, FfxUInt32 slice)
|
||||
{
|
||||
StoreInpaintingPyramid(pix, outValue, index);
|
||||
}
|
||||
|
||||
void SpdIncreaseAtomicCounter(FfxUInt32 slice)
|
||||
{
|
||||
AtomicIncreaseCounter(COUNTER_SPD, spdCounter);
|
||||
}
|
||||
|
||||
FfxUInt32 SpdGetAtomicCounter()
|
||||
{
|
||||
return spdCounter;
|
||||
}
|
||||
void SpdResetAtomicCounter(FfxUInt32 slice)
|
||||
{
|
||||
StoreCounter(COUNTER_SPD, 0);
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdLoadIntermediate(FfxUInt32 x, FfxUInt32 y)
|
||||
{
|
||||
return FfxFloat32x4(
|
||||
spdIntermediateR[x][y],
|
||||
spdIntermediateG[x][y],
|
||||
spdIntermediateB[x][y],
|
||||
spdIntermediateA[x][y]);
|
||||
}
|
||||
|
||||
void SpdStoreIntermediate(FfxUInt32 x, FfxUInt32 y, FfxFloat32x4 value)
|
||||
{
|
||||
spdIntermediateR[x][y] = value.x;
|
||||
spdIntermediateG[x][y] = value.y;
|
||||
spdIntermediateB[x][y] = value.z;
|
||||
spdIntermediateA[x][y] = value.w;
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdReduce4(FfxFloat32x4 v0, FfxFloat32x4 v1, FfxFloat32x4 v2, FfxFloat32x4 v3)
|
||||
{
|
||||
FfxFloat32x4 vec = FfxFloat32x4(0,0,0,0);
|
||||
|
||||
FfxFloat32 fWeightSum = 0.0f;
|
||||
#define ADD(SAMPLE) { \
|
||||
FfxFloat32 fWeight = FfxFloat32(SAMPLE.z > 0.0f); \
|
||||
vec += SAMPLE * fWeight; \
|
||||
fWeightSum += fWeight; \
|
||||
}
|
||||
|
||||
ADD(v0);
|
||||
ADD(v1);
|
||||
ADD(v2);
|
||||
ADD(v3);
|
||||
|
||||
vec /= (fWeightSum > FFX_FRAMEINTERPOLATION_EPSILON) ? fWeightSum : 1.0f;
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
#include "spd/ffx_spd.h"
|
||||
|
||||
void computeFrameinterpolationGameVectorFieldInpaintingPyramid(FfxInt32x3 iGroupId, FfxInt32 iLocalIndex)
|
||||
{
|
||||
SpdDownsample(
|
||||
FfxUInt32x2(iGroupId.xy),
|
||||
FfxUInt32(iLocalIndex),
|
||||
FfxUInt32(NumMips()),
|
||||
FfxUInt32(NumWorkGroups()),
|
||||
FfxUInt32(iGroupId.z),
|
||||
FfxUInt32x2(WorkGroupOffset()));
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_COMPUTE_GAME_VECTOR_FIELD_INPAINTING_PYRAMID_H
|
||||
@@ -0,0 +1,120 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_COMPUTE_INPAINTING_PYRAMID_H
|
||||
#define FFX_FRAMEINTERPOLATION_COMPUTE_INPAINTING_PYRAMID_H
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Buffer definitions - global atomic counter
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 spdCounter;
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateR[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateG[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateB[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 spdIntermediateA[16][16];
|
||||
|
||||
FfxFloat32x4 SpdLoadSourceImage(FfxInt32x2 tex, FfxUInt32 slice)
|
||||
{
|
||||
FfxFloat32x4 fColor = LoadFrameInterpolationOutput(tex) * FfxFloat32(DisplaySize().x > 0);
|
||||
|
||||
// reverse sample weights
|
||||
fColor.w = ffxSaturate(1.0f - fColor.w);
|
||||
|
||||
|
||||
if (tex.x < InterpolationRectBase().x || tex.x >= (InterpolationRectSize().x + InterpolationRectBase().x) || tex.y < InterpolationRectBase().y ||
|
||||
tex.y >= (InterpolationRectSize().y + InterpolationRectBase().y))
|
||||
{
|
||||
fColor.w = 0.0f; // don't take contributions from outside of the interpolation rect
|
||||
}
|
||||
|
||||
return fColor;
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdLoad(FfxInt32x2 tex, FfxUInt32 slice)
|
||||
{
|
||||
return RWLoadInpaintingPyramid(tex, 5);
|
||||
}
|
||||
|
||||
void SpdStore(FfxInt32x2 pix, FfxFloat32x4 outValue, FfxUInt32 index, FfxUInt32 slice)
|
||||
{
|
||||
StoreInpaintingPyramid(pix, outValue, index);
|
||||
}
|
||||
|
||||
void SpdIncreaseAtomicCounter(FfxUInt32 slice)
|
||||
{
|
||||
AtomicIncreaseCounter(COUNTER_SPD, spdCounter);
|
||||
}
|
||||
|
||||
FfxUInt32 SpdGetAtomicCounter()
|
||||
{
|
||||
return spdCounter;
|
||||
}
|
||||
void SpdResetAtomicCounter(FfxUInt32 slice)
|
||||
{
|
||||
StoreCounter(COUNTER_SPD, 0);
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdLoadIntermediate(FfxUInt32 x, FfxUInt32 y)
|
||||
{
|
||||
return FfxFloat32x4(
|
||||
spdIntermediateR[x][y],
|
||||
spdIntermediateG[x][y],
|
||||
spdIntermediateB[x][y],
|
||||
spdIntermediateA[x][y]);
|
||||
}
|
||||
|
||||
void SpdStoreIntermediate(FfxUInt32 x, FfxUInt32 y, FfxFloat32x4 value)
|
||||
{
|
||||
spdIntermediateR[x][y] = value.x;
|
||||
spdIntermediateG[x][y] = value.y;
|
||||
spdIntermediateB[x][y] = value.z;
|
||||
spdIntermediateA[x][y] = value.w;
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdReduce4(FfxFloat32x4 v0, FfxFloat32x4 v1, FfxFloat32x4 v2, FfxFloat32x4 v3)
|
||||
{
|
||||
FfxFloat32x4 w = FfxFloat32x4(v0.w, v1.w, v2.w, v3.w);
|
||||
|
||||
FfxFloat32 sum = (w[0] + w[1] + w[2] + w[3]);
|
||||
|
||||
if (sum == 0.0f) {
|
||||
return FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
return (v0 * w[0] + v1 * w[1] + v2 * w[2] + v3 * w[3]) / sum;
|
||||
}
|
||||
|
||||
#include "spd/ffx_spd.h"
|
||||
|
||||
void computeFrameinterpolationInpaintingPyramid(FfxInt32x3 iGroupId, FfxInt32 iLocalIndex)
|
||||
{
|
||||
SpdDownsample(
|
||||
FfxUInt32x2(iGroupId.xy),
|
||||
FfxUInt32(iLocalIndex),
|
||||
FfxUInt32(NumMips()),
|
||||
FfxUInt32(NumWorkGroups()),
|
||||
FfxUInt32(iGroupId.z),
|
||||
FfxUInt32x2(WorkGroupOffset()));
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_COMPUTE_INPAINTING_PYRAMID_H
|
||||
@@ -0,0 +1,163 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_DEBUG_VIEW_H
|
||||
#define FFX_FRAMEINTERPOLATION_DEBUG_VIEW_H
|
||||
|
||||
struct FfxFrameInterpolationDebugViewport
|
||||
{
|
||||
FfxInt32x2 offset;
|
||||
FfxInt32x2 size;
|
||||
};
|
||||
|
||||
// Macro to cull and draw debug viewport
|
||||
#define DRAW_VIEWPORT(function, pos, vp) \
|
||||
{ \
|
||||
if (pointIsInsideViewport(pos, vp)) \
|
||||
{ \
|
||||
function(pos, vp); \
|
||||
} \
|
||||
}
|
||||
|
||||
FfxFloat32x2 getTransformedUv(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxFloat32x2 fUv = (FfxFloat32x2(iPxPos - vp.offset) + 0.5f) / vp.size;
|
||||
|
||||
return fUv;
|
||||
}
|
||||
|
||||
FfxFloat32x4 getMotionVectorColor(FfxFloat32x2 fMotionVector)
|
||||
{
|
||||
return FfxFloat32x4(0.5f + fMotionVector * DisplaySize() * 0.1f, 0.5f, 1.0f);
|
||||
}
|
||||
|
||||
FfxFloat32x4 getUnusedIndicationColor(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxInt32x2 basePos = iPxPos - vp.offset;
|
||||
|
||||
FfxFloat32 ar = FfxFloat32(vp.size.x) / FfxFloat32(vp.size.y);
|
||||
|
||||
return FfxFloat32x4(basePos.x == FfxInt32(basePos.y * ar), 0, 0, 1);
|
||||
}
|
||||
|
||||
void drawGameMotionVectorFieldVectors(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp);
|
||||
|
||||
VectorFieldEntry gameMv;
|
||||
LoadInpaintedGameFieldMv(fUv, gameMv);
|
||||
|
||||
StoreFrameinterpolationOutput(iPxPos, getMotionVectorColor(gameMv.fMotionVector));
|
||||
}
|
||||
|
||||
void drawGameMotionVectorFieldDepthPriority(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp);
|
||||
|
||||
VectorFieldEntry gameMv;
|
||||
LoadInpaintedGameFieldMv(fUv, gameMv);
|
||||
|
||||
StoreFrameinterpolationOutput(iPxPos, FfxFloat32x4(0, gameMv.uHighPriorityFactor, 0, 1));
|
||||
}
|
||||
|
||||
void drawOpticalFlowMotionVectorField(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp);
|
||||
|
||||
VectorFieldEntry ofMv;
|
||||
SampleOpticalFlowMotionVectorField(fUv, ofMv);
|
||||
|
||||
StoreFrameinterpolationOutput(iPxPos, getMotionVectorColor(ofMv.fMotionVector));
|
||||
}
|
||||
|
||||
void drawDisocclusionMask(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp);
|
||||
|
||||
FfxFloat32x2 fLrUv = fUv * (FfxFloat32x2(RenderSize()) / GetMaxRenderSize());
|
||||
|
||||
FfxFloat32x2 fDisocclusionFactor = ffxSaturate(SampleDisocclusionMask(fLrUv).xy);
|
||||
|
||||
StoreFrameinterpolationOutput(iPxPos, FfxFloat32x4(fDisocclusionFactor, 0, 1));
|
||||
}
|
||||
|
||||
void drawPresentBackbuffer(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp);
|
||||
|
||||
FfxFloat32x4 fPresentColor = getUnusedIndicationColor(iPxPos, vp);
|
||||
|
||||
if (GetHUDLessAttachedFactor() == 1)
|
||||
{
|
||||
fPresentColor = SamplePresentBackbuffer(fUv);
|
||||
}
|
||||
|
||||
StoreFrameinterpolationOutput(iPxPos, fPresentColor);
|
||||
}
|
||||
|
||||
void drawCurrentInterpolationSource(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxFloat32x2 fUv = getTransformedUv(iPxPos, vp);
|
||||
|
||||
FfxFloat32x4 fCurrentBackBuffer = FfxFloat32x4(SampleCurrentBackbuffer(fUv), 1.0f);
|
||||
|
||||
StoreFrameinterpolationOutput(iPxPos, fCurrentBackBuffer);
|
||||
}
|
||||
|
||||
FfxBoolean pointIsInsideViewport(FfxInt32x2 iPxPos, FfxFrameInterpolationDebugViewport vp)
|
||||
{
|
||||
FfxInt32x2 extent = vp.offset + vp.size;
|
||||
|
||||
return (iPxPos.x >= vp.offset.x && iPxPos.x < extent.x) && (iPxPos.y >= vp.offset.y && iPxPos.y < extent.y);
|
||||
}
|
||||
|
||||
void computeDebugView(FfxInt32x2 iPxPos)
|
||||
{
|
||||
#define VIEWPORT_GRID_SIZE_X 3
|
||||
#define VIEWPORT_GRID_SIZE_Y 3
|
||||
|
||||
FfxFloat32x2 fViewportScale = FfxFloat32x2(1.0f / VIEWPORT_GRID_SIZE_X, 1.0f / VIEWPORT_GRID_SIZE_Y);
|
||||
FfxInt32x2 iViewportSize = FfxInt32x2(DisplaySize() * fViewportScale);
|
||||
|
||||
// compute grid [y][x] for easier placement of viewports
|
||||
FfxFrameInterpolationDebugViewport vp[VIEWPORT_GRID_SIZE_Y][VIEWPORT_GRID_SIZE_X];
|
||||
for (FfxInt32 y = 0; y < VIEWPORT_GRID_SIZE_Y; y++)
|
||||
{
|
||||
for (FfxInt32 x = 0; x < VIEWPORT_GRID_SIZE_X; x++)
|
||||
{
|
||||
vp[y][x].offset = iViewportSize * FfxInt32x2(x, y);
|
||||
vp[y][x].size = iViewportSize;
|
||||
}
|
||||
}
|
||||
|
||||
// top row
|
||||
DRAW_VIEWPORT(drawGameMotionVectorFieldVectors, iPxPos, vp[0][0]);
|
||||
DRAW_VIEWPORT(drawGameMotionVectorFieldDepthPriority, iPxPos, vp[0][1]);
|
||||
DRAW_VIEWPORT(drawOpticalFlowMotionVectorField, iPxPos, vp[0][2]);
|
||||
|
||||
// bottom row
|
||||
DRAW_VIEWPORT(drawDisocclusionMask, iPxPos, vp[2][0]);
|
||||
DRAW_VIEWPORT(drawCurrentInterpolationSource, iPxPos, vp[2][1]);
|
||||
DRAW_VIEWPORT(drawPresentBackbuffer, iPxPos, vp[2][2]);
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_DEBUG_VIEW_H
|
||||
@@ -0,0 +1,142 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_DISOCCLUSION_MASK_H
|
||||
#define FFX_FRAMEINTERPOLATION_DISOCCLUSION_MASK_H
|
||||
|
||||
FFX_STATIC const FfxFloat32 DepthClipBaseScale = 1.0f;
|
||||
|
||||
FfxFloat32 ComputeSampleDepthClip(FfxInt32x2 iPxSamplePos, FfxFloat32 fPreviousDepth, FfxFloat32 fPreviousDepthBilinearWeight, FfxFloat32 fCurrentDepthViewSpace)
|
||||
{
|
||||
FfxFloat32 fPrevNearestDepthViewSpace = ConvertFromDeviceDepthToViewSpace(fPreviousDepth);
|
||||
|
||||
// Depth separation logic ref: See "Minimum Triangle Separation for Correct Z-Buffer Occlusion"
|
||||
// Intention: worst case of formula in Figure4 combined with Ksep factor in Section 4
|
||||
const FfxFloat32 fHalfViewportWidth = RenderSize().x * 0.5f;
|
||||
FfxFloat32 fDepthThreshold = ffxMax(fCurrentDepthViewSpace, fPrevNearestDepthViewSpace);
|
||||
|
||||
// WARNING: Ksep only works with reversed-z with infinite projection.
|
||||
const FfxFloat32 Ksep = 1.37e-05f;
|
||||
FfxFloat32 fRequiredDepthSeparation = Ksep * fDepthThreshold * TanHalfFoV() * fHalfViewportWidth;
|
||||
FfxFloat32 fDepthDiff = fCurrentDepthViewSpace - fPrevNearestDepthViewSpace;
|
||||
|
||||
FfxFloat32 fDepthClipFactor = (fDepthDiff > 0) ? ffxSaturate(fRequiredDepthSeparation / fDepthDiff) : 1.0f;
|
||||
|
||||
return fPreviousDepthBilinearWeight * fDepthClipFactor * ffxLerp(1.0f, DepthClipBaseScale, ffxSaturate(fDepthDiff * fDepthDiff));
|
||||
}
|
||||
|
||||
FfxFloat32 LoadEstimatedDepth(FfxUInt32 estimatedIndex, FfxInt32x2 iSamplePos)
|
||||
{
|
||||
if (estimatedIndex == 0)
|
||||
{
|
||||
return LoadReconstructedDepthPreviousFrame(iSamplePos);
|
||||
}
|
||||
else if (estimatedIndex == 1)
|
||||
{
|
||||
return LoadDilatedDepth(iSamplePos);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 ComputeDepthClip(FfxUInt32 estimatedIndex, FfxFloat32x2 fUvSample, FfxFloat32 fCurrentDepthSample)
|
||||
{
|
||||
FfxFloat32 fCurrentDepthViewSpace = ConvertFromDeviceDepthToViewSpace(fCurrentDepthSample);
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUvSample, RenderSize());
|
||||
|
||||
FfxFloat32 fDilatedSum = 0.0f;
|
||||
FfxFloat32 fDepth = 0.0f;
|
||||
FfxFloat32 fWeightSum = 0.0f;
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) {
|
||||
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
if (IsOnScreen(iSamplePos, RenderSize())) {
|
||||
const FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex];
|
||||
if (fWeight > fReconstructedDepthBilinearWeightThreshold) {
|
||||
|
||||
const FfxFloat32 fPrevDepthSample = LoadEstimatedDepth(estimatedIndex, iSamplePos);
|
||||
const FfxFloat32 fPrevNearestDepthViewSpace = ConvertFromDeviceDepthToViewSpace(fPrevDepthSample);
|
||||
|
||||
const FfxFloat32 fDepthDiff = fCurrentDepthViewSpace - fPrevNearestDepthViewSpace;
|
||||
|
||||
if (fDepthDiff > 0.0f) {
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH
|
||||
const FfxFloat32 fPlaneDepth = ffxMin(fPrevDepthSample, fCurrentDepthSample);
|
||||
#else
|
||||
const FfxFloat32 fPlaneDepth = ffxMax(fPrevDepthSample, fCurrentDepthSample);
|
||||
#endif
|
||||
|
||||
const FfxFloat32x3 fCenter = GetViewSpacePosition(FfxInt32x2(RenderSize() * 0.5f), RenderSize(), fPlaneDepth);
|
||||
const FfxFloat32x3 fCorner = GetViewSpacePosition(FfxInt32x2(0, 0), RenderSize(), fPlaneDepth);
|
||||
|
||||
const FfxFloat32 fHalfViewportWidth = length(FfxFloat32x2(RenderSize()));
|
||||
const FfxFloat32 fDepthThreshold = ffxMin(fCurrentDepthViewSpace, fPrevNearestDepthViewSpace);
|
||||
|
||||
const FfxFloat32 Ksep = 1.37e-05f;
|
||||
const FfxFloat32 Kfov = length(fCorner) / length(fCenter);
|
||||
const FfxFloat32 fRequiredDepthSeparation = Ksep * Kfov * fHalfViewportWidth * fDepthThreshold;
|
||||
|
||||
const FfxFloat32 fResolutionFactor = ffxSaturate(length(FfxFloat32x2(RenderSize())) / length(FfxFloat32x2(1920.0f, 1080.0f)));
|
||||
const FfxFloat32 fPower = ffxLerp(1.0f, 3.0f, fResolutionFactor);
|
||||
|
||||
fDepth += FfxFloat32((fRequiredDepthSeparation / fDepthDiff) >= 1.0f) * fWeight;
|
||||
fWeightSum += fWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (fWeightSum > 0.0f) ? ffxSaturate(1.0f - fDepth / fWeightSum) : 0.0f;
|
||||
}
|
||||
|
||||
void computeDisocclusionMask(FfxInt32x2 iPxPos)
|
||||
{
|
||||
FfxFloat32 fDilatedDepth = LoadEstimatedInterpolationFrameDepth(iPxPos);
|
||||
|
||||
FfxFloat32x2 fDepthUv = (iPxPos + 0.5f) / RenderSize();
|
||||
FfxFloat32 fCurrentDepthViewSpace = ConvertFromDeviceDepthToViewSpace(fDilatedDepth);
|
||||
|
||||
VectorFieldEntry gameMv;
|
||||
LoadInpaintedGameFieldMv(fDepthUv, gameMv);
|
||||
|
||||
const FfxFloat32 fDepthClipInterpolatedToPrevious = 1.0f - ComputeDepthClip(0, fDepthUv + gameMv.fMotionVector, fDilatedDepth);
|
||||
const FfxFloat32 fDepthClipInterpolatedToCurrent = 1.0f - ComputeDepthClip(1, fDepthUv - gameMv.fMotionVector, fDilatedDepth);
|
||||
FfxFloat32x2 fDisocclusionMask = FfxFloat32x2(fDepthClipInterpolatedToPrevious, fDepthClipInterpolatedToCurrent);
|
||||
|
||||
fDisocclusionMask = FfxFloat32x2(FFX_GREATER_THAN_EQUAL(fDisocclusionMask, ffxBroadcast2(FFX_FRAMEINTERPOLATION_EPSILON)));
|
||||
|
||||
// Avoid false disocclusion if primary game vector pointer outside screen area
|
||||
const FfxFloat32x2 fSrcMotionVector = gameMv.fMotionVector * 2.0f;
|
||||
const FfxInt32x2 iSamplePosPrevious = FfxInt32x2((fDepthUv + fSrcMotionVector) * RenderSize());
|
||||
fDisocclusionMask.x = ffxSaturate(fDisocclusionMask.x + FfxFloat32(!IsOnScreen(iSamplePosPrevious, RenderSize())));
|
||||
|
||||
const FfxInt32x2 iSamplePosCurrent = FfxInt32x2((fDepthUv - fSrcMotionVector) * RenderSize());
|
||||
fDisocclusionMask.y = ffxSaturate(fDisocclusionMask.y + FfxFloat32(!IsOnScreen(iSamplePosCurrent, RenderSize())));
|
||||
|
||||
StoreDisocclusionMask(iPxPos, fDisocclusionMask);
|
||||
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_DISOCCLUSION_MASK_H
|
||||
@@ -0,0 +1,118 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_GAME_MOTION_VECTOR_FIELD_H
|
||||
#define FFX_FRAMEINTERPOLATION_GAME_MOTION_VECTOR_FIELD_H
|
||||
|
||||
FfxUInt32 getPriorityFactorFromViewSpaceDepth(FfxFloat32 fViewSpaceDepthInMeters)
|
||||
{
|
||||
fViewSpaceDepthInMeters = ffxPow(fViewSpaceDepthInMeters, 0.33f);
|
||||
|
||||
FfxUInt32 uPriorityFactor = FfxUInt32(FfxFloat32(1 - (fViewSpaceDepthInMeters * (1.0f / (1.0f + fViewSpaceDepthInMeters)))) * PRIORITY_HIGH_MAX);
|
||||
|
||||
return ffxMax(1, uPriorityFactor);
|
||||
}
|
||||
|
||||
void computeGameFieldMvs(FfxInt32x2 iPxPos)
|
||||
{
|
||||
const FfxFloat32x2 fUvInScreenSpace = (FfxFloat32x2(iPxPos) + 0.5f) / RenderSize();
|
||||
const FfxFloat32x2 fUvInInterpolationRectStart = FfxFloat32x2(InterpolationRectBase()) / DisplaySize();
|
||||
const FfxFloat32x2 fUvLetterBoxScale = FfxFloat32x2(InterpolationRectSize()) / DisplaySize();
|
||||
const FfxFloat32x2 fUvInInterpolationRect = fUvInInterpolationRectStart + fUvInScreenSpace * fUvLetterBoxScale;
|
||||
|
||||
const FfxFloat32 fDepthSample = LoadDilatedDepth(iPxPos);
|
||||
const FfxFloat32x2 fGameMotionVector = LoadDilatedMotionVector(iPxPos);
|
||||
const FfxFloat32x2 fMotionVectorHalf = fGameMotionVector * 0.5f;
|
||||
const FfxFloat32x2 fInterpolatedLocationUv = fUvInScreenSpace + fMotionVectorHalf;
|
||||
|
||||
const FfxFloat32 fViewSpaceDepth = ConvertFromDeviceDepthToViewSpace(fDepthSample);
|
||||
const FfxUInt32 uHighPriorityFactorPrimary = getPriorityFactorFromViewSpaceDepth(fViewSpaceDepth);
|
||||
|
||||
FfxFloat32x3 prevBackbufferCol = SamplePreviousBackbuffer(fUvInInterpolationRect).xyz;
|
||||
FfxFloat32x3 curBackbufferCol = SamplePreviousBackbuffer(fUvInInterpolationRect + fGameMotionVector * fUvLetterBoxScale).xyz;
|
||||
FfxFloat32 prevLuma = 0.001f + RawRGBToLuminance(prevBackbufferCol);
|
||||
FfxFloat32 currLuma = 0.001f + RawRGBToLuminance(curBackbufferCol);
|
||||
|
||||
FfxUInt32 uLowPriorityFactor = FfxUInt32(ffxRound(ffxPow(MinDividedByMax(prevLuma, currLuma), 1.0f / 1.0f) * PRIORITY_LOW_MAX))
|
||||
* FfxUInt32(IsUvInside(fUvInInterpolationRect + fGameMotionVector * fUvLetterBoxScale));
|
||||
|
||||
// Update primary motion vectors
|
||||
{
|
||||
const FfxUInt32x2 packedVectorPrimary = PackVectorFieldEntries(true, uHighPriorityFactorPrimary, uLowPriorityFactor, fMotionVectorHalf);
|
||||
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fInterpolatedLocationUv, RenderSize());
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++)
|
||||
{
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
if (IsOnScreen(iSamplePos, RenderSize()))
|
||||
{
|
||||
UpdateGameMotionVectorField(iSamplePos, packedVectorPrimary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update secondary vectors
|
||||
// Main purpose of secondary vectors is to improve quality of inpainted vectors
|
||||
const FfxBoolean bWriteSecondaryVectors = length(fMotionVectorHalf * RenderSize()) > FFX_FRAMEINTERPOLATION_EPSILON;
|
||||
if (bWriteSecondaryVectors)
|
||||
{
|
||||
FfxBoolean bWriteSecondary = true;
|
||||
FfxUInt32 uNumPrimaryHits = 0;
|
||||
const FfxFloat32 fSecondaryStepScale = length(1.0f / RenderSize());
|
||||
const FfxFloat32x2 fStepMv = normalize(fGameMotionVector);
|
||||
const FfxFloat32 fBreakDist = ffxMin(length(fMotionVectorHalf), length(FfxFloat32x2(0.5f, 0.5f)));
|
||||
|
||||
for (FfxFloat32 fMvScale = fSecondaryStepScale; fMvScale <= fBreakDist && bWriteSecondary; fMvScale += fSecondaryStepScale)
|
||||
{
|
||||
const FfxFloat32x2 fSecondaryLocationUv = fInterpolatedLocationUv - fStepMv * fMvScale;
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fSecondaryLocationUv, RenderSize());
|
||||
|
||||
// Reverse depth prio for secondary vectors
|
||||
FfxUInt32 uHighPriorityFactorSecondary = ffxMax(1, PRIORITY_HIGH_MAX - uHighPriorityFactorPrimary);
|
||||
|
||||
const FfxFloat32x2 fToCenter = normalize(FfxFloat32x2(0.5f, 0.5f) - fSecondaryLocationUv);
|
||||
uLowPriorityFactor = FfxUInt32(ffxMax(0.0f, dot(fToCenter, fStepMv)) * PRIORITY_LOW_MAX);
|
||||
const FfxUInt32x2 packedVectorSecondary = PackVectorFieldEntries(false, uHighPriorityFactorSecondary, uLowPriorityFactor, fMotionVectorHalf);
|
||||
|
||||
// Only write secondary mvs to single bilinear location
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 1; iSampleIndex++)
|
||||
{
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
bWriteSecondary = bWriteSecondary && IsOnScreen(iSamplePos, RenderSize());
|
||||
|
||||
if (bWriteSecondary)
|
||||
{
|
||||
const FfxUInt32 uExistingVectorFieldEntry = UpdateGameMotionVectorFieldEx(iSamplePos, packedVectorSecondary);
|
||||
|
||||
uNumPrimaryHits += FfxUInt32(PackedVectorFieldEntryIsPrimary(uExistingVectorFieldEntry));
|
||||
bWriteSecondary = bWriteSecondary && (uNumPrimaryHits <= 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_GAME_MOTION_VECTOR_FIELD_H
|
||||
@@ -0,0 +1,150 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_INPAINTING_H
|
||||
#define FFX_FRAMEINTERPOLATION_INPAINTING_H
|
||||
|
||||
FfxFloat32x4 ComputeInpaintingLevel(FfxFloat32x2 fUv, const FfxInt32 iMipLevel, const FfxInt32x2 iTexSize)
|
||||
{
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUv, iTexSize);
|
||||
|
||||
FfxFloat32x4 fColor = FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) {
|
||||
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
if (IsOnScreen(iSamplePos, iTexSize)) {
|
||||
|
||||
FfxFloat32x4 fSample = LoadInpaintingPyramid(iMipLevel, iSamplePos);
|
||||
|
||||
const FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex] * FfxFloat32(fSample.w > 0.0f);
|
||||
|
||||
fColor += FfxFloat32x4(fSample.rgb * fWeight, fWeight);
|
||||
}
|
||||
}
|
||||
|
||||
return fColor;
|
||||
}
|
||||
|
||||
FfxFloat32x3 ComputeInpainting(FfxInt32x2 iPxPos)
|
||||
{
|
||||
FfxFloat32x2 fUv = (iPxPos + 0.5f) / (DisplaySize());
|
||||
|
||||
FfxFloat32x4 fColor = FfxFloat32x4(0.0, 0.0, 0.0, 0.0);
|
||||
FfxFloat32 fWeightSum = 0.0f;
|
||||
FfxInt32x2 iTexSize = DisplaySize();
|
||||
|
||||
for (FfxInt32 iMipLevel = 0; iMipLevel < 10; iMipLevel++) {
|
||||
|
||||
iTexSize /= 2;
|
||||
|
||||
FfxFloat32x4 fMipColor = ComputeInpaintingLevel(fUv, iMipLevel, iTexSize);
|
||||
|
||||
if (fMipColor.w > 0.0f) {
|
||||
const FfxFloat32x3 fNormalizedMipColor = fMipColor.rgb / fMipColor.w;
|
||||
const FfxFloat32 fMipWeight = ffxPow(1.0f - iMipLevel / 10.0f, 3.0f) * fMipColor.w;
|
||||
|
||||
fColor += FfxFloat32x4(fNormalizedMipColor, 1.0f) * fMipWeight;
|
||||
}
|
||||
}
|
||||
|
||||
return fColor.rgb / fColor.w;
|
||||
}
|
||||
|
||||
void drawDebugTearLines(FfxInt32x2 iPxPos, inout FfxFloat32x3 fColor, inout FfxBoolean bWriteColor)
|
||||
{
|
||||
if (iPxPos.x < 16)
|
||||
{
|
||||
fColor.g = 1.f;
|
||||
bWriteColor = true;
|
||||
}
|
||||
else if (iPxPos.x > DisplaySize().x - 16)
|
||||
{
|
||||
fColor += GetDebugBarColor();
|
||||
bWriteColor = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void drawDebugResetIndicators(FfxInt32x2 iPxPos, inout FfxFloat32x3 fColor, inout FfxBoolean bWriteColor)
|
||||
{
|
||||
if (iPxPos.y < 32 && Reset())
|
||||
{
|
||||
fColor.r = 1.f;
|
||||
bWriteColor = true;
|
||||
}
|
||||
else if (iPxPos.y > 32 && iPxPos.y < 64 && HasSceneChanged())
|
||||
{
|
||||
fColor.b = 1.f;
|
||||
bWriteColor = true;
|
||||
}
|
||||
}
|
||||
|
||||
void computeInpainting(FfxInt32x2 iPxPos)
|
||||
{
|
||||
FfxBoolean bWriteColor = false;
|
||||
FfxFloat32x4 fInterpolatedColor = RWLoadFrameinterpolationOutput(iPxPos);
|
||||
|
||||
const FfxFloat32 fInPaintingWeight = fInterpolatedColor.w;
|
||||
if (fInPaintingWeight > FFX_FRAMEINTERPOLATION_EPSILON)
|
||||
{
|
||||
fInterpolatedColor.rgb = ffxLerp(fInterpolatedColor.rgb, ComputeInpainting(iPxPos) * FfxFloat32(DisplaySize().x > 0), fInPaintingWeight);
|
||||
bWriteColor = true;
|
||||
}
|
||||
|
||||
if (GetHUDLessAttachedFactor() == 1)
|
||||
{
|
||||
const FfxFloat32x3 fCurrentInterpolationSource = LoadCurrentBackbuffer(iPxPos).rgb;
|
||||
const FfxFloat32x3 fPresentColor = LoadPresentBackbuffer(iPxPos).rgb;
|
||||
|
||||
if (any(FFX_GREATER_THAN(abs(fCurrentInterpolationSource - fPresentColor), FfxFloat32x3(0.0, 0.0, 0.0))))
|
||||
{
|
||||
const FfxFloat32 fStaticFactor = CalculateStaticContentFactor(RawRGBToLinear(fCurrentInterpolationSource), RawRGBToLinear(fPresentColor));
|
||||
|
||||
if (fStaticFactor > FFX_FRAMEINTERPOLATION_EPSILON)
|
||||
{
|
||||
fInterpolatedColor.rgb = ffxLerp(fInterpolatedColor.rgb, fPresentColor, fStaticFactor);
|
||||
bWriteColor = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((GetDispatchFlags() & FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_TEAR_LINES) != 0)
|
||||
{
|
||||
drawDebugTearLines(iPxPos, fInterpolatedColor.rgb, bWriteColor);
|
||||
}
|
||||
|
||||
if ((GetDispatchFlags() & FFX_FRAMEINTERPOLATION_DISPATCH_DRAW_DEBUG_RESET_INDICATORS) != 0)
|
||||
{
|
||||
drawDebugResetIndicators(iPxPos, fInterpolatedColor.rgb, bWriteColor);
|
||||
}
|
||||
|
||||
if (bWriteColor)
|
||||
{
|
||||
StoreFrameinterpolationOutput(iPxPos, FfxFloat32x4(fInterpolatedColor.rgb, 1.0f));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_INPAINTING_H
|
||||
@@ -0,0 +1,124 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_OPTICAL_FLOW_VECTOR_FIELD_H
|
||||
#define FFX_FRAMEINTERPOLATION_OPTICAL_FLOW_VECTOR_FIELD_H
|
||||
|
||||
void computeOpticalFlowFieldMvs(FfxUInt32x2 dtID, FfxFloat32x2 fOpticalFlowVector)
|
||||
{
|
||||
FfxFloat32x2 fUv = FfxFloat32x2(FfxFloat32x2(dtID)+0.5f) / GetOpticalFlowSize2();
|
||||
|
||||
const FfxFloat32 scaleFactor = 1.0f;
|
||||
FfxFloat32x2 fMotionVectorHalf = fOpticalFlowVector * 0.5f;
|
||||
|
||||
FfxFloat32 fDilatedDepth = ConvertFromDeviceDepthToViewSpace(LoadDilatedDepth(FfxInt32x2(dtID)));
|
||||
|
||||
FfxFloat32x3 prevBackbufferCol = SamplePreviousBackbuffer(fUv).xyz;
|
||||
FfxFloat32x3 curBackbufferCol = SampleCurrentBackbuffer(fUv + fOpticalFlowVector).xyz;
|
||||
|
||||
FfxFloat32 prevLuma = 0.001f + RawRGBToLuminance(prevBackbufferCol);
|
||||
FfxFloat32 currLuma = 0.001f + RawRGBToLuminance(curBackbufferCol);
|
||||
|
||||
FfxFloat32 fVelocity = length(fOpticalFlowVector * InterpolationRectSize());
|
||||
FfxUInt32 uHighPriorityFactor = FfxUInt32(fVelocity > 1.0f) * FfxUInt32(ffxSaturate(fVelocity / length(InterpolationRectSize() * 0.05f)) * PRIORITY_HIGH_MAX);
|
||||
|
||||
if(uHighPriorityFactor > 0) {
|
||||
FfxUInt32 uLowPriorityFactor = FfxUInt32(ffxRound(ffxPow(MinDividedByMax(prevLuma, currLuma), 1.0f / 1.0f) * PRIORITY_LOW_MAX))
|
||||
* FfxUInt32(IsUvInside(fUv + fOpticalFlowVector));
|
||||
|
||||
// Project current depth into previous frame locations.
|
||||
// Push to all pixels having some contribution if reprojection is using bilinear logic.
|
||||
|
||||
const FfxUInt32x2 packedVectorPrimary = PackVectorFieldEntries(true, uHighPriorityFactor, uLowPriorityFactor, fMotionVectorHalf);
|
||||
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUv + fMotionVectorHalf, GetOpticalFlowSize2());
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++)
|
||||
{
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
|
||||
if (IsOnScreen(iSamplePos, GetOpticalFlowSize2()))
|
||||
{
|
||||
UpdateOpticalflowMotionVectorField(iSamplePos, packedVectorPrimary);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void computeOpticalFlowVectorField(FfxInt32x2 iPxPos)
|
||||
{
|
||||
FfxFloat32x2 fOpticalFlowVector = FfxFloat32x2(0.0, 0.0);
|
||||
FfxFloat32x2 fOpticalFlowVector3x3Avg = FfxFloat32x2(0.0, 0.0);
|
||||
FfxInt32 size = 1;
|
||||
FfxFloat32 sw = 0.0f;
|
||||
|
||||
for(FfxInt32 y = -size; y <= size; y++) {
|
||||
for(FfxInt32 x = -size; x <= size; x++) {
|
||||
|
||||
FfxInt32x2 samplePos = iPxPos + FfxInt32x2(x, y);
|
||||
|
||||
FfxFloat32x2 vs = LoadOpticalFlow(samplePos);
|
||||
FfxFloat32 fConfidenceFactor = ffxMax(FFX_FRAMEINTERPOLATION_EPSILON, LoadOpticalFlowConfidence(samplePos));
|
||||
|
||||
|
||||
FfxFloat32 len = length(vs * InterpolationRectSize());
|
||||
FfxFloat32 len_factor = ffxMax(0.0f, 512.0f - len) * FfxFloat32(len > 1.0f);
|
||||
FfxFloat32 w = len_factor;
|
||||
|
||||
fOpticalFlowVector3x3Avg += vs * w;
|
||||
|
||||
sw += w;
|
||||
}
|
||||
}
|
||||
|
||||
fOpticalFlowVector3x3Avg /= sw;
|
||||
|
||||
|
||||
sw = 0.0f;
|
||||
for(FfxInt32 y = -size; y <= size; y++) {
|
||||
for(FfxInt32 x = -size; x <= size; x++) {
|
||||
|
||||
FfxInt32x2 samplePos = iPxPos + FfxInt32x2(x, y);
|
||||
|
||||
FfxFloat32x2 vs = LoadOpticalFlow(samplePos);
|
||||
|
||||
FfxFloat32 fConfidenceFactor = ffxMax(FFX_FRAMEINTERPOLATION_EPSILON, LoadOpticalFlowConfidence(samplePos));
|
||||
FfxFloat32 len = length(vs * InterpolationRectSize());
|
||||
FfxFloat32 len_factor = ffxMax(0.0f, 512.0f - len) * FfxFloat32(len > 1.0f);
|
||||
|
||||
|
||||
FfxFloat32 w = ffxMax(0.0f, ffxPow(dot(fOpticalFlowVector3x3Avg, vs), 1.25f)) * len_factor;
|
||||
|
||||
fOpticalFlowVector += vs * w;
|
||||
sw += w;
|
||||
}
|
||||
}
|
||||
|
||||
if (sw > FFX_FRAMEINTERPOLATION_EPSILON)
|
||||
{
|
||||
fOpticalFlowVector /= sw;
|
||||
}
|
||||
|
||||
computeOpticalFlowFieldMvs(iPxPos, fOpticalFlowVector);
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_OPTICAL_FLOW_VECTOR_FIELD_H
|
||||
@@ -0,0 +1,123 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_RECONSTRUCT_DILATED_VELOCITY_AND_PREVIOUS_DEPTH_H
|
||||
#define FFX_FRAMEINTERPOLATION_RECONSTRUCT_DILATED_VELOCITY_AND_PREVIOUS_DEPTH_H
|
||||
|
||||
void ReconstructPrevDepth(FfxInt32x2 iPxPos, FfxFloat32 fDepth, FfxFloat32x2 fMotionVector, FfxInt32x2 iPxDepthSize)
|
||||
{
|
||||
fMotionVector *= FfxFloat32(length(fMotionVector * DisplaySize()) > 0.1f);
|
||||
|
||||
FfxFloat32x2 fUv = (iPxPos + FfxFloat32(0.5)) / iPxDepthSize;
|
||||
FfxFloat32x2 fReprojectedUv = fUv + fMotionVector;
|
||||
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fReprojectedUv, RenderSize());
|
||||
|
||||
// Project current depth into previous frame locations.
|
||||
// Push to all pixels having some contribution if reprojection is using bilinear logic.
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++) {
|
||||
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
FfxFloat32 fWeight = bilinearInfo.fWeights[iSampleIndex];
|
||||
|
||||
if (fWeight > fReconstructedDepthBilinearWeightThreshold) {
|
||||
|
||||
FfxInt32x2 iStorePos = bilinearInfo.iBasePos + iOffset;
|
||||
if (IsOnScreen(iStorePos, iPxDepthSize)) {
|
||||
UpdateReconstructedDepthPreviousFrame(iStorePos, fDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FindNearestDepth(FFX_PARAMETER_IN FfxInt32x2 iPxPos, FFX_PARAMETER_IN FfxInt32x2 iPxSize, FFX_PARAMETER_OUT FfxFloat32 fNearestDepth, FFX_PARAMETER_OUT FfxInt32x2 fNearestDepthCoord)
|
||||
{
|
||||
const FfxInt32 iSampleCount = 9;
|
||||
const FfxInt32x2 iSampleOffsets[iSampleCount] = {
|
||||
FfxInt32x2(+0, +0),
|
||||
FfxInt32x2(+1, +0),
|
||||
FfxInt32x2(+0, +1),
|
||||
FfxInt32x2(+0, -1),
|
||||
FfxInt32x2(-1, +0),
|
||||
FfxInt32x2(-1, +1),
|
||||
FfxInt32x2(+1, +1),
|
||||
FfxInt32x2(-1, -1),
|
||||
FfxInt32x2(+1, -1),
|
||||
};
|
||||
|
||||
// pull out the depth loads to allow SC to batch them
|
||||
FfxFloat32 depth[9];
|
||||
FfxInt32 iSampleIndex = 0;
|
||||
FFX_UNROLL
|
||||
for (iSampleIndex = 0; iSampleIndex < iSampleCount; ++iSampleIndex) {
|
||||
|
||||
FfxInt32x2 iPos = iPxPos + iSampleOffsets[iSampleIndex];
|
||||
depth[iSampleIndex] = LoadInputDepth(iPos);
|
||||
}
|
||||
|
||||
// find closest depth
|
||||
fNearestDepthCoord = iPxPos;
|
||||
fNearestDepth = depth[0];
|
||||
FFX_UNROLL
|
||||
for (iSampleIndex = 1; iSampleIndex < iSampleCount; ++iSampleIndex) {
|
||||
|
||||
FfxInt32x2 iPos = iPxPos + iSampleOffsets[iSampleIndex];
|
||||
if (IsOnScreen(iPos, iPxSize)) {
|
||||
|
||||
FfxFloat32 fNdDepth = depth[iSampleIndex];
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_INVERTED_DEPTH
|
||||
if (fNdDepth > fNearestDepth) {
|
||||
#else
|
||||
if (fNdDepth < fNearestDepth) {
|
||||
#endif
|
||||
fNearestDepthCoord = iPos;
|
||||
fNearestDepth = fNdDepth;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReconstructAndDilate(FfxInt32x2 iPxLrPos)
|
||||
{
|
||||
FfxFloat32 fDilatedDepth;
|
||||
FfxInt32x2 iNearestDepthCoord;
|
||||
|
||||
FindNearestDepth(iPxLrPos, RenderSize(), fDilatedDepth, iNearestDepthCoord);
|
||||
|
||||
#if FFX_FRAMEINTERPOLATION_OPTION_LOW_RES_MOTION_VECTORS
|
||||
FfxInt32x2 iSamplePos = iPxLrPos;
|
||||
FfxInt32x2 iMotionVectorPos = iNearestDepthCoord;
|
||||
#else
|
||||
FfxInt32x2 iSamplePos = ComputeHrPosFromLrPos(iPxLrPos);
|
||||
FfxInt32x2 iMotionVectorPos = ComputeHrPosFromLrPos(iNearestDepthCoord);
|
||||
#endif
|
||||
|
||||
FfxFloat32x2 fDilatedMotionVector = LoadInputMotionVector(iMotionVectorPos);
|
||||
|
||||
StoreDilatedDepth(iPxLrPos, fDilatedDepth);
|
||||
StoreDilatedMotionVectors(iPxLrPos, fDilatedMotionVector);
|
||||
|
||||
ReconstructPrevDepth(iPxLrPos, fDilatedDepth, fDilatedMotionVector, RenderSize());
|
||||
}
|
||||
|
||||
|
||||
#endif //!defined( FFX_FRAMEINTERPOLATION_RECONSTRUCT_DILATED_VELOCITY_AND_PREVIOUS_DEPTH_H )
|
||||
@@ -0,0 +1,59 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_RECONSTRUCT_PREVIOUS_DEPTH_H
|
||||
#define FFX_FRAMEINTERPOLATION_RECONSTRUCT_PREVIOUS_DEPTH_H
|
||||
|
||||
void ReconstructPrevDepth(FfxInt32x2 iPxPos, FfxUInt32 depthTarget, FfxFloat32 fDepth, FfxFloat32x2 fMotionVector, FfxInt32x2 iPxDepthSize)
|
||||
{
|
||||
const FfxFloat32x2 fUv = (iPxPos + FfxFloat32(0.5)) / iPxDepthSize;
|
||||
|
||||
// Project current depth into previous frame locations.
|
||||
// Push to all pixels having some contribution if reprojection is using bilinear logic.
|
||||
BilinearSamplingData bilinearInfo = GetBilinearSamplingData(fUv + fMotionVector, RenderSize());
|
||||
for (FfxInt32 iSampleIndex = 0; iSampleIndex < 4; iSampleIndex++)
|
||||
{
|
||||
const FfxInt32x2 iOffset = bilinearInfo.iOffsets[iSampleIndex];
|
||||
const FfxInt32x2 iSamplePos = bilinearInfo.iBasePos + iOffset;
|
||||
const FfxFloat32 fSampleWeight = bilinearInfo.fWeights[iSampleIndex];
|
||||
|
||||
if (fSampleWeight > fReconstructedDepthBilinearWeightThreshold)
|
||||
{
|
||||
if (IsOnScreen(iSamplePos, RenderSize()))
|
||||
{
|
||||
if (depthTarget != 0) {
|
||||
UpdateReconstructedDepthInterpolatedFrame(iSamplePos, fDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reconstructPreviousDepth(FfxInt32x2 iPxPos)
|
||||
{
|
||||
FfxFloat32x2 fMotionVector = LoadDilatedMotionVector(iPxPos);
|
||||
FfxFloat32 fDilatedDepth = LoadDilatedDepth(iPxPos);
|
||||
|
||||
ReconstructPrevDepth(iPxPos, 1, fDilatedDepth, fMotionVector * 0.5f, RenderSize());
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_RECONSTRUCT_PREVIOUS_DEPTH_H
|
||||
@@ -0,0 +1,99 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_RESOURCES_H
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OUTPUT 1
|
||||
//#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_BACKBUFFER 2
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_PREVIOUS_INTERPOLATION_SOURCE 3
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_CURRENT_INTERPOLATION_SOURCE 4
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEPTH 5
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_MOTION_VECTORS 6
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RESERVED_2 7
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RESERVED_3 8
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RESERVED_4 9
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_DEPTH 10
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS 11
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME 12
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_INTERPOLATED_FRAME 13
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DISOCCLUSION_MASK 14
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_GAME_MOTION_VECTOR_FIELD_X 15
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_GAME_MOTION_VECTOR_FIELD_Y 16
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OPTICAL_FLOW_MOTION_VECTOR_FIELD_X 17
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OPTICAL_FLOW_MOTION_VECTOR_FIELD_Y 18
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OPTICAL_FLOW_VECTOR 19
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RESERVED_5 20
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OPTICAL_FLOW_CONFIDENCE 21
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OPTICAL_FLOW_GLOBAL_MOTION 22
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCENE_CHANGE_DETECTION 23
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RESERVED_6 25
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RESERVED_7 26
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEBUG_OUTPUT_0 27
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEBUG_OUTPUT_1 28
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DEBUG_OUTPUT 29
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RESERVED_8 30
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_PRESENT_BACKBUFFER 31
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNTERS 32
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID 33 // same as FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_0
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_0 33
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_1 34
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_2 35
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_3 36
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_4 37
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_5 38
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_6 39
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_7 40
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_8 41
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_9 42
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_10 43
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_11 44
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_INPAINTING_PYRAMID_MIPMAP_12 45
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_DEPTH_0 46 // resources for ping ponging if async is enabled.
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_DEPTH_1 47 // code relies on them being interleaved
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_0 48
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS_1 49 // code relies on them being interleaved
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME_0 50
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_RECONSTRUCTED_DEPTH_PREVIOUS_FRAME_1 51 // code relies on them being interleaved
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_RESOURCE_IDENTIFIER_COUNT 52
|
||||
|
||||
#define FFX_FRAMEINTERPOLATION_CONSTANTBUFFER_IDENTIFIER 0
|
||||
#define FFX_FRAMEINTERPOLATION_INPAINTING_PYRAMID_CONSTANTBUFFER_IDENTIFIER 1
|
||||
#define FFX_FRAMEINTERPOLATION_CONSTANTBUFFER_COUNT 2
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif //!defined( FFX_FRAMEINTERPOLATION_RESOURCES_H )
|
||||
@@ -0,0 +1,50 @@
|
||||
// This file is part of the FidelityFX SDK.
|
||||
//
|
||||
// Copyright (C) 2024 Advanced Micro Devices, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files(the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and /or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions :
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef FFX_FRAMEINTERPOLATION_SETUP_H
|
||||
#define FFX_FRAMEINTERPOLATION_SETUP_H
|
||||
|
||||
void setupFrameinterpolationResources(FfxInt32x2 iPxPos)
|
||||
{
|
||||
// Update reset counters
|
||||
StoreCounter(COUNTER_SPD, 0);
|
||||
if (all(FFX_EQUAL(iPxPos, FfxInt32x2(0, 0))))
|
||||
{
|
||||
if(Reset() || HasSceneChanged()) {
|
||||
StoreCounter(COUNTER_FRAME_INDEX_SINCE_LAST_RESET, 0);
|
||||
} else {
|
||||
FfxUInt32 counter = RWLoadCounter(COUNTER_FRAME_INDEX_SINCE_LAST_RESET);
|
||||
StoreCounter(COUNTER_FRAME_INDEX_SINCE_LAST_RESET, counter + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset resources
|
||||
StoreGameMotionVectorFieldX(iPxPos, 0);
|
||||
StoreGameMotionVectorFieldY(iPxPos, 0);
|
||||
|
||||
StoreOpticalflowMotionVectorFieldX(iPxPos, 0);
|
||||
StoreOpticalflowMotionVectorFieldY(iPxPos, 0);
|
||||
|
||||
StoreDisocclusionMask(iPxPos, FfxFloat32x2(0.0, 0.0));
|
||||
}
|
||||
|
||||
#endif // FFX_FRAMEINTERPOLATION_SETUP_H
|
||||
Reference in New Issue
Block a user