16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 15:09:19 +02:00

Some renaming

This commit is contained in:
2025-04-15 01:32:56 +02:00
parent 12d6a1578d
commit a39d972126
864 changed files with 29 additions and 34 deletions

View File

@@ -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(OPTICALFLOW_BASE_ARGS
-reflection -deps=gcc -DFFX_GPU=1)
set(OPTICALFLOW_PERMUTATION_ARGS
-DFFX_OPTICALFLOW_OPTION_HDR_COLOR_INPUT={0,1}
)
set(OPTICALFLOW_INCLUDE_ARGS
"${FFX_GPU_PATH}"
"${FFX_GPU_PATH}/opticalflow")
if (NOT OPTICALFLOW_SHADER_EXT)
set(OPTICALFLOW_SHADER_EXT *)
endif()
file(GLOB OPTICALFLOW_SHADERS
"shaders/opticalflow/ffx_opticalflow_prepare_luma_pass.${OPTICALFLOW_SHADER_EXT}"
"shaders/opticalflow/ffx_opticalflow_compute_luminance_pyramid_pass.${OPTICALFLOW_SHADER_EXT}"
"shaders/opticalflow/ffx_opticalflow_generate_scd_histogram_pass.${OPTICALFLOW_SHADER_EXT}"
"shaders/opticalflow/ffx_opticalflow_compute_scd_divergence_pass.${OPTICALFLOW_SHADER_EXT}"
"shaders/opticalflow/ffx_opticalflow_compute_optical_flow_advanced_pass_v5.${OPTICALFLOW_SHADER_EXT}"
"shaders/opticalflow/ffx_opticalflow_filter_optical_flow_pass_v5.${OPTICALFLOW_SHADER_EXT}"
"shaders/opticalflow/ffx_opticalflow_scale_optical_flow_advanced_pass_v5.${OPTICALFLOW_SHADER_EXT}"
)
# compile all the shaders
compile_shaders_with_depfile(
"${FFX_SC_EXECUTABLE}"
"${OPTICALFLOW_BASE_ARGS}" "${OPTICALFLOW_API_BASE_ARGS}" "${OPTICALFLOW_PERMUTATION_ARGS}" "${OPTICALFLOW_INCLUDE_ARGS}"
"${OPTICALFLOW_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" OPTICALFLOW_PERMUTATION_OUTPUTS)
# add the header files they generate to the main list of dependencies
add_shader_output("${OPTICALFLOW_PERMUTATION_OUTPUTS}")

View File

@@ -0,0 +1,578 @@
// 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_OPTICALFLOW_CALLBACKS_HLSL_H
#define FFX_OPTICALFLOW_CALLBACKS_HLSL_H
#include "opticalflow/ffx_opticalflow_resources.h"
// no msad4 in glsl
#define FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION 0
#define FFX_OPTICALFLOW_FIX_TOP_LEFT_BIAS 1
#define FFX_OPTICALFLOW_USE_HEURISTICS 1
#define FFX_OPTICALFLOW_BLOCK_SIZE 8
#define FFX_LOCAL_SEARCH_FALLBACK 1
// perf optimization for h/w not supporting accelerated msad4()
//#if !defined(FFX_PREFER_WAVE64) && defined(FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION)
//#undef FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION
//#endif
#if defined(FFX_GPU)
#include "ffx_core.h"
#endif // #if defined(FFX_GPU)
#if defined(FFX_GPU)
#ifndef FFX_PREFER_WAVE64
#define FFX_PREFER_WAVE64
#endif // #if defined(FFX_GPU)
#include "opticalflow/ffx_opticalflow_common.h"
#if defined(FFX_OPTICALFLOW_BIND_CB_COMMON)
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_CB_COMMON, std140) uniform cbOF_t
{
FfxInt32x2 iInputLumaResolution;
FfxUInt32 uOpticalFlowPyramidLevel;
FfxUInt32 uOpticalFlowPyramidLevelCount;
FfxUInt32 iFrameIndex;
FfxUInt32 backbufferTransferFunction;
FfxFloat32x2 minMaxLuminance;
} cbOF;
FfxInt32x2 DisplaySize()
{
return cbOF.iInputLumaResolution;
}
FfxUInt32 FrameIndex()
{
return cbOF.iFrameIndex;
}
FfxUInt32 BackbufferTransferFunction()
{
return cbOF.backbufferTransferFunction;
}
FfxFloat32x2 MinMaxLuminance()
{
return cbOF.minMaxLuminance;
}
FfxBoolean CrossedSceneChangeThreshold(FfxFloat32 sceneChangeValue)
{
return sceneChangeValue > 0.45f;
}
FfxUInt32 OpticalFlowPyramidLevel()
{
return cbOF.uOpticalFlowPyramidLevel;
}
FfxUInt32 OpticalFlowPyramidLevelCount()
{
return cbOF.uOpticalFlowPyramidLevelCount;
}
FfxInt32x2 OpticalFlowHistogramMaxVelocity()
{
const FfxInt32 searchRadius = 8;
FfxInt32 scale = FfxInt32(1) << (OpticalFlowPyramidLevelCount() - 1 - OpticalFlowPyramidLevel());
FfxInt32 maxVelocity = searchRadius * scale;
return FfxInt32x2(maxVelocity, maxVelocity);
}
#endif //FFX_OPTICALFLOW_BIND_CB_COMMON
#if defined(FFX_OPTICALFLOW_BIND_CB_SPD)
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_CB_SPD, std140) uniform cbOF_SPD_t
{
FfxUInt32 mips;
FfxUInt32 numWorkGroups;
FfxUInt32x2 workGroupOffset;
FfxUInt32 numWorkGroupOpticalFlowInputPyramid;
FfxUInt32 pad0_;
FfxUInt32 pad1_;
FfxUInt32 pad2_;
} cbOF_SPD;
uint NumWorkGroups()
{
return cbOF_SPD.numWorkGroupOpticalFlowInputPyramid;
}
#endif // defined(FFX_OPTICALFLOW_BIND_CB_SPD)
#if defined FFX_OPTICALFLOW_BIND_SRV_INPUT_COLOR
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_INPUT_COLOR) uniform texture2D r_input_color;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_INPUT_MOTION_VECTORS
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_INPUT_MOTION_VECTORS) uniform texture2D r_input_motion_vectors;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT) uniform utexture2D r_optical_flow_input;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT) uniform utexture2D r_optical_flow_previous_input;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW) uniform itexture2D r_optical_flow;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS) uniform itexture2D r_optical_flow_previous;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO) uniform utexture2D r_optical_flow_additional_info;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO_PREVIOUS
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO_PREVIOUS) uniform utexture2D r_optical_flow_additional_info_previous;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_HISTOGRAM
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_HISTOGRAM) uniform utexture2D r_optical_flow_histogram;
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH) uniform utexture2D r_optical_flow_global_motion_search;
#endif
// UAV declarations
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT, r8ui) uniform uimage2D rw_optical_flow_input;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1, r8ui) uniform uimage2D rw_optical_flow_input_level_1;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2, r8ui) uniform uimage2D rw_optical_flow_input_level_2;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3, r8ui) uniform uimage2D rw_optical_flow_input_level_3;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4, r8ui) uniform uimage2D rw_optical_flow_input_level_4;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5, r8ui) uniform uimage2D rw_optical_flow_input_level_5;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6, r8ui) uniform uimage2D rw_optical_flow_input_level_6;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW, rg16i) uniform iimage2D rw_optical_flow;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_NEXT_LEVEL
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_NEXT_LEVEL, rg16i) uniform iimage2D rw_optical_flow_next_level;
#endif
//#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO
// RWTexture2D<FfxUInt32x2> rw_optical_flow_additional_info : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO);
// layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO, r32ui) uniform uimage2D rw_optical_flow_additional_info;
//#endif
//#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO_NEXT_LEVEL
// RWTexture2D<FfxUInt32x2> rw_optical_flow_additional_info_next_level : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO_NEXT_LEVEL);
// layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO_NEXT_LEVEL, r32ui) uniform uimage2D rw_optical_flow_additional_info_next_level;
//#endif
//#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_HISTOGRAM
// RWTexture2D<FfxUInt32> rw_optical_flow_histogram : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_HISTOGRAM);
// layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_HISTOGRAM, r32ui) uniform uimage2D rw_optical_flow_histogram;
//#endif
//#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH
// globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_global_motion_search: FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH);
// layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH, r32ui) coherent uniform uimage2D rw_optical_flow_global_motion_search;
//#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM, r32ui) uniform uimage2D rw_optical_flow_scd_histogram;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM, r32f) uniform image2D rw_optical_flow_scd_previous_histogram;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP, r32ui) uniform uimage2D rw_optical_flow_scd_temp;
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT
layout (set = 0, binding = FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT, r32ui) uniform uimage2D rw_optical_flow_scd_output;
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_INPUT_COLOR)
FfxFloat32x4 LoadInputColor(FfxUInt32x2 iPxHistory)
{
return texelFetch(r_input_color, FfxInt32x2(iPxHistory), 0);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_INPUT_MOTION_VECTORS)
FfxFloat32x2 LoadGameMotionVector(FfxInt32x2 iPxPos)
{
FfxFloat32x2 positionScale = FfxFloat32x2(RenderSize()) / DisplaySize();
return texelFetch(r_input_motion_vectors, FfxInt32x2(iPxPos * positionScale), 0).xy * motionVectorScale / positionScale;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT)
void StoreOpticalFlowInput(FfxInt32x2 iPxPos, FfxUInt32 fLuma)
{
imageStore(rw_optical_flow_input, iPxPos, FfxUInt32x4(fLuma, 0, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT)
FfxUInt32 LoadOpticalFlowInput(FfxInt32x2 iPxPos)
{
#if FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION == 1
return max(1, texelFetch(r_optical_flow_input, iPxPos, 0).x);
#else
return texelFetch(r_optical_flow_input, iPxPos, 0).x;
#endif
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT)
FfxUInt32 LoadRwOpticalFlowInput(FfxInt32x2 iPxPos)
{
return imageLoad(rw_optical_flow_input, iPxPos).x;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT)
FfxUInt32 LoadOpticalFlowPreviousInput(FfxInt32x2 iPxPos)
{
#if FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION == 1
return max(1, texelFetch(r_optical_flow_previous_input, iPxPos, 0).x);
#else
return texelFetch(r_optical_flow_previous_input, iPxPos, 0).x;
#endif
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW)
FfxInt32x2 LoadOpticalFlow(FfxInt32x2 iPxPos)
{
return texelFetch(r_optical_flow, iPxPos, 0).xy;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW)
FfxInt32x2 LoadRwOpticalFlow(FfxInt32x2 iPxPos)
{
return imageLoad(rw_optical_flow, iPxPos).xy;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS)
FfxInt32x2 LoadPreviousOpticalFlow(FfxInt32x2 iPxPos)
{
return texelFetch(r_optical_flow_previous, iPxPos, 0).xy;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW)
void StoreOpticalFlow(FfxInt32x2 iPxPos, FfxInt32x2 motionVector)
{
imageStore(rw_optical_flow, iPxPos, FfxInt32x4(motionVector, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_NEXT_LEVEL)
void StoreOpticalFlowNextLevel(FfxInt32x2 iPxPos, FfxInt32x2 motionVector)
{
imageStore(rw_optical_flow_next_level, iPxPos, FfxInt32x4(motionVector, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO)
FfxUInt32x2 LoadOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos)
{
return texelFetch(r_optical_flow_additional_info, iPxPos, 0).xy;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO)
FfxUInt32x2 LoadRwOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos)
{
return imageLoad(rw_optical_flow_additional_info, iPxPos).xy;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO_PREVIOUS)
FfxUInt32x2 LoadPreviousOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos)
{
return texelFetch(r_optical_flow_additional_info_previous, iPxPos, 0).xy;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO)
void StoreOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos, FfxUInt32x2 additionalInfo)
{
imageStore(rw_optical_flow_additional_info, iPxPos, FfxUInt32x4(additionalInfo, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO_NEXT_LEVEL)
void StoreOpticalFlowNextLevelAdditionalInfo(FfxInt32x2 iPxPos, FfxUInt32x2 additionalInfo)
{
imageStore(rw_optical_flow_additional_info_next_level, iPxPos, FfxUInt32x4(additionalInfo, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_HISTOGRAM)
FfxUInt32 LoadOpticalFlowHistogram(FfxInt32x2 iBucketId)
{
return texelFetch(r_optical_flow_histogram, iBucketId, 0).x;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_HISTOGRAM)
void AtomicIncrementOpticalFlowHistogram(FfxInt32x2 iBucketId)
{
imageAtomicAdd(rw_optical_flow_histogram, iBucketId, 1);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxInt32x2 LoadGlobalMotionVector()
{
FfxInt32 vx = FfxInt32(texelFetch(r_optical_flow_global_motion_search, FfxInt32x2(0, 0), 0).x);
FfxInt32 vy = FfxInt32(texelFetch(r_optical_flow_global_motion_search, FfxInt32x2(1, 0), 0).x);
return FfxInt32x2(vx, vy);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxInt32x2 LoadRwGlobalMotionVector()
{
FfxInt32 vx = FfxInt32(imageLoad(rw_optical_flow_global_motion_search, FfxInt32x2(0, 0)).x);
FfxInt32 vy = FfxInt32(imageLoad(rw_optical_flow_global_motion_search, FfxInt32x2(1, 0)).x);
return FfxInt32x2(vx, vy);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxUInt32 LoadGlobalMotionValue(FfxInt32 index)
{
return imageLoad(rw_optical_flow_global_motion_search, FfxInt32x2(index, 0)).x;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
void StoreGlobalMotionValue(FfxInt32 index, FfxUInt32 value)
{
imageStore(rw_optical_flow_global_motion_search, FfxInt32x2(index, 0), FfxUInt32x4(value, 0, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxUInt32 AtomicIncrementGlobalMotionValue(FfxInt32 index)
{
return imageAtomicAdd(rw_optical_flow_global_motion_search, FfxInt32x2(index, 0), 1);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM)
FfxUInt32 LoadRwSCDHistogram(FfxInt32 iIndex)
{
return imageLoad(rw_optical_flow_scd_histogram, FfxInt32x2(iIndex, 0)).x;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM)
void StoreSCDHistogram(FfxInt32 iIndex, FfxUInt32 value)
{
imageStore(rw_optical_flow_scd_histogram, FfxInt32x2(iIndex, 0), FfxUInt32x4(value, 0, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM)
void AtomicIncrementSCDHistogram(FfxInt32 iIndex, FfxUInt32 valueToAdd)
{
imageAtomicAdd(rw_optical_flow_scd_histogram, FfxInt32x2(iIndex, 0), valueToAdd);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM)
FfxFloat32 LoadRwSCDPreviousHistogram(FfxInt32 iIndex)
{
return imageLoad(rw_optical_flow_scd_previous_histogram, FfxInt32x2(iIndex, 0)).x;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM)
void StoreSCDPreviousHistogram(FfxInt32 iIndex, FfxFloat32 value)
{
imageStore(rw_optical_flow_scd_previous_histogram, FfxInt32x2(iIndex, 0), FfxFloat32x4(value, 0.0, 0.0, 0.0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP)
FfxUInt32 LoadRwSCDTemp(FfxInt32 iIndex)
{
return imageLoad(rw_optical_flow_scd_temp, FfxInt32x2(iIndex, 0)).x;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP)
void AtomicIncrementSCDTemp(FfxInt32 iIndex, FfxUInt32 valueToAdd)
{
imageAtomicAdd(rw_optical_flow_scd_temp, FfxInt32x2(iIndex, 0), valueToAdd);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP)
void ResetSCDTemp()
{
imageStore(rw_optical_flow_scd_temp, FfxInt32x2(0, 0), FfxUInt32x4(0, 0, 0, 0));
imageStore(rw_optical_flow_scd_temp, FfxInt32x2(1, 0), FfxUInt32x4(0, 0, 0, 0));
imageStore(rw_optical_flow_scd_temp, FfxInt32x2(2, 0), FfxUInt32x4(0, 0, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
FfxUInt32 LoadRwSCDOutput(FfxInt32 iIndex)
{
return imageLoad(rw_optical_flow_scd_output, FfxInt32x2(iIndex, 0)).x;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
void StoreSCDOutput(FfxInt32 iIndex, FfxUInt32 value)
{
imageStore(rw_optical_flow_scd_output, FfxInt32x2(iIndex, 0), FfxUInt32x4(value, 0, 0, 0));
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
FfxUInt32 AtomicIncrementSCDOutput(FfxInt32 iIndex, FfxUInt32 valueToAdd)
{
return imageAtomicAdd(rw_optical_flow_scd_output, FfxInt32x2(iIndex, 0), valueToAdd);
}
#endif
//#if defined(FFX_OPTICALFLOW_BIND_UAV_DEBUG_VISUALIZATION)
//void StoreDebugVisualization(FfxUInt32x2 iPxPos, FfxFloat32x3 fColor)
//{
// imageStore(rw_debug_visualization, iPxPos, FfxFloat32x4(fColor, 1.f));
//}
//#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
FfxFloat32 GetSceneChangeValue()
{
if (FrameIndex() <= 5)
return 1.0;
else
return ffxAsFloat(LoadRwSCDOutput(SCD_OUTPUT_SCENE_CHANGE_SLOT));
}
FfxBoolean IsSceneChanged()
{
if (FrameIndex() <= 5)
{
return true;
}
else
{
return (LoadRwSCDOutput(SCD_OUTPUT_HISTORY_BITS_SLOT) & 0xfu) != 0;
}
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT)
FfxUInt32 LoadFirstImagePackedLuma(FfxInt32x2 iPxPos)
{
const FfxInt32 lumaTextureWidth = DisplaySize().x >> OpticalFlowPyramidLevel();
const FfxInt32 lumaTextureHeight = DisplaySize().y >> OpticalFlowPyramidLevel();
FfxInt32x2 adjustedPos = FfxInt32x2(
ffxClamp(iPxPos.x, 0, lumaTextureWidth - 4),
ffxClamp(iPxPos.y, 0, lumaTextureHeight - 1)
);
FfxUInt32 luma0 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(0, 0));
FfxUInt32 luma1 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(1, 0));
FfxUInt32 luma2 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(2, 0));
FfxUInt32 luma3 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(3, 0));
return GetPackedLuma(lumaTextureWidth, iPxPos.x, luma0, luma1, luma2, luma3);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT)
FfxUInt32 LoadSecondImagePackedLuma(FfxInt32x2 iPxPos)
{
const FfxInt32 lumaTextureWidth = DisplaySize().x >> OpticalFlowPyramidLevel();
const FfxInt32 lumaTextureHeight = DisplaySize().y >> OpticalFlowPyramidLevel();
FfxInt32x2 adjustedPos = FfxInt32x2(
ffxClamp(iPxPos.x, 0, lumaTextureWidth - 4),
ffxClamp(iPxPos.y, 0, lumaTextureHeight - 1)
);
FfxUInt32 luma0 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(0, 0));
FfxUInt32 luma1 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(1, 0));
FfxUInt32 luma2 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(2, 0));
FfxUInt32 luma3 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(3, 0));
return GetPackedLuma(lumaTextureWidth, iPxPos.x, luma0, luma1, luma2, luma3);
}
#endif
void SPD_SetMipmap(FfxInt32x2 iPxPos, FfxUInt32 index, FfxFloat32 value)
{
FfxUInt32x4 value4 = FfxUInt32x4(value, 0.0, 0.0, 0.0);
switch (index)
{
case 0:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1
imageStore(rw_optical_flow_input_level_1, iPxPos, value4);
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1
break;
case 1:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2
imageStore(rw_optical_flow_input_level_2, iPxPos, value4);
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2
break;
case 2:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3
imageStore(rw_optical_flow_input_level_3, iPxPos, value4);
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3
break;
case 3:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4
imageStore(rw_optical_flow_input_level_4, iPxPos, value4);
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4
break;
case 4:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5
imageStore(rw_optical_flow_input_level_5, iPxPos, value4);
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5
break;
case 5:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6
imageStore(rw_optical_flow_input_level_6, iPxPos, value4);
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6
break;
}
}
#endif // #if defined(FFX_GPU)
#endif // FFX_OPTICALFLOW_CALLBACKS_HLSL_H

View File

@@ -0,0 +1,634 @@
// 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_OPTICALFLOW_CALLBACKS_HLSL_H
#define FFX_OPTICALFLOW_CALLBACKS_HLSL_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
#define FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION 1
#define FFX_OPTICALFLOW_FIX_TOP_LEFT_BIAS 1
#define FFX_OPTICALFLOW_USE_HEURISTICS 1
#define FFX_OPTICALFLOW_BLOCK_SIZE 8
#define FFX_LOCAL_SEARCH_FALLBACK 1
// perf optimization for h/w not supporting accelerated msad4()
#if !defined(FFX_PREFER_WAVE64) && defined(FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION)
#undef FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION
#endif
#include "opticalflow/ffx_opticalflow_common.h"
#ifndef FFX_PREFER_WAVE64
#define FFX_PREFER_WAVE64
#endif
#pragma warning(disable: 3205) // conversion from larger type to smaller
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
#define DECLARE_CB_REGISTER(regIndex) b##regIndex
#define FFX_OPTICALFLOW_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
#define FFX_OPTICALFLOW_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
#define FFX_OPTICALFLOW_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
#if defined(FFX_OPTICALFLOW_BIND_CB_COMMON)
cbuffer cbOF : FFX_OPTICALFLOW_DECLARE_CB(FFX_OPTICALFLOW_BIND_CB_COMMON)
{
FfxInt32x2 iInputLumaResolution;
FfxUInt32 uOpticalFlowPyramidLevel;
FfxUInt32 uOpticalFlowPyramidLevelCount;
FfxUInt32 iFrameIndex;
FfxUInt32 backbufferTransferFunction;
FfxFloat32x2 minMaxLuminance;
};
#define FFX_OPTICALFLOW_CONSTANT_BUFFER_1_SIZE 8
#endif //FFX_OPTICALFLOW_BIND_CB_COMMON
#if defined(FFX_OPTICALFLOW_BIND_CB_SPD)
cbuffer cbOF_SPD : FFX_OPTICALFLOW_DECLARE_CB(FFX_OPTICALFLOW_BIND_CB_SPD) {
FfxUInt32 mips;
FfxUInt32 numWorkGroups;
FfxUInt32x2 workGroupOffset;
FfxUInt32 numWorkGroupOpticalFlowInputPyramid;
FfxUInt32 pad0_;
FfxUInt32 pad1_;
FfxUInt32 pad2_;
};
FfxUInt32 NumWorkGroups()
{
return numWorkGroupOpticalFlowInputPyramid;
}
#endif //FFX_OPTICALFLOW_BIND_CB_SPD
#define FFX_OPTICALFLOW_CONSTANT_BUFFER_2_SIZE 8
#define FFX_OPTICALFLOW_DESCRIPTOR_COUNT 32
#define FFX_OPTICALFLOW_ROOTSIG_STRINGIFY(p) FFX_OPTICALFLOW_ROOTSIG_STR(p)
#define FFX_OPTICALFLOW_ROOTSIG_STR(p) #p
#define FFX_OPTICALFLOW_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_OPTICALFLOW_ROOTSIG_STRINGIFY(FFX_OPTICALFLOW_DESCRIPTOR_COUNT) ")), " \
"DescriptorTable(SRV(t0, numDescriptors = " FFX_OPTICALFLOW_ROOTSIG_STRINGIFY(FFX_OPTICALFLOW_DESCRIPTOR_COUNT) ")), " \
"CBV(b0), " \
"StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_POINT, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \
"addressV = TEXTURE_ADDRESS_CLAMP, " \
"addressW = TEXTURE_ADDRESS_CLAMP, " \
"comparisonFunc = COMPARISON_NEVER, " \
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK), " \
"StaticSampler(s1, 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_OPTICALFLOW_CB2_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_OPTICALFLOW_ROOTSIG_STRINGIFY(FFX_OPTICALFLOW_DESCRIPTOR_COUNT) ")), " \
"DescriptorTable(SRV(t0, numDescriptors = " FFX_OPTICALFLOW_ROOTSIG_STRINGIFY(FFX_OPTICALFLOW_DESCRIPTOR_COUNT) ")), " \
"CBV(b0), " \
"StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_POINT, " \
"addressU = TEXTURE_ADDRESS_CLAMP, " \
"addressV = TEXTURE_ADDRESS_CLAMP, " \
"addressW = TEXTURE_ADDRESS_CLAMP, " \
"comparisonFunc = COMPARISON_NEVER, " \
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK), " \
"StaticSampler(s1, 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_OPTICALFLOW_EMBED_ROOTSIG)
#define FFX_OPTICALFLOW_EMBED_ROOTSIG_CONTENT FFX_OPTICALFLOW_ROOTSIG
#define FFX_OPTICALFLOW_EMBED_CB2_ROOTSIG_CONTENT FFX_OPTICALFLOW_CB2_ROOTSIG
#else
#define FFX_OPTICALFLOW_EMBED_ROOTSIG_CONTENT
#define FFX_OPTICALFLOW_EMBED_CB2_ROOTSIG_CONTENT
#endif // #if FFX_OPTICALFLOW_EMBED_ROOTSIG
FfxInt32x2 DisplaySize()
{
return iInputLumaResolution;
}
FfxUInt32 FrameIndex()
{
return iFrameIndex;
}
FfxUInt32 BackbufferTransferFunction()
{
return backbufferTransferFunction;
}
FfxFloat32x2 MinMaxLuminance()
{
return minMaxLuminance;
}
FfxBoolean CrossedSceneChangeThreshold(FfxFloat32 sceneChangeValue)
{
return sceneChangeValue > 0.45f;
}
FfxUInt32 OpticalFlowPyramidLevel()
{
return uOpticalFlowPyramidLevel;
}
FfxUInt32 OpticalFlowPyramidLevelCount()
{
return uOpticalFlowPyramidLevelCount;
}
FfxInt32x2 OpticalFlowHistogramMaxVelocity()
{
const FfxInt32 searchRadius = 8;
FfxInt32 scale = FfxInt32(1) << (OpticalFlowPyramidLevelCount() - 1 - OpticalFlowPyramidLevel());
FfxInt32 maxVelocity = searchRadius * scale;
return FfxInt32x2(maxVelocity, maxVelocity);
}
#if defined FFX_OPTICALFLOW_BIND_SRV_INPUT_COLOR
Texture2D<FfxFloat32x4> r_input_color : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_INPUT_COLOR);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_INPUT_MOTION_VECTORS
Texture2D<FfxFloat32x2> r_input_motion_vectors : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_INPUT_MOTION_VECTORS);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT
Texture2D<FfxUInt32> r_optical_flow_input : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT
Texture2D<FfxUInt32> r_optical_flow_previous_input : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW
Texture2D<FfxInt32x2> r_optical_flow : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS
Texture2D<FfxInt32x2> r_optical_flow_previous : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO
Texture2D<FfxUInt32x2> r_optical_flow_additional_info : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO_PREVIOUS
Texture2D<FfxUInt32x2> r_optical_flow_additional_info_previous : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO_PREVIOUS);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_HISTOGRAM
Texture2D<FfxUInt32> r_optical_flow_histogram : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_HISTOGRAM);
#endif
#if defined FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH
Texture2D<FfxUInt32> r_optical_flow_global_motion_search : FFX_OPTICALFLOW_DECLARE_SRV(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH);
#endif
// UAV declarations
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT
RWTexture2D<FfxUInt32> rw_optical_flow_input : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1
globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_input_level_1 : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2
globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_input_level_2 : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3
globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_input_level_3 : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4
globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_input_level_4 : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5
globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_input_level_5 : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6
globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_input_level_6 : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW
RWTexture2D<FfxInt32x2> rw_optical_flow : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_NEXT_LEVEL
RWTexture2D<FfxInt32x2> rw_optical_flow_next_level : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_NEXT_LEVEL);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO
RWTexture2D<FfxUInt32x2> rw_optical_flow_additional_info : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO_NEXT_LEVEL
RWTexture2D<FfxUInt32x2> rw_optical_flow_additional_info_next_level : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO_NEXT_LEVEL);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_HISTOGRAM
RWTexture2D<FfxUInt32> rw_optical_flow_histogram : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_HISTOGRAM);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH
globallycoherent RWTexture2D<FfxUInt32> rw_optical_flow_global_motion_search: FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM
RWTexture2D<FfxUInt32> rw_optical_flow_scd_histogram : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM
RWTexture2D<FfxFloat32> rw_optical_flow_scd_previous_histogram : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP
RWTexture2D<FfxUInt32> rw_optical_flow_scd_temp : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP);
#endif
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT
RWTexture2D<FfxUInt32> rw_optical_flow_scd_output : FFX_OPTICALFLOW_DECLARE_UAV(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT);
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_INPUT_COLOR)
FfxFloat32x4 LoadInputColor(FfxUInt32x2 iPxHistory)
{
return r_input_color[iPxHistory];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_INPUT_MOTION_VECTORS)
FfxFloat32x2 LoadGameMotionVector(FfxInt32x2 iPxPos)
{
FfxFloat32x2 positionScale = FfxFloat32x2(RenderSize()) / DisplaySize();
return r_input_motion_vectors[iPxPos * positionScale] * motionVectorScale / positionScale;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT)
void StoreOpticalFlowInput(FfxInt32x2 iPxPos, FfxUInt32 fLuma)
{
rw_optical_flow_input[iPxPos] = fLuma;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT)
FfxUInt32 LoadOpticalFlowInput(FfxInt32x2 iPxPos)
{
#if FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION == 1
return max(1, r_optical_flow_input[iPxPos]);
#else
return r_optical_flow_input[iPxPos];
#endif
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT)
FfxUInt32 LoadRwOpticalFlowInput(FfxInt32x2 iPxPos)
{
return rw_optical_flow_input[iPxPos];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT)
FfxUInt32 LoadOpticalFlowPreviousInput(FfxInt32x2 iPxPos)
{
#if FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION == 1
return max(1, r_optical_flow_previous_input[iPxPos]);
#else
return r_optical_flow_previous_input[iPxPos];
#endif
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW)
FfxInt32x2 LoadOpticalFlow(FfxInt32x2 iPxPos)
{
return r_optical_flow[iPxPos];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW)
FfxInt32x2 LoadRwOpticalFlow(FfxInt32x2 iPxPos)
{
return rw_optical_flow[iPxPos];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS)
FfxInt32x2 LoadPreviousOpticalFlow(FfxInt32x2 iPxPos)
{
return r_optical_flow_previous[iPxPos];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW)
void StoreOpticalFlow(FfxInt32x2 iPxPos, FfxInt32x2 motionVector)
{
rw_optical_flow[iPxPos] = motionVector;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_NEXT_LEVEL)
void StoreOpticalFlowNextLevel(FfxInt32x2 iPxPos, FfxInt32x2 motionVector)
{
rw_optical_flow_next_level[iPxPos] = motionVector;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO)
FfxUInt32x2 LoadOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos)
{
return r_optical_flow_additional_info[iPxPos];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO)
FfxUInt32x2 LoadRwOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos)
{
return rw_optical_flow_additional_info[iPxPos];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_ADDITIONAL_INFO_PREVIOUS)
FfxUInt32x2 LoadPreviousOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos)
{
return r_optical_flow_additional_info_previous[iPxPos];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO)
void StoreOpticalFlowAdditionalInfo(FfxInt32x2 iPxPos, FfxUInt32x2 additionalInfo)
{
rw_optical_flow_additional_info[iPxPos] = additionalInfo;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_ADDITIONAL_INFO_NEXT_LEVEL)
void StoreOpticalFlowNextLevelAdditionalInfo(FfxInt32x2 iPxPos, FfxUInt32x2 additionalInfo)
{
rw_optical_flow_additional_info_next_level[iPxPos] = additionalInfo;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_HISTOGRAM)
FfxUInt32 LoadOpticalFlowHistogram(FfxInt32x2 iBucketId)
{
return r_optical_flow_histogram[iBucketId];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_HISTOGRAM)
void AtomicIncrementOpticalFlowHistogram(FfxInt32x2 iBucketId)
{
InterlockedAdd(rw_optical_flow_histogram[iBucketId], 1);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxInt32x2 LoadGlobalMotionVector()
{
FfxInt32 vx = FfxInt32(r_optical_flow_global_motion_search[FfxInt32x2(0, 0)]);
FfxInt32 vy = FfxInt32(r_optical_flow_global_motion_search[FfxInt32x2(1, 0)]);
return FfxInt32x2(vx, vy);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxInt32x2 LoadRwGlobalMotionVector()
{
FfxInt32 vx = FfxInt32(rw_optical_flow_global_motion_search[FfxInt32x2(0, 0)]);
FfxInt32 vy = FfxInt32(rw_optical_flow_global_motion_search[FfxInt32x2(1, 0)]);
return FfxInt32x2(vx, vy);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxUInt32 LoadGlobalMotionValue(FfxInt32 index)
{
return rw_optical_flow_global_motion_search[FfxInt32x2(index, 0)];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
void StoreGlobalMotionValue(FfxInt32 index, FfxUInt32 value)
{
rw_optical_flow_global_motion_search[FfxInt32x2(index, 0)] = value;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_GLOBAL_MOTION_SEARCH)
FfxUInt32 AtomicIncrementGlobalMotionValue(FfxInt32 index)
{
FfxUInt32 initialValue;
InterlockedAdd(rw_optical_flow_global_motion_search[FfxInt32x2(index, 0)], 1, initialValue);
return initialValue;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM)
FfxUInt32 LoadRwSCDHistogram(FfxInt32 iIndex)
{
return rw_optical_flow_scd_histogram[FfxInt32x2(iIndex, 0)];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM)
void StoreSCDHistogram(FfxInt32 iIndex, FfxUInt32 value)
{
rw_optical_flow_scd_histogram[FfxInt32x2(iIndex, 0)] = value;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_HISTOGRAM)
void AtomicIncrementSCDHistogram(FfxInt32 iIndex, FfxUInt32 valueToAdd)
{
InterlockedAdd(rw_optical_flow_scd_histogram[FfxInt32x2(iIndex, 0)], valueToAdd);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM)
FfxFloat32 LoadRwSCDPreviousHistogram(FfxInt32 iIndex)
{
return rw_optical_flow_scd_previous_histogram[FfxInt32x2(iIndex, 0)];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM)
void StoreSCDPreviousHistogram(FfxInt32 iIndex, FfxFloat32 value)
{
rw_optical_flow_scd_previous_histogram[FfxInt32x2(iIndex, 0)] = value;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP)
FfxUInt32 LoadRwSCDTemp(FfxInt32 iIndex)
{
return rw_optical_flow_scd_temp[FfxInt32x2(iIndex, 0)];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP)
void AtomicIncrementSCDTemp(FfxInt32 iIndex, FfxUInt32 valueToAdd)
{
InterlockedAdd(rw_optical_flow_scd_temp[FfxInt32x2(iIndex, 0)], valueToAdd);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_TEMP)
void ResetSCDTemp()
{
rw_optical_flow_scd_temp[FfxInt32x2(0, 0)] = 0;
rw_optical_flow_scd_temp[FfxInt32x2(1, 0)] = 0;
rw_optical_flow_scd_temp[FfxInt32x2(2, 0)] = 0;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
FfxUInt32 LoadRwSCDOutput(FfxInt32 iIndex)
{
return rw_optical_flow_scd_output[FfxInt32x2(iIndex, 0)];
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
void StoreSCDOutput(FfxInt32 iIndex, FfxUInt32 value)
{
rw_optical_flow_scd_output[FfxInt32x2(iIndex, 0)] = value;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
FfxUInt32 AtomicIncrementSCDOutput(FfxInt32 iIndex, FfxUInt32 valueToAdd)
{
FfxUInt32 initialValue;
InterlockedAdd(rw_optical_flow_scd_output[FfxInt32x2(iIndex, 0)], valueToAdd, initialValue);
return initialValue;
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_DEBUG_VISUALIZATION)
void StoreDebugVisualization(FfxUInt32x2 iPxPos, FfxFloat32x3 fColor)
{
rw_debug_visualization[iPxPos] = FfxFloat32x4(fColor, 1.f);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_SCD_OUTPUT)
FfxFloat32 GetSceneChangeValue()
{
if (FrameIndex() <= 5)
return 1.0;
else
return ffxAsFloat(LoadRwSCDOutput(SCD_OUTPUT_SCENE_CHANGE_SLOT));
}
FfxBoolean IsSceneChanged()
{
if (FrameIndex() <= 5)
{
return 1.0;
}
else
{
return (LoadRwSCDOutput(SCD_OUTPUT_HISTORY_BITS_SLOT) & 0xfu) != 0;
}
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_INPUT)
FfxUInt32 LoadFirstImagePackedLuma(FfxInt32x2 iPxPos)
{
const FfxInt32 lumaTextureWidth = DisplaySize().x >> OpticalFlowPyramidLevel();
const FfxInt32 lumaTextureHeight = DisplaySize().y >> OpticalFlowPyramidLevel();
FfxInt32x2 adjustedPos = FfxInt32x2(
ffxClamp(iPxPos.x, 0, lumaTextureWidth - 4),
ffxClamp(iPxPos.y, 0, lumaTextureHeight - 1)
);
FfxUInt32 luma0 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(0, 0));
FfxUInt32 luma1 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(1, 0));
FfxUInt32 luma2 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(2, 0));
FfxUInt32 luma3 = LoadOpticalFlowInput(adjustedPos + FfxInt32x2(3, 0));
return GetPackedLuma(lumaTextureWidth, iPxPos.x, luma0, luma1, luma2, luma3);
}
#endif
#if defined(FFX_OPTICALFLOW_BIND_SRV_OPTICAL_FLOW_PREVIOUS_INPUT)
FfxUInt32 LoadSecondImagePackedLuma(FfxInt32x2 iPxPos)
{
const FfxInt32 lumaTextureWidth = DisplaySize().x >> OpticalFlowPyramidLevel();
const FfxInt32 lumaTextureHeight = DisplaySize().y >> OpticalFlowPyramidLevel();
FfxInt32x2 adjustedPos = FfxInt32x2(
ffxClamp(iPxPos.x, 0, lumaTextureWidth - 4),
ffxClamp(iPxPos.y, 0, lumaTextureHeight - 1)
);
FfxUInt32 luma0 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(0, 0));
FfxUInt32 luma1 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(1, 0));
FfxUInt32 luma2 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(2, 0));
FfxUInt32 luma3 = LoadOpticalFlowPreviousInput(adjustedPos + FfxInt32x2(3, 0));
return GetPackedLuma(lumaTextureWidth, iPxPos.x, luma0, luma1, luma2, luma3);
}
#endif
void SPD_SetMipmap(int2 iPxPos, int index, float value)
{
switch (index)
{
case 0:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1
rw_optical_flow_input_level_1[iPxPos] = value;
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_1
break;
case 1:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2
rw_optical_flow_input_level_2[iPxPos] = value;
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_2
break;
case 2:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3
rw_optical_flow_input_level_3[iPxPos] = value;
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_3
break;
case 3:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4
rw_optical_flow_input_level_4[iPxPos] = value;
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_4
break;
case 4:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5
rw_optical_flow_input_level_5[iPxPos] = value;
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_5
break;
case 5:
#if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6
rw_optical_flow_input_level_6[iPxPos] = value;
#endif // #if defined FFX_OPTICALFLOW_BIND_UAV_OPTICAL_FLOW_INPUT_LEVEL_6
break;
}
}
#endif // #if defined(FFX_GPU)
#endif // FFX_OPTICALFLOW_CALLBACKS_HLSL_H

View File

@@ -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.
#if !defined(FFX_OPTICALFLOW_COMMON_H)
#define FFX_OPTICALFLOW_COMMON_H
#if defined(FFX_GPU)
#define SCD_OUTPUT_SCENE_CHANGE_SLOT 0
#define SCD_OUTPUT_HISTORY_BITS_SLOT 1
#define SCD_OUTPUT_COMPLETED_WORKGROUPS_SLOT 2
#define ffxClamp(x, a, b) (ffxMax(a, ffxMin(b, x)))
FfxUInt32 GetPackedLuma(FfxInt32 width, FfxInt32 x, FfxUInt32 luma0, FfxUInt32 luma1, FfxUInt32 luma2, FfxUInt32 luma3)
{
FfxUInt32 packedLuma = luma0 | (luma1 << 8) | (luma2 << 16) | (luma3 << 24);
if (x < 0)
{
FfxUInt32 outOfScreenFiller = packedLuma & 0xffu;
if (x <= -1)
packedLuma = (packedLuma << 8) | outOfScreenFiller;
if (x <= -2)
packedLuma = (packedLuma << 8) | outOfScreenFiller;
if (x <= -3)
packedLuma = (packedLuma << 8) | outOfScreenFiller;
}
else if (x > width - 4)
{
FfxUInt32 outOfScreenFiller = packedLuma & 0xff000000u;
if (x >= width - 3)
packedLuma = (packedLuma >> 8) | outOfScreenFiller;
if (x >= width - 2)
packedLuma = (packedLuma >> 8) | outOfScreenFiller;
if (x >= width - 1)
packedLuma = (packedLuma >> 8) | outOfScreenFiller;
}
return packedLuma;
}
FfxUInt32 Sad(FfxUInt32 a, FfxUInt32 b)
{
#if FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION == 1
return msad4(a, FfxUInt32x2(b, 0), FfxUInt32x4(0, 0, 0, 0)).x;
#else
return abs(FfxInt32((a >> 0) & 0xffu) - FfxInt32((b >> 0) & 0xffu)) +
abs(FfxInt32((a >> 8) & 0xffu) - FfxInt32((b >> 8) & 0xffu)) +
abs(FfxInt32((a >> 16) & 0xffu) - FfxInt32((b >> 16) & 0xffu)) +
abs(FfxInt32((a >> 24) & 0xffu) - FfxInt32((b >> 24) & 0xffu));
#endif
}
FfxUInt32x4 QSad(FfxUInt32 a0, FfxUInt32 a1, FfxUInt32 b)
{
#if FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION == 1
return msad4(b, FfxUInt32x2(a0, a1), FfxUInt32x4(0, 0, 0, 0));
#else
FfxUInt32x4 sad;
sad.x = Sad(a0, b);
a0 = (a0 >> 8) | ((a1 & 0xffu) << 24);
a1 >>= 8;
sad.y = Sad(a0, b);
a0 = (a0 >> 8) | ((a1 & 0xffu) << 24);
a1 >>= 8;
sad.z = Sad(a0, b);
a0 = (a0 >> 8) | ((a1 & 0xffu) << 24);
sad.w = Sad(a0, b);
return sad;
#endif
}
#endif // #if defined(FFX_GPU)
#endif //!defined(FFX_OPTICALFLOW_COMMON_H)

View File

@@ -0,0 +1,107 @@
// 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_OPTICALFLOW_COMPUTE_LUMINANCE_PYRAMID_H
#define FFX_OPTICALFLOW_COMPUTE_LUMINANCE_PYRAMID_H
FFX_GROUPSHARED FfxFloat32 spdIntermediateR[16][16];
FFX_GROUPSHARED FfxFloat32 spdIntermediateG[16][16];
FFX_GROUPSHARED FfxFloat32 spdIntermediateB[16][16];
FFX_GROUPSHARED FfxFloat32 spdIntermediateA[16][16];
void SPD_IncreaseAtomicCounter(inout FfxUInt32 spdCounter)
{
}
void SPD_ResetAtomicCounter()
{
}
FfxFloat32x4 SpdLoadSourceImage(FfxFloat32x2 tex, FfxUInt32 slice)
{
FfxFloat32 luma = LoadRwOpticalFlowInput(FfxInt32x2(tex));
return FfxFloat32x4(luma, 0, 0, 0);
}
FfxFloat32x4 SpdLoad(FfxInt32x2 tex, FfxUInt32 slice)
{
return FfxFloat32x4(0, 0, 0, 0);
}
void SpdStore(FfxInt32x2 pix, FfxFloat32x4 outValue, FfxUInt32 index, FfxUInt32 slice)
{
SPD_SetMipmap(pix, index, outValue.r);
}
void SpdIncreaseAtomicCounter(FfxUInt32 slice)
{
}
FfxUInt32 SpdGetAtomicCounter()
{
return 0;
}
void SpdResetAtomicCounter(FfxUInt32 slice)
{
SPD_ResetAtomicCounter();
}
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)
{
return (v0 + v1 + v2 + v3) * 0.25;
}
#ifdef FFX_HALF
#undef FFX_HALF
#endif
// https://github.com/GPUOpen-Effects/FidelityFX-SPD/blob/master/docs/FidelityFX_SPD.pdf
#include "spd/ffx_spd.h"
void ComputeOpticalFlowInputPyramid(FfxInt32x2 iGroupId, FfxInt32 iLocalIndex)
{
SpdDownsample(
FfxUInt32x2(iGroupId.xy),
FfxUInt32(iLocalIndex),
6, // mip levels to generate
FfxUInt32(NumWorkGroups()),
1 // single slice
);
}
#endif // FFX_OPTICALFLOW_COMPUTE_LUMINANCE_PYRAMID_H

View File

@@ -0,0 +1,279 @@
// 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_OPTICALFLOW_COMPUTE_OPTICAL_FLOW_V5_H
#define FFX_OPTICALFLOW_COMPUTE_OPTICAL_FLOW_V5_H
#define CompareSize (4 * 2)
#define BlockSizeY 8
#define BlockSizeX 8
#define ThreadCount (4 * 16)
#define SearchRadiusX (8)
#define SearchRadiusY (8)
#define BlockCount 2
#define SearchBufferSizeX ((CompareSize + SearchRadiusX*2)/4)
#define SearchBufferSizeY (CompareSize + SearchRadiusY*2)
FFX_GROUPSHARED FfxUInt32 pixels[CompareSize][CompareSize / 4];
FFX_GROUPSHARED FfxUInt32 searchBuffer[1][SearchBufferSizeY * SearchBufferSizeX];
#define bankBreaker 1
FFX_GROUPSHARED FfxUInt32 sadMapBuffer[4][SearchRadiusY * 2][(SearchRadiusX * 2) / 4 + bankBreaker];
#define MaxWaves 2
FFX_GROUPSHARED FfxUInt32 sWaveSad[MaxWaves];
FFX_GROUPSHARED FfxUInt32 sWaveMin[MaxWaves];
FfxUInt32 BlockSad64(FfxUInt32 blockSadSum, FfxInt32 iLocalIndex, FfxInt32 iLaneToBlockId, FfxInt32 block)
{
if (iLaneToBlockId != block)
{
blockSadSum = 0u;
}
blockSadSum = ffxWaveSum(blockSadSum);
if (ffxWaveLaneCount() == 32)
{
FfxInt32 waveId = iLocalIndex >> 5u;
if (ffxWaveIsFirstLane())
{
sWaveSad[waveId] = blockSadSum;
}
FFX_GROUP_MEMORY_BARRIER;
blockSadSum += sWaveSad[waveId ^ 1];
}
return blockSadSum;
}
FfxUInt32 SadMapMinReduction256(FfxInt32x2 iSearchId, FfxInt32 iLocalIndex)
{
FfxUInt32 min01 = ffxMin(sadMapBuffer[0][iSearchId.y][iSearchId.x], sadMapBuffer[1][iSearchId.y][iSearchId.x]);
FfxUInt32 min23 = ffxMin(sadMapBuffer[2][iSearchId.y][iSearchId.x], sadMapBuffer[3][iSearchId.y][iSearchId.x]);
FfxUInt32 min0123 = ffxMin(min01, min23);
min0123 = ffxWaveMin(min0123);
if (ffxWaveLaneCount() == 32)
{
FfxInt32 waveId = iLocalIndex >> 5u;
if (ffxWaveIsFirstLane())
{
sWaveMin[waveId] = min0123;
}
FFX_GROUP_MEMORY_BARRIER;
min0123 = ffxMin(min0123, sWaveMin[waveId ^ 1]);
}
return min0123;
}
void LoadSearchBuffer(FfxInt32 iLocalIndex, FfxInt32x2 iPxPosShifted)
{
FfxInt32 baseX = (iPxPosShifted.x - SearchRadiusX);
FfxInt32 baseY = (iPxPosShifted.y - SearchRadiusY);
for (FfxInt32 id = iLocalIndex; id < SearchBufferSizeX * SearchBufferSizeY; id += ThreadCount)
{
FfxInt32 idx = id % SearchBufferSizeX;
FfxInt32 idy = id / SearchBufferSizeX;
FfxInt32 x = baseX + idx * 4;
FfxInt32 y = baseY + idy;
searchBuffer[0][id] = LoadSecondImagePackedLuma(FfxInt32x2(x, y));
}
FFX_GROUP_MEMORY_BARRIER;
}
FfxUInt32x4 CalculateQSads2(FfxInt32x2 iSearchId)
{
FfxUInt32x4 sad = ffxBroadcast4(0u);
#if FFX_OPTICALFLOW_USE_MSAD4_INSTRUCTION == 1
FfxInt32 idx = iSearchId.y * 6 + iSearchId.x;
sad = msad4(pixels[0][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[0][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
idx += 6;
sad = msad4(pixels[1][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[1][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
idx += 6;
sad = msad4(pixels[2][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[2][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
idx += 6;
sad = msad4(pixels[3][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[3][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
idx += 6;
sad = msad4(pixels[4][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[4][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
idx += 6;
sad = msad4(pixels[5][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[5][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
idx += 6;
sad = msad4(pixels[6][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[6][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
idx += 6;
sad = msad4(pixels[7][0], FfxUInt32x2(searchBuffer[0][idx], searchBuffer[0][idx + 1]), sad);
sad = msad4(pixels[7][1], FfxUInt32x2(searchBuffer[0][idx + 1], searchBuffer[0][idx + 2]), sad);
#else
for (FfxInt32 dy = 0; dy < CompareSize; dy++)
{
FfxInt32 rowOffset = (iSearchId.y + dy) * SearchBufferSizeX;
FfxUInt32 a0 = searchBuffer[0][rowOffset + iSearchId.x];
FfxUInt32 a1 = searchBuffer[0][rowOffset + iSearchId.x + 1];
FfxUInt32 a2 = searchBuffer[0][rowOffset + iSearchId.x + 2];
sad += QSad(a0, a1, pixels[dy][0]);
sad += QSad(a1, a2, pixels[dy][1]);
}
#endif
return sad;
}
FfxUInt32x2 abs_2(FfxInt32x2 val)
{
FfxInt32x2 tmp = val;
FfxInt32x2 mask = tmp >> 31;
FfxUInt32x2 res = (tmp + mask) ^ mask;
return res;
}
FfxUInt32 EncodeSearchCoord(FfxInt32x2 coord)
{
#if FFX_OPTICALFLOW_FIX_TOP_LEFT_BIAS == 1
FfxUInt32x2 absCoord = FfxUInt32x2(abs_2(coord - 8));
return FfxUInt32(absCoord.y << 12) | FfxUInt32(absCoord.x << 8) | FfxUInt32(coord.y << 4) | FfxUInt32(coord.x);
#else //FFX_OPTICALFLOW_FIX_TOP_LEFT_BIAS == 1
return FfxUInt32(coord.y << 8) | FfxUInt32(coord.x);
#endif //FFX_OPTICALFLOW_FIX_TOP_LEFT_BIAS == 1
}
FfxInt32x2 DecodeSearchCoord(FfxUInt32 bits)
{
#if FFX_OPTICALFLOW_FIX_TOP_LEFT_BIAS == 1
FfxInt32 dx = FfxInt32(bits & 0xfu) - SearchRadiusX;
FfxInt32 dy = FfxInt32((bits >> 4) & 0xfu) - SearchRadiusY;
return FfxInt32x2(dx, dy);
#else
FfxInt32 dx = FfxInt32(bits & 0xffu) - SearchRadiusX;
FfxInt32 dy = FfxInt32((bits >> 8) & 0xffu) - SearchRadiusY;
return FfxInt32x2(dx, dy);
#endif
}
void PrepareSadMap(FfxInt32x2 iSearchId, FfxUInt32x4 qsad)
{
sadMapBuffer[0][iSearchId.y][iSearchId.x] = (qsad.x << 16) | EncodeSearchCoord(FfxInt32x2(iSearchId.x * 4 + 0, iSearchId.y));
sadMapBuffer[1][iSearchId.y][iSearchId.x] = (qsad.y << 16) | EncodeSearchCoord(FfxInt32x2(iSearchId.x * 4 + 1, iSearchId.y));
sadMapBuffer[2][iSearchId.y][iSearchId.x] = (qsad.z << 16) | EncodeSearchCoord(FfxInt32x2(iSearchId.x * 4 + 2, iSearchId.y));
sadMapBuffer[3][iSearchId.y][iSearchId.x] = (qsad.w << 16) | EncodeSearchCoord(FfxInt32x2(iSearchId.x * 4 + 3, iSearchId.y));
FFX_GROUP_MEMORY_BARRIER;
}
uint ABfe(uint src, uint off, uint bits) { uint mask = (1u << bits) - 1u; return (src >> off) & mask; }
uint ABfi(uint src, uint ins, uint mask) { return (ins & mask) | (src & (~mask)); }
uint ABfiM(uint src, uint ins, uint bits) { uint mask = (1u << bits) - 1u; return (ins & mask) | (src & (~mask)); }
void MapThreads(in FfxInt32x2 iGroupId, in FfxInt32 iLocalIndex,
out FfxInt32x2 iSearchId, out FfxInt32x2 iPxPos, out FfxInt32 iLaneToBlockId)
{
iSearchId = FfxInt32x2(ABfe(iLocalIndex, 0u, 2u), ABfe(iLocalIndex, 2u, 4u));
iLaneToBlockId = FfxInt32(ABfe(iLocalIndex, 1u, 1u) | (ABfe(iLocalIndex, 5u, 1u) << 1u));
iPxPos = (iGroupId << 4u) + iSearchId * FfxInt32x2(4, 1);
}
void ComputeOpticalFlowAdvanced(FfxInt32x2 iGlobalId, FfxInt32x2 iLocalId, FfxInt32x2 iGroupId, FfxInt32 iLocalIndex)
{
FfxInt32x2 iSearchId;
FfxInt32x2 iPxPos;
FfxInt32 iLaneToBlockId;
MapThreads(iGroupId, iLocalIndex, iSearchId, iPxPos, iLaneToBlockId);
FfxInt32x2 currentOFPos = iPxPos >> 3u;
if (IsSceneChanged())
{
if ((iSearchId.y & 0x7) == 0 && (iSearchId.x & 0x1) == 0)
{
StoreOpticalFlow(currentOFPos, FfxInt32x2(0, 0));
}
return;
}
const FfxBoolean bUsePredictionFromPreviousLevel = (OpticalFlowPyramidLevel() != OpticalFlowPyramidLevelCount() - 1);
FfxUInt32 packedLuma_4blocks = LoadFirstImagePackedLuma(iPxPos);
#if FFX_LOCAL_SEARCH_FALLBACK == 1
FfxUInt32 prevPackedLuma_4blocks = LoadSecondImagePackedLuma(iPxPos);
FfxUInt32 sad_4blocks = Sad(packedLuma_4blocks, prevPackedLuma_4blocks);
#endif //FFX_LOCAL_SEARCH_FALLBACK
FfxInt32x2 ofGroupOffset = iGroupId << 1u;
FfxInt32x2 pixelGroupOffset = iGroupId << 4u;
FfxInt32x2 blockId;
for (blockId.y = 0; blockId.y < BlockCount; blockId.y++)
{
for (blockId.x = 0; blockId.x < BlockCount; blockId.x++)
{
FfxInt32x2 currentVector = LoadRwOpticalFlow(ofGroupOffset + blockId);
if (!bUsePredictionFromPreviousLevel)
{
currentVector = FfxInt32x2(0, 0);
}
if (iLaneToBlockId == blockId.y * 2 + blockId.x)
{
pixels[iSearchId.y & 0x7][iSearchId.x & 0x1] = packedLuma_4blocks;
}
LoadSearchBuffer(iLocalIndex, pixelGroupOffset + blockId * 8 + currentVector);
FfxUInt32x4 qsad = CalculateQSads2(iSearchId);
PrepareSadMap(iSearchId, qsad);
FfxUInt32 minSad = SadMapMinReduction256(iSearchId, iLocalIndex);
FfxInt32x2 minSadCoord = DecodeSearchCoord(minSad);
FfxInt32x2 newVector = currentVector + minSadCoord;
#if FFX_LOCAL_SEARCH_FALLBACK == 1
FfxUInt32 blockSadSum = BlockSad64(sad_4blocks, iLocalIndex, iLaneToBlockId, blockId.x + blockId.y * 2);
if (OpticalFlowPyramidLevel() == 0 && blockSadSum <= (minSad >> 16u))
{
newVector = FfxInt32x2(0, 0);
}
#endif //FFX_LOCAL_SEARCH_FALLBACK
{
StoreOpticalFlow(ofGroupOffset + blockId, newVector);
}
}
}
}
#endif // FFX_OPTICALFLOW_COMPUTE_OPTICAL_FLOW_V5_H

View File

@@ -0,0 +1,159 @@
// 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_OPTICALFLOW_COMPUTE_SCD_DIVERGENCE_H
#define FFX_OPTICALFLOW_COMPUTE_SCD_DIVERGENCE_H
FFX_GROUPSHARED FfxFloat32 sourceHistogram[256];
FFX_GROUPSHARED FfxFloat32 filteredHistogram[256];
FFX_GROUPSHARED FfxFloat32 tempBuffer[256];
FFX_GROUPSHARED FfxFloat32x2 tempBuffer2[256];
void ComputeSCDHistogramsDivergence(FfxInt32x3 iGlobalId, FfxInt32x2 iLocalId, FfxInt32 iLocalIndex, FfxInt32x2 iGroupId, FfxInt32x2 iGroupSize)
{
FFX_STATIC const FfxFloat32 Factor = 1000000.0;
FFX_STATIC const FfxInt32 WhereToStop = 3*9 - 1;
FFX_STATIC const FfxInt32 HistogramCount = 3 * 3;
FFX_STATIC const FfxFloat32 Kernel[] = {
0.0088122291, 0.027143577, 0.065114059, 0.12164907, 0.17699835, 0.20056541
};
sourceHistogram[iLocalIndex] = FfxFloat32(LoadRwSCDHistogram(iGlobalId.x));
FFX_GROUP_MEMORY_BARRIER;
const FfxInt32 kernelShift = -5;
const FfxInt32 indexToRead = iLocalIndex + kernelShift;
FfxFloat32 val = 0.0;
val += Kernel[0] * sourceHistogram[ffxClamp(indexToRead + 0, 0, 255)];
val += Kernel[1] * sourceHistogram[ffxClamp(indexToRead + 1, 0, 255)];
val += Kernel[2] * sourceHistogram[ffxClamp(indexToRead + 2, 0, 255)];
val += Kernel[3] * sourceHistogram[ffxClamp(indexToRead + 3, 0, 255)];
val += Kernel[4] * sourceHistogram[ffxClamp(indexToRead + 4, 0, 255)];
val += Kernel[5] * sourceHistogram[ffxClamp(indexToRead + 5, 0, 255)];
val += Kernel[4] * sourceHistogram[ffxClamp(indexToRead + 6, 0, 255)];
val += Kernel[3] * sourceHistogram[ffxClamp(indexToRead + 7, 0, 255)];
val += Kernel[2] * sourceHistogram[ffxClamp(indexToRead + 8, 0, 255)];
val += Kernel[1] * sourceHistogram[ffxClamp(indexToRead + 9, 0, 255)];
val += Kernel[0] * sourceHistogram[ffxClamp(indexToRead + 10, 0, 255)];
val += 1.0;
if (iGlobalId.y == 0)
{
if (iLocalIndex == 0)
filteredHistogram[255] = 1.0;
else
filteredHistogram[iLocalIndex - 1] = val;
}
else if (iGlobalId.y == 1)
{
filteredHistogram[iLocalIndex] = val;
}
else if (iGlobalId.y == 2)
{
if (iLocalIndex == 255)
filteredHistogram[0] = 1.0;
else
filteredHistogram[iLocalIndex + 1] = val;
}
FFX_GROUP_MEMORY_BARRIER;
tempBuffer[iLocalIndex] = filteredHistogram[iLocalIndex];
FFX_GROUP_MEMORY_BARRIER;
if (iLocalIndex < 128) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 128];
FFX_GROUP_MEMORY_BARRIER;
if (iLocalIndex < 64) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 64];
FFX_GROUP_MEMORY_BARRIER;
if (iLocalIndex < 32) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 32];
if (iLocalIndex < 16) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 16];
if (iLocalIndex < 8 ) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 8];
if (iLocalIndex < 4 ) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 4];
if (iLocalIndex < 2 ) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 2];
if (iLocalIndex < 1 ) tempBuffer[iLocalIndex] += tempBuffer[iLocalIndex + 1];
FFX_GROUP_MEMORY_BARRIER;
filteredHistogram[iLocalIndex] /= tempBuffer[0];
FfxFloat32 currentFilteredHistogramsValue = filteredHistogram[iLocalIndex];
FfxFloat32 previousHistogramsValue = LoadRwSCDPreviousHistogram(iGlobalId.x);
tempBuffer2[iLocalIndex] = FfxFloat32x2(
currentFilteredHistogramsValue * log(currentFilteredHistogramsValue / previousHistogramsValue),
previousHistogramsValue * log(previousHistogramsValue / currentFilteredHistogramsValue)
);
FFX_GROUP_MEMORY_BARRIER;
if (iLocalIndex < 128) tempBuffer2[iLocalIndex] += tempBuffer2[iLocalIndex + 128];
FFX_GROUP_MEMORY_BARRIER;
if (iLocalIndex < 64) tempBuffer2[iLocalIndex] += tempBuffer2[iLocalIndex + 64];
FFX_GROUP_MEMORY_BARRIER;
if (iLocalIndex < 32) tempBuffer2[iLocalIndex] += tempBuffer2[iLocalIndex + 32];
if (iLocalIndex < 16) tempBuffer2[iLocalIndex] += tempBuffer2[iLocalIndex + 16];
if (iLocalIndex < 8 ) tempBuffer2[iLocalIndex] += tempBuffer2[iLocalIndex + 8];
if (iLocalIndex < 4 ) tempBuffer2[iLocalIndex] += tempBuffer2[iLocalIndex + 4];
if (iLocalIndex < 2 ) tempBuffer2[iLocalIndex] += tempBuffer2[iLocalIndex + 2];
if (iLocalIndex == 0)
{
FfxFloat32x2 sum = tempBuffer2[0] + tempBuffer2[1];
FfxFloat32 resFloat = 1 - exp(-(abs(sum.x) + abs(sum.y)));
FfxUInt32 resUInt = FfxUInt32((resFloat / FfxFloat32(HistogramCount)) * Factor);
AtomicIncrementSCDTemp(iGlobalId.y, resUInt);
FfxUInt32 oldFinishedGroupCount = AtomicIncrementSCDOutput(SCD_OUTPUT_COMPLETED_WORKGROUPS_SLOT, 1);
if (oldFinishedGroupCount == WhereToStop)
{
FfxUInt32 res0 = LoadRwSCDTemp(0);
FfxUInt32 res1 = LoadRwSCDTemp(1);
FfxUInt32 res2 = LoadRwSCDTemp(2);
FfxFloat32 sceneChangeValue = ffxMin(res0, ffxMin(res1, res2)) / Factor;
FfxUInt32 history = LoadRwSCDOutput(SCD_OUTPUT_HISTORY_BITS_SLOT) << 1;
if (CrossedSceneChangeThreshold(sceneChangeValue))
{
history |= 1;
}
StoreSCDOutput(SCD_OUTPUT_SCENE_CHANGE_SLOT, ffxAsUInt32(sceneChangeValue));
StoreSCDOutput(SCD_OUTPUT_HISTORY_BITS_SLOT, history);
StoreSCDOutput(SCD_OUTPUT_COMPLETED_WORKGROUPS_SLOT, 0);
ResetSCDTemp();
}
}
if (iGlobalId.y == 1)
{
StoreSCDPreviousHistogram(iGlobalId.x, currentFilteredHistogramsValue);
StoreSCDHistogram(iGlobalId.x, 0);
}
}
#endif // FFX_OPTICALFLOW_COMPUTE_SCD_DIVERGENCE_H

View File

@@ -0,0 +1,58 @@
// 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_OPTICALFLOW_FILTER_OPTICAL_FLOW_V5_H
#define FFX_OPTICALFLOW_FILTER_OPTICAL_FLOW_V5_H
void FilterOpticalFlow(FfxInt32x2 iGlobalId, FfxInt32x2 iLocalId, FfxInt32x2 iGroupId, FfxInt32 iLocalIndex)
{
FfxInt32x2 tmpMV[9];
FfxInt32 idx = 0;
for (FfxInt32 xx = -1; xx < 2; xx++)
{
for (FfxInt32 yy = -1; yy < 2; yy++)
{
tmpMV[idx] = LoadPreviousOpticalFlow(iGlobalId + FfxInt32x2(xx, yy));
idx++;
}
}
FfxUInt32 ret = 0xFFFFFFFF;
for (FfxInt32 i = 0; i < 9; ++i)
{
FfxUInt32 tmp = 0;
for (FfxInt32 j = 0; j < 9; ++j)
{
FfxInt32x2 delta = tmpMV[i] - tmpMV[j];
tmp = delta.x * delta.x + (delta.y * delta.y + tmp);
}
ret = min(((tmp) << 4) | i, ret);
}
FfxUInt32 minIdx = ret & 0xF;
StoreOpticalFlow(iGlobalId, tmpMV[minIdx]);
}
#endif // FFX_OPTICALFLOW_FILTER_OPTICAL_FLOW_V5_H

View File

@@ -0,0 +1,92 @@
// 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_OPTICALFLOW_GENERATE_SCD_HISTOGRAM_H
#define FFX_OPTICALFLOW_GENERATE_SCD_HISTOGRAM_H
#define LBASE 10
FFX_GROUPSHARED FfxUInt32 scdBuffer[256 * LBASE];
void GenerateSceneChangeDetectionHistogram(FfxInt32x3 iGlobalId, FfxInt32x2 iLocalId, FfxInt32 iLocalIndex, FfxInt32x2 iGroupId, FfxInt32x2 iGroupSize)
{
FFX_STATIC const FfxUInt32 HistogramsPerDim = 3;
FfxUInt32 divX = DisplaySize().x / HistogramsPerDim;
FfxUInt32 divY = DisplaySize().y / HistogramsPerDim;
FfxUInt32 nx = iGlobalId.z % HistogramsPerDim;
FfxUInt32 ny = iGlobalId.z / HistogramsPerDim;
FfxUInt32 startX = divX * nx;
FfxUInt32 startY = divY * ny;
FfxUInt32 stopX = startX + divX;
FfxUInt32 stopY = startY + divY;
const FfxUInt32 bufferOffset = iLocalIndex * LBASE;
for (FfxInt32 i = 0; i < LBASE; i++)
{
scdBuffer[bufferOffset + i] = 0;
}
FFX_GROUP_MEMORY_BARRIER;
FfxInt32x2 coord = FfxInt32x2(startX + (4 * iGlobalId.x), startY + iGlobalId.y);
if (coord.x < stopX)
{
for (; coord.y < stopY; coord.y += 128)
{
FfxUInt32x4 color = FfxUInt32x4(
LoadOpticalFlowInput(coord + FfxInt32x2(0, 0)),
LoadOpticalFlowInput(coord + FfxInt32x2(1, 0)),
LoadOpticalFlowInput(coord + FfxInt32x2(2, 0)),
LoadOpticalFlowInput(coord + FfxInt32x2(3, 0))
);
color *= LBASE;
FfxUInt32 scramblingOffset = iLocalIndex % LBASE;
#if defined(FFX_HLSL)
InterlockedAdd(scdBuffer[color.x + scramblingOffset], 1);
InterlockedAdd(scdBuffer[color.y + scramblingOffset], 1);
InterlockedAdd(scdBuffer[color.z + scramblingOffset], 1);
InterlockedAdd(scdBuffer[color.w + scramblingOffset], 1);
#elif defined(FFX_GLSL)
atomicAdd(scdBuffer[color.x + scramblingOffset], 1);
atomicAdd(scdBuffer[color.y + scramblingOffset], 1);
atomicAdd(scdBuffer[color.z + scramblingOffset], 1);
atomicAdd(scdBuffer[color.w + scramblingOffset], 1);
#endif
}
}
FFX_GROUP_MEMORY_BARRIER;
FfxUInt32 value = 0;
for (FfxInt32 i = 0; i < LBASE; i++)
{
value += scdBuffer[bufferOffset + i];
}
FfxUInt32 histogramStart = (iGroupSize.x * iGroupSize.y) * iGlobalId.z;
AtomicIncrementSCDHistogram(FfxInt32(histogramStart + iLocalIndex), value);
}
#endif // FFX_OPTICALFLOW_GENERATE_SCD_HISTOGRAM_H

View File

@@ -0,0 +1,106 @@
// 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_OPTICALFLOW_PREPARE_LUMA_H
#define FFX_OPTICALFLOW_PREPARE_LUMA_H
FfxFloat32 LuminanceToPerceivedLuminance(FfxFloat32 fLuminance)
{
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;
}
FfxFloat32 LinearLdrToLuminance(FfxFloat32x3 linearRec709RGB)
{
FfxFloat32 fY = 0.2126 * linearRec709RGB.x + 0.7152 * linearRec709RGB.y + 0.0722 * linearRec709RGB.z;
return fY;
}
FfxFloat32 LinearRec2020ToLuminance(FfxFloat32x3 linearRec2020RGB)
{
FfxFloat32 fY = 0.2627 * linearRec2020RGB.x + 0.678 * linearRec2020RGB.y + 0.0593 * linearRec2020RGB.z;
return fY;
}
FfxFloat32 PQCorrectedHdrToLuminance(FfxFloat32x3 pq, FfxFloat32 maxLuminance)
{
FfxFloat32 fY = LinearRec2020ToLuminance(ffxLinearFromPQ(pq) * (10000.0f / maxLuminance));
return fY;
}
FfxFloat32x3 ffxscRGBToLinear(FfxFloat32x3 value, FfxFloat32 minLuminance, FfxFloat32 maxLuminance)
{
FfxFloat32x3 p = value - ffxBroadcast3(minLuminance / 80.0f);
return p / ffxBroadcast3((maxLuminance - minLuminance) / 80.0f);
}
FfxFloat32 SCRGBCorrectedHdrToLuminance(FfxFloat32x3 scRGB, FfxFloat32 minLuminance, FfxFloat32 maxLuminance)
{
FfxFloat32 fY = LinearLdrToLuminance(ffxscRGBToLinear(scRGB, minLuminance, maxLuminance));
return fY;
}
void PrepareLuma(FfxInt32x2 iGlobalId, FfxInt32 iLocalIndex)
{
#define PixelsPerThreadX 2
#define PixelsPerThreadY 2
#pragma unroll
for (FfxInt32 y = 0; y < PixelsPerThreadY; y++)
{
#pragma unroll
for (FfxInt32 x = 0; x < PixelsPerThreadX; x++)
{
FfxInt32x2 pos = iGlobalId * FfxInt32x2(PixelsPerThreadX, PixelsPerThreadY) + FfxInt32x2(x, y);
FfxInt32x2 iPxHrPos = pos;
FfxFloat32 fY = 0.0;
FfxFloat32x3 inputColor = LoadInputColor(iPxHrPos).rgb;
FfxUInt32 backbufferTransferFunction = BackbufferTransferFunction();
if (backbufferTransferFunction == 0)
{
fY = LinearLdrToLuminance(inputColor);
}
else if (backbufferTransferFunction == 1)
{
fY = PQCorrectedHdrToLuminance(inputColor, MinMaxLuminance()[1]);
fY = LuminanceToPerceivedLuminance(fY);
}
else if (backbufferTransferFunction == 2)
{
fY = SCRGBCorrectedHdrToLuminance(inputColor, MinMaxLuminance()[0], MinMaxLuminance()[1]);
fY = LuminanceToPerceivedLuminance(fY);
}
StoreOpticalFlowInput(pos, FfxUInt32(fY * 255));
}
}
}
#endif // FFX_OPTICALFLOW_PREPARE_LUMA_H

View File

@@ -0,0 +1,74 @@
// 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_OPTICALFLOW_RESOURCES_H
#define FFX_OPTICALFLOW_RESOURCES_H
#if defined(FFX_CPU) || defined(FFX_GPU)
#define FFX_OF_RESOURCE_IDENTIFIER_NULL 0
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_1 1
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_1_LEVEL_1 2
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_1_LEVEL_2 3
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_1_LEVEL_3 4
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_1_LEVEL_4 5
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_1_LEVEL_5 6
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_1_LEVEL_6 7
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_2 8
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_2_LEVEL_1 9
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_2_LEVEL_2 10
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_2_LEVEL_3 11
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_2_LEVEL_4 12
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_2_LEVEL_5 13
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_INPUT_2_LEVEL_6 14
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_1 15
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_1_LEVEL_1 16
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_1_LEVEL_2 17
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_1_LEVEL_3 18
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_1_LEVEL_4 19
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_1_LEVEL_5 20
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_1_LEVEL_6 21
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_2 22
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_2_LEVEL_1 23
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_2_LEVEL_2 24
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_2_LEVEL_3 25
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_2_LEVEL_4 26
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_2_LEVEL_5 27
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_2_LEVEL_6 28
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_HISTOGRAM 29
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_PREVIOUS_HISTOGRAM 30
#define FFX_OF_RESOURCE_IDENTIFIER_OPTICAL_FLOW_SCD_TEMP 31
#define FFX_OF_RESOURCE_IDENTIFIER_COUNT 32
#define FFX_OPTICALFLOW_CONSTANTBUFFER_IDENTIFIER 0
#define FFX_OPTICALFLOW_CONSTANTBUFFER_IDENTIFIER_SPD 1
#define FFX_OPTICALFLOW_CONSTANTBUFFER_COUNT 2
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
#endif //!defined( FFX_OPTICALFLOW_RESOURCES_H )

View File

@@ -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_OPTICALFLOW_SCALE_OPTICAL_FLOW_ADVANCED_V5_H
#define FFX_OPTICALFLOW_SCALE_OPTICAL_FLOW_ADVANCED_V5_H
#define WG_WIDTH FFX_OPTICALFLOW_THREAD_GROUP_WIDTH
#define WG_HEIGHT FFX_OPTICALFLOW_THREAD_GROUP_HEIGHT
#define WG_DEPTH FFX_OPTICALFLOW_THREAD_GROUP_DEPTH
FFX_GROUPSHARED FfxInt32x2 nearestVectors[4][WG_HEIGHT][WG_WIDTH];
FFX_GROUPSHARED FfxUInt32 localRegion[4][WG_HEIGHT][WG_WIDTH];
FFX_GROUPSHARED FfxUInt32 sads[4][WG_HEIGHT][WG_WIDTH];
void ScaleOpticalFlowAdvanced(FfxInt32x3 iGlobalId, FfxInt32x3 iLocalId)
{
if (IsSceneChanged())
{
StoreOpticalFlowNextLevel(iGlobalId.xy, FfxInt32x2(0, 0));
return;
}
int xOffset = (iLocalId.z % 2) - 1 + iGlobalId.x % 2;
int yOffset = (iLocalId.z / 2) - 1 + iGlobalId.y % 2;
FfxInt32x2 srcOFPos = FfxInt32x2(
(iGlobalId.x / 2) + xOffset,
(iGlobalId.y / 2) + yOffset
);
FfxInt32x2 nearestVector = LoadOpticalFlow(srcOFPos);
nearestVectors[iLocalId.z][iLocalId.y][iLocalId.x] = nearestVector * 2;
int maxY = 4;
for (int n = iLocalId.z; n < maxY; n += WG_DEPTH)
{
{
FfxInt32x2 lumaPos = FfxInt32x2((iGlobalId.x) * 4, iGlobalId.y * maxY + n);
FfxUInt32 firstPixel = LoadFirstImagePackedLuma(lumaPos);
localRegion[n][iLocalId.y][iLocalId.x] = firstPixel;
}
}
FFX_GROUP_MEMORY_BARRIER;
uint sad = 0;
for (int n = 0; n < maxY; n++)
{
{
FfxInt32x2 lumaPos = FfxInt32x2((iGlobalId.x) * 4, (iGlobalId.y * maxY + n)) + nearestVector;
FfxUInt32 secondPixel = LoadSecondImagePackedLuma(lumaPos);
sad += Sad(localRegion[n][iLocalId.y][iLocalId.x], secondPixel);
}
}
sads[iLocalId.z][iLocalId.y][iLocalId.x] = sad;
FFX_GROUP_MEMORY_BARRIER;
{
if (iLocalId.z == 0)
{
uint bestSad = 0xffffffff;
uint bestId = 0;
for (int n = 0; n < 4; n++)
{
if ((sads[n][iLocalId.y][iLocalId.x]) < bestSad)
{
bestSad = sads[n][iLocalId.y][iLocalId.x];
bestId = n;
}
}
FfxInt32x2 outputVector = nearestVectors[bestId][iLocalId.y][iLocalId.x];
StoreOpticalFlowNextLevel(iGlobalId.xy, outputVector);
}
}
}
#endif // FFX_OPTICALFLOW_SCALE_OPTICAL_FLOW_ADVANCED_V5_H