mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 09:19:18 +02:00
merge manul
This commit is contained in:
141
manul/thirdparty/fsr2/include/FidelityFX/gpu/CMakeCompileShaders.txt
vendored
Normal file
141
manul/thirdparty/fsr2/include/FidelityFX/gpu/CMakeCompileShaders.txt
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
# 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.
|
||||
|
||||
# Function to compile a set of shaders using the FidelityFX shader compiler driver.
|
||||
#
|
||||
# EXECUTABLE Path to the FidelityFX SC tool executable.
|
||||
# BASE_ARGS The base arguments for the compiler.
|
||||
# API_BASE_ARGS API (DX12 or Vulkan) specific base args.
|
||||
# PERMUTATION_ARGS Permutation set to compile for.
|
||||
# SHADER_FILES A list of shader files to compile using the permutation matrix expanded from SC_PERMUTATION_ARGS.
|
||||
# OUTPUT_PATH Path to store compiled shader output.
|
||||
#
|
||||
# Returns
|
||||
# A list of header files generated by the FidelityFX Shader Compiler driver.
|
||||
function(compile_shaders_with_depfile
|
||||
EXECUTABLE BASE_ARGS API_BASE_ARGS
|
||||
PERMUTATION_ARGS INCLUDES_ARGS
|
||||
SHADER_FILES OUTPUT_PATH
|
||||
PERMUTATION_OUTPUTS)
|
||||
|
||||
#message(STATUS "OUTPUT_PATH=${OUTPUT_PATH}")
|
||||
#message(STATUS "EXE=${EXECUTABLE}")
|
||||
#message(STATUS "BASE=${BASE_ARGS}")
|
||||
#message(STATUS "API=${API_BASE_ARGS}")
|
||||
#message(STATUS "PERMS=${PERMUTATION_ARGS}")
|
||||
#message(STATUS "INCLUDES=${INCLUDES_ARGS}")
|
||||
#message(STATUS "SHADER_FILES=${SHADER_FILES}")
|
||||
|
||||
# Figure out if this HLSL or GLSL
|
||||
list(GET SHADER_FILES 0 FIRST_SHADER_FILE)
|
||||
get_filename_component(SHADER_EXT "${FIRST_SHADER_FILE}" LAST_EXT)
|
||||
string(TOUPPER "${SHADER_EXT}" SHADER_EXT)
|
||||
set(INCLUDE_SPACE )
|
||||
set(HLSL_WAVE64_ARGS )
|
||||
set(HLSL_WAVE32_ARGS )
|
||||
set(HLSL_16BIT_ARGS )
|
||||
if (SHADER_EXT STREQUAL ".HLSL")
|
||||
set(INCLUDE_SPACE " ")
|
||||
set(HLSL_WAVE64_ARGS "-DFFX_PREFER_WAVE64=\"[WaveSize(64)]\"" "-DFFX_HLSL_SM=66" -T cs_6_6)
|
||||
set(HLSL_WAVE32_ARGS "-DFFX_HLSL_SM=62" -T cs_6_2)
|
||||
set(HLSL_16BIT_ARGS "-enable-16bit-types")
|
||||
endif()
|
||||
# GLSL requires no spaces: -I<include0> -I<include1> etc.
|
||||
# HLSL requires spaces: -I <include0> -I <include1> etc.
|
||||
set(COMPILE_INCLUDE_ARGS )
|
||||
foreach(INC ${INCLUDES_ARGS})
|
||||
list(APPEND COMPILE_INCLUDE_ARGS "-I${INCLUDE_SPACE}${INC}")
|
||||
endforeach(INC)
|
||||
|
||||
if (FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64)
|
||||
set(FFX_GDK_OPTION -compiler=gdk.desktop.x64)
|
||||
elseif (FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64)
|
||||
set(FFX_GDK_OPTION -compiler=gdk.scarlett.x64)
|
||||
else()
|
||||
set(FFX_GDK_OPTION )
|
||||
endif()
|
||||
|
||||
foreach(PASS_SHADER ${SHADER_FILES})
|
||||
get_filename_component(PASS_SHADER_FILENAME ${PASS_SHADER} NAME_WE)
|
||||
get_filename_component(PASS_SHADER_TARGET ${PASS_SHADER} NAME_WLE)
|
||||
|
||||
set(WAVE32_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_permutations.h)
|
||||
set(WAVE64_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_wave64_permutations.h)
|
||||
set(WAVE32_16BIT_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_16bit_permutations.h)
|
||||
set(WAVE64_16BIT_PERMUTATION_HEADER ${OUTPUT_PATH}/${PASS_SHADER_TARGET}_wave64_16bit_permutations.h)
|
||||
|
||||
# combine base and permutation args
|
||||
set(SC_ARGS ${BASE_ARGS} ${API_BASE_ARGS} ${PERMUTATION_ARGS})
|
||||
|
||||
# Wave32
|
||||
add_custom_command(
|
||||
OUTPUT ${WAVE32_PERMUTATION_HEADER}
|
||||
COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME} -DFFX_HALF=0 ${HLSL_WAVE32_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${PASS_SHADER}
|
||||
DEPFILE ${WAVE32_PERMUTATION_HEADER}.d
|
||||
)
|
||||
list(APPEND PERMUTATION_OUTPUTS ${WAVE32_PERMUTATION_HEADER})
|
||||
|
||||
# Wave64
|
||||
add_custom_command(
|
||||
OUTPUT ${WAVE64_PERMUTATION_HEADER}
|
||||
COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME}_wave64 -DFFX_HALF=0 ${HLSL_WAVE64_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${PASS_SHADER}
|
||||
DEPFILE ${WAVE64_PERMUTATION_HEADER}.d
|
||||
)
|
||||
list(APPEND PERMUTATION_OUTPUTS ${WAVE64_PERMUTATION_HEADER})
|
||||
|
||||
# Wave32 16-bit
|
||||
add_custom_command(
|
||||
OUTPUT ${WAVE32_16BIT_PERMUTATION_HEADER}
|
||||
COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME}_16bit -DFFX_HALF=1 ${HLSL_16BIT_ARGS} ${HLSL_WAVE32_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${PASS_SHADER}
|
||||
DEPFILE ${WAVE32_16BIT_PERMUTATION_HEADER}.d
|
||||
)
|
||||
list(APPEND PERMUTATION_OUTPUTS ${WAVE32_16BIT_PERMUTATION_HEADER})
|
||||
|
||||
# Wave64 16-bit
|
||||
add_custom_command(
|
||||
OUTPUT ${WAVE64_16BIT_PERMUTATION_HEADER}
|
||||
COMMAND ${EXECUTABLE} ${FFX_GDK_OPTION} ${SC_ARGS} -name=${PASS_SHADER_FILENAME}_wave64_16bit -DFFX_HALF=1 ${HLSL_16BIT_ARGS} ${HLSL_WAVE64_ARGS} ${COMPILE_INCLUDE_ARGS} -output=${OUTPUT_PATH} ${PASS_SHADER}
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
||||
DEPENDS ${PASS_SHADER}
|
||||
DEPFILE ${WAVE64_16BIT_PERMUTATION_HEADER}.d
|
||||
)
|
||||
list(APPEND PERMUTATION_OUTPUTS ${WAVE64_16BIT_PERMUTATION_HEADER})
|
||||
endforeach(PASS_SHADER)
|
||||
|
||||
set(${PERMUTATION_OUTPUTS} ${PERMUTATION_OUTPUTS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# macro to add shader output files to a list for dependencies
|
||||
macro (add_shader_output)
|
||||
foreach (_SHADER_SRC ${ARGN})
|
||||
#message (STATUS ${_SHADER_SRC})
|
||||
list (APPEND FFX_SC_PERMUTATION_OUTPUTS "${_SHADER_SRC}")
|
||||
endforeach()
|
||||
|
||||
set (FFX_SC_PERMUTATION_OUTPUTS ${FFX_SC_PERMUTATION_OUTPUTS} PARENT_SCOPE)
|
||||
endmacro()
|
||||
48
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/CMakeCompileBlurShaders.txt
vendored
Normal file
48
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/CMakeCompileBlurShaders.txt
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# 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(BLUR_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(BLUR_PERMUTATION_ARGS
|
||||
-DFFX_BLUR_OPTION_KERNEL_DIMENSION={3,5,7,9,11,13,15,17,19,21}
|
||||
-DFFX_BLUR_OPTION_KERNEL_PERMUTATION={0,1,2})
|
||||
|
||||
set(BLUR_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/blur")
|
||||
|
||||
if (NOT BLUR_SHADER_EXT)
|
||||
set(BLUR_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB BLUR_SHADERS
|
||||
"shaders/blur/ffx_blur_pass.${BLUR_SHADER_EXT}")
|
||||
|
||||
# compile all the shaders
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${BLUR_BASE_ARGS}" "${BLUR_API_BASE_ARGS}" "${BLUR_PERMUTATION_ARGS}" "${BLUR_INCLUDE_ARGS}"
|
||||
"${BLUR_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" BLUR_PERMUTATION_OUTPUTS)
|
||||
|
||||
# add the header files they generate to the main list of dependencies
|
||||
add_shader_output("${BLUR_PERMUTATION_OUTPUTS}")
|
||||
937
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur.h
vendored
Normal file
937
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur.h
vendored
Normal file
@@ -0,0 +1,937 @@
|
||||
// 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_BLUR_H
|
||||
#define FFX_BLUR_H
|
||||
//_____________________________________________________________/\_______________________________________________________________
|
||||
//==============================================================================================================================
|
||||
//
|
||||
// [FFX BLUR] Blur
|
||||
//
|
||||
//==============================================================================================================================
|
||||
//
|
||||
/// @defgroup FfxGPUBlur FidelityFX BLUR
|
||||
/// FidelityFX Blur GPU documentation
|
||||
///
|
||||
/// @ingroup FfxGPUEffects
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// ABOUT
|
||||
// =====
|
||||
// AMD FidelityFX Blur is a collection of blurring effects implemented on compute shaders, hand-optimized for maximum performance.
|
||||
// FFX-Blur includes
|
||||
// - Gaussian Blur w/ large kernel support (up to 21x21)
|
||||
//
|
||||
//==============================================================================================================================
|
||||
|
||||
//==============================================================================================================================
|
||||
// BLUR SETUP
|
||||
//==============================================================================================================================
|
||||
|
||||
|
||||
/// FFX_BLUR_TILE_SIZE_Y: Tile Y dimensions that the local threadgroup will work on.
|
||||
/// Note: each threadgroup is responsible for blurring a tile of the input image.
|
||||
///
|
||||
/// @ingroup FfxGPUBlur
|
||||
#ifndef FFX_BLUR_TILE_SIZE_Y
|
||||
#define FFX_BLUR_TILE_SIZE_Y 8
|
||||
#endif
|
||||
|
||||
/// FFX_BLUR_TILE_SIZE_X: Tile X dimensions that the local threadgroup will work on.
|
||||
/// Note: each threadgroup is responsible for blurring a tile of the input image.
|
||||
///
|
||||
/// @ingroup FfxGPUBlur
|
||||
#ifndef FFX_BLUR_TILE_SIZE_X
|
||||
#define FFX_BLUR_TILE_SIZE_X 8
|
||||
#endif
|
||||
|
||||
/// FFX_BLUR_DISPATCH_Y: Y dimension of the Blur compute dispatch.
|
||||
/// The compute dispatch on the CPU side uses this value when invoking Dispatch.
|
||||
///
|
||||
/// @ingroup FfxGPUBlur
|
||||
#define FFX_BLUR_DISPATCH_Y 8
|
||||
|
||||
#ifndef FFX_CPU
|
||||
|
||||
/// FFX_BLUR_OPTION_KERNEL_DIMENSION needs to be defined by the client application
|
||||
/// App should define e.g the following for 5x5 blur:
|
||||
/// #define FFX_BLUR_OPTION_KERNEL_DIMENSION 5
|
||||
///
|
||||
/// @ingroup FfxGPUBlur
|
||||
#ifndef FFX_BLUR_OPTION_KERNEL_DIMENSION
|
||||
#error Please define FFX_BLUR_OPTION_KERNEL_DIMENSION
|
||||
#endif
|
||||
|
||||
/// FFX_BLUR_KERNEL_RANGE is defined relative to FFX_BLUR_OPTION_KERNEL_DIMENSION
|
||||
/// See ffx_blur_callbacks_*.h for details.
|
||||
///
|
||||
/// @ingroup FfxGPUBlur
|
||||
#ifndef FFX_BLUR_KERNEL_RANGE
|
||||
#error Please define FFX_BLUR_KERNEL_RANGE
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// BLUR CONFIG
|
||||
//--------------------------------------------------------------------------------------
|
||||
// hardcoded variants
|
||||
#define BLUR_DEBUG_PREFILL_OUTPUT_CACHE_WITH_COLOR 0
|
||||
#define BLUR_GROUPSHARED_MEMORY_SOA 0 // [Deprecated] improves LDS but too high traffic still
|
||||
#define BLUR_GROUPSHARED_MEMORY_HALF 0 // [Deprecated] LOTS of LDS traffic (1x ds_read per channel), need to pack with FfxUInt32
|
||||
#define BLUR_GROUPSHARED_MEMORY_PK_UINT 1 // 1x ds_read2st64_b32 for all three channels
|
||||
#define BLUR_FP16_KERNEL_LOOPS 1 // use fp16 for kernel loop counters and lds indexing (increases VGPR due to sdwa)
|
||||
#define BLUR_FP16_CLAMP 1 // ensure fp16 min/max is used for clamp()
|
||||
// cpu-driven variants
|
||||
#ifndef BLUR_ENABLE_INPUT_CACHE
|
||||
#define BLUR_ENABLE_INPUT_CACHE 0 // currently only slows the algorithm :(
|
||||
#endif
|
||||
#ifndef BLUR_DISABLE_CLAMP
|
||||
#define BLUR_DISABLE_CLAMP 0 // Generates incorrect image at the image borders (no clamp), for testing theoretical speed
|
||||
#endif
|
||||
#ifndef BLUR_OPTIMIZED_CLAMP
|
||||
#define BLUR_OPTIMIZED_CLAMP 0 // [Experimental] Testing a new optimized clamp ISA
|
||||
#endif
|
||||
|
||||
// constants
|
||||
#define BLUR_TILE_SIZE_Y_INV (1.0 / FFX_BLUR_TILE_SIZE_Y)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// GROUPSHARED MEMORY
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Define CacheTypes<FP16, SOA>
|
||||
#if BLUR_GROUPSHARED_MEMORY_SOA
|
||||
#if BLUR_GROUPSHARED_MEMORY_HALF
|
||||
#ifdef FFX_HLSL
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat16
|
||||
#else
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat16
|
||||
#endif
|
||||
#else
|
||||
#ifdef FFX_HLSL
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat32
|
||||
#else
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat32
|
||||
#endif
|
||||
#endif
|
||||
#else // BLUR_GROUPSHARED_MEMORY_SOA
|
||||
#if BLUR_GROUPSHARED_MEMORY_HALF
|
||||
#ifdef FFX_HLSL
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat16x3
|
||||
#else
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat16x3
|
||||
#endif
|
||||
#else
|
||||
#ifdef FFX_HLSL
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE groupshared FfxFloat32x3
|
||||
#else
|
||||
#define BLUR_GROUPSHARED_MEMORY_TYPE shared FfxFloat32x3
|
||||
#endif
|
||||
#endif
|
||||
#endif // BLUR_GROUPSHARED_MEMORY_SOA
|
||||
|
||||
//==============================================================================================================================
|
||||
// MATH HELPERS
|
||||
//==============================================================================================================================
|
||||
#define DIV_AND_ROUND_UP(x, y) (((x) + ((y)-1)) / ((y)))
|
||||
// Fast modulo operator for powers of two values for Y: x % y == x & (y-1)
|
||||
#define FAST_MOD(x, y) ((x) & (y - 1))
|
||||
#if FFX_HALF
|
||||
#define FAST_MOD16(x, y) ((x) & (y - FfxInt16(1)))
|
||||
#endif
|
||||
|
||||
// OUTPUT CACHE ########################################
|
||||
/*
|
||||
# Notes from Jordan's Presentation
|
||||
src: https://gpuopen.com/gdc-presentations/2019/gdc-2019-s5-blend-of-gcn-optimization-and-color-processing.pdf
|
||||
Use 2^n tiles to use bitwise AND in place of the more ALU-expensive % operator, see #define FAST_MOD above
|
||||
MinTiles -> Ceil(HalfKernel / TileSize) * 2 + 1
|
||||
*/
|
||||
#if FFX_BLUR_OPTION_KERNEL_DIMENSION > 7
|
||||
#define NUM_TILES_OUTPUT_CACHE 8
|
||||
#else
|
||||
#define NUM_TILES_OUTPUT_CACHE 4
|
||||
#endif
|
||||
|
||||
#define NUM_PIXELS_OUTPUT_CACHE (FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_TILE_SIZE_X * NUM_TILES_OUTPUT_CACHE)
|
||||
|
||||
|
||||
#if BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
#ifdef FFX_HLSL
|
||||
groupshared FfxUInt32 OutputCacheRG[NUM_PIXELS_OUTPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
|
||||
groupshared FfxFloat32 OutputCacheB [NUM_PIXELS_OUTPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
|
||||
#else
|
||||
shared FfxUInt32 OutputCacheRG[NUM_PIXELS_OUTPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
|
||||
shared FfxFloat32 OutputCacheB [NUM_PIXELS_OUTPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
|
||||
#endif
|
||||
#else
|
||||
#if BLUR_GROUPSHARED_MEMORY_SOA
|
||||
BLUR_GROUPSHARED_MEMORY_TYPE OutputCache[NUM_PIXELS_OUTPUT_CACHE * 3]; // stores rrrrrr...ggggggg...bbbbb...
|
||||
#else
|
||||
BLUR_GROUPSHARED_MEMORY_TYPE OutputCache[NUM_PIXELS_OUTPUT_CACHE]; // stores rgbrgbrgbrgbrgbrgbrgbrgb...
|
||||
#endif // BLUR_GROUPSHARED_MEMORY_SOA
|
||||
#endif // BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
|
||||
// Based on the FFX_BLUR_OPTION_KERNEL_DIMENSION, we will need to pre-fill a number of tiles.
|
||||
// e.g. TILE_SIZE_Y=8
|
||||
// -----------------------------------------
|
||||
// kernel = 3 | NUM_PREFILL_TILES_OUTPUT_CACHE = 1 |
|
||||
// kernel = 5 | NUM_PREFILL_TILES_OUTPUT_CACHE = 1 |
|
||||
// kernel = 7 | NUM_PREFILL_TILES_OUTPUT_CACHE = 1 |
|
||||
// kernel = 9* | NUM_PREFILL_TILES_OUTPUT_CACHE = 2*|
|
||||
// kernel = 11 | NUM_PREFILL_TILES_OUTPUT_CACHE = 2 |
|
||||
// kernel = 13 | NUM_PREFILL_TILES_OUTPUT_CACHE = 2 |
|
||||
// kernel = 15 | NUM_PREFILL_TILES_OUTPUT_CACHE = 2 |
|
||||
// kernel = 17*| NUM_PREFILL_TILES_OUTPUT_CACHE = 3*|
|
||||
// kernel = 19 | NUM_PREFILL_TILES_OUTPUT_CACHE = 3 |
|
||||
// kernel = 21 | NUM_PREFILL_TILES_OUTPUT_CACHE = 3 |
|
||||
// kernel = 23 | NUM_PREFILL_TILES_OUTPUT_CACHE = 3 |
|
||||
// -----------------------------------------
|
||||
#define NUM_PREFILL_TILES_OUTPUT_CACHE DIV_AND_ROUND_UP(FFX_BLUR_OPTION_KERNEL_DIMENSION, FFX_BLUR_TILE_SIZE_Y)
|
||||
|
||||
|
||||
// INPUT CACHE ########################################
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
#define INPUT_CACHE_TILE_SIZE_X (FFX_BLUR_TILE_SIZE_X + FFX_BLUR_OPTION_KERNEL_DIMENSION - 1)
|
||||
#define NUM_TILES_INPUT_CACHE 1
|
||||
#define NUM_PIXELS_INPUT_CACHE ((INPUT_CACHE_TILE_SIZE_X * FFX_BLUR_TILE_SIZE_Y) * NUM_TILES_INPUT_CACHE)
|
||||
|
||||
#if BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
#ifdef FFX_HLSL
|
||||
groupshared FfxUInt32 InputCacheRG[NUM_PIXELS_INPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
|
||||
groupshared FfxFloat32 InputCacheB [NUM_PIXELS_INPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
|
||||
#else
|
||||
shared FfxUInt32 InputCacheRG[NUM_PIXELS_INPUT_CACHE]; // RG: 2x fp16's are packed into 32bit unsigned int
|
||||
shared FfxFloat32 InputCacheB [NUM_PIXELS_INPUT_CACHE]; // B : don't use fp16 for B to avoid bank conflicts
|
||||
#endif
|
||||
#else
|
||||
#if BLUR_GROUPSHARED_MEMORY_SOA
|
||||
BLUR_GROUPSHARED_MEMORY_TYPE InputCache[NUM_PIXELS_INPUT_CACHE * 3]; // stores rrrrrr...ggggggg...bbbbb...
|
||||
#else
|
||||
BLUR_GROUPSHARED_MEMORY_TYPE InputCache[NUM_PIXELS_INPUT_CACHE]; // stores rgbrgbrgbrgbrgbrgbrgbrgb...
|
||||
#endif // BLUR_GROUPSHARED_MEMORY_SOA
|
||||
#endif //BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//==============================================================================================================================
|
||||
// GROUPSHARED MEMORY MAPPING FUNCTIONS
|
||||
//==============================================================================================================================
|
||||
// LDS ops ----------------------------------------------------------------------------------
|
||||
// LDS TILES : FFX_BLUR_TILE_SIZE_X * FFX_BLUR_TILE_SIZE_Y sized tiles
|
||||
// e.g. FFX_BLUR_TILE_SIZE_X = 8
|
||||
//
|
||||
// <------------ FFX_BLUR_TILE_SIZE_X -------------->
|
||||
// ^ OutputCache[0-7]
|
||||
// | OutputCache[8-15]
|
||||
// |
|
||||
// | // TILE #1
|
||||
// |
|
||||
// |
|
||||
// v OutputCache[56-63]
|
||||
// <------------------------------------------------>
|
||||
// |
|
||||
// <------------ FFX_BLUR_TILE_SIZE_X -------------->
|
||||
// ^ OutputCache[64-71]
|
||||
// |
|
||||
// |
|
||||
// | // TILE #2
|
||||
// |
|
||||
// |
|
||||
// v
|
||||
// <------------------------------------------------>
|
||||
// |
|
||||
//...
|
||||
FfxUInt32 PackF2(FfxFloat32x2 c) { return (ffxF32ToF16(c.r) << 16) | ffxF32ToF16(c.g); }
|
||||
FfxFloat32x2 UnpackToF2(FfxUInt32 packedRG)
|
||||
{
|
||||
#ifdef FFX_HLSL
|
||||
return f16tof32(FfxUInt32x2(packedRG >> 16, packedRG & 0xFFFF));
|
||||
#else
|
||||
return unpackHalf2x16(packedRG).yx;
|
||||
#endif
|
||||
}
|
||||
#if FFX_HALF
|
||||
FfxUInt32 PackH2(FfxFloat16x2 c) { return (ffxF32ToF16(FfxFloat32(c.r)) << 16) | ffxF32ToF16(FfxFloat32(c.g)); } // TODO: is there a cast fp16->FfxUInt32 and skip fp16->fp32 promotion?
|
||||
FfxFloat16x2 UnpackToH2(FfxUInt32 packedRG){ return FfxFloat16x2(UnpackToF2(packedRG)); }
|
||||
#endif
|
||||
|
||||
#ifdef FFX_HLSL
|
||||
inline FfxUInt32 FlattenIndex(FfxInt32x2 Index, FfxInt32 ElementStride)
|
||||
#else
|
||||
FfxUInt32 FlattenIndex(FfxInt32x2 Index, FfxInt32 ElementStride)
|
||||
#endif
|
||||
{
|
||||
return Index.x + Index.y * ElementStride;
|
||||
}
|
||||
|
||||
#if BLUR_GROUPSHARED_MEMORY_SOA
|
||||
void SetOutputCache(FfxInt32x2 index, FfxFloat32x3 value)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * BLUR_TILE_SIZE_X;
|
||||
OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 0] = value.r;
|
||||
OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 1] = value.g;
|
||||
OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 2] = value.b;
|
||||
}
|
||||
FfxFloat32x3 GetOutputCache(FfxInt32x2 index)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
|
||||
FfxFloat32x3 c;
|
||||
c.r = OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 0];
|
||||
c.g = OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 1];
|
||||
c.b = OutputCache[iLDS + NUM_PIXELS_OUTPUT_CACHE * 2];
|
||||
return c;
|
||||
}
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
void SetInputCache(FfxInt32x2 index, FfxFloat32x3 value)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
|
||||
InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 0] = value.r;
|
||||
InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 1] = value.g;
|
||||
InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 2] = value.b;
|
||||
}
|
||||
FfxFloat32x3 GetInputCache(FfxInt32x2 index)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
|
||||
FfxFloat32x3 c;
|
||||
c.r = InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 0];
|
||||
c.g = InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 1];
|
||||
c.b = InputCache[iLDS + NUM_PIXELS_INPUT_CACHE * 2];
|
||||
return c;
|
||||
}
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
#else
|
||||
#if BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
#if FFX_HALF
|
||||
void SetOutputCache(FfxInt32x2 index, FfxFloat16x3 value)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
|
||||
OutputCacheRG[iLDS] = PackH2(value.rg);
|
||||
OutputCacheB[iLDS] = value.b;
|
||||
}
|
||||
FfxFloat16x3 GetOutputCache(FfxInt32x2 index)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
|
||||
FfxFloat16x2 RG = UnpackToH2(OutputCacheRG[iLDS]);
|
||||
return FfxFloat16x3(RG.r, RG.g, OutputCacheB[iLDS]);
|
||||
}
|
||||
#else
|
||||
void SetOutputCache(FfxInt32x2 index, FfxFloat32x3 value)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
|
||||
OutputCacheRG[iLDS] = PackF2(value.rg);
|
||||
OutputCacheB[iLDS] = value.b;
|
||||
}
|
||||
FfxFloat32x3 GetOutputCache(FfxInt32x2 index)
|
||||
{
|
||||
FfxInt32 iLDS = index.x + index.y * FFX_BLUR_TILE_SIZE_X;
|
||||
FfxFloat32x2 RG = UnpackToF2(OutputCacheRG[iLDS]);
|
||||
return FfxFloat32x3(RG.r, RG.g, OutputCacheB[iLDS]);
|
||||
}
|
||||
#endif // FFX_HALF
|
||||
#else
|
||||
#if FFX_HALF
|
||||
void SetOutputCache(FfxInt32x2 index, FfxFloat16x3 value)
|
||||
{
|
||||
const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
|
||||
OutputCache[iLDS] = value;
|
||||
}
|
||||
FfxFloat16x3 GetOutputCache(FfxInt32x2 index)
|
||||
{
|
||||
const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
|
||||
return OutputCache[iLDS];
|
||||
}
|
||||
#else
|
||||
void SetOutputCache(FfxInt32x2 index, FfxFloat32x3 value)
|
||||
{
|
||||
const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
|
||||
OutputCache[iLDS] = value;
|
||||
}
|
||||
FfxFloat32x3 GetOutputCache(FfxInt32x2 index)
|
||||
{
|
||||
const FfxUInt32 iLDS = FlattenIndex(index, FFX_BLUR_TILE_SIZE_X);
|
||||
return OutputCache[iLDS];
|
||||
}
|
||||
#endif // FFX_HALF
|
||||
#endif // BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
|
||||
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
#if BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
#if FFX_HALF
|
||||
void SetInputCache(FfxInt32x2 index, FfxFloat16x3 value)
|
||||
{
|
||||
FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
|
||||
InputCacheRG[iLDS] = PackH2(value.rg);
|
||||
InputCacheB[iLDS] = value.b;
|
||||
}
|
||||
FfxFloat16x3 GetInputCache(FfxInt32x2 index)
|
||||
{
|
||||
FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
|
||||
FfxFloat16x2 RG = UnpackToH2(InputCacheRG[iLDS]);
|
||||
return FfxFloat16x3(RG.r, RG.g, InputCacheB[iLDS]);
|
||||
}
|
||||
#else
|
||||
void SetInputCache(FfxInt32x2 index, FfxFloat32x3 value)
|
||||
{
|
||||
//FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
|
||||
FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
|
||||
InputCacheRG[iLDS] = PackF2(value.rg);
|
||||
InputCacheB[iLDS] = value.b;
|
||||
}
|
||||
FfxFloat32x3 GetInputCache(FfxInt32x2 index)
|
||||
{
|
||||
//FfxInt32 iLDS = FlattenIndex(index, INPUT_CACHE_TILE_SIZE_X);
|
||||
FfxInt32 iLDS = index.x + index.y * INPUT_CACHE_TILE_SIZE_X;
|
||||
|
||||
FfxFloat32x2 RG = UnpackToF2(InputCacheRG[iLDS]);
|
||||
return FfxFloat32x3(RG.r, RG.g, InputCacheB[iLDS]);
|
||||
}
|
||||
#endif // FFX_HALF
|
||||
#else
|
||||
void SetInputCache(FfxInt32x2 index, FfxFloat32x3 value) { InputCache[index.x + index.y * INPUT_CACHE_TILE_SIZE_X].rgb = value; }
|
||||
FfxFloat32x3 GetInputCache(FfxInt32x2 index) { return InputCache[index.x + index.y * INPUT_CACHE_TILE_SIZE_X].rgb; }
|
||||
#endif // BLUR_GROUPSHARED_MEMORY_PK_UINT
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
|
||||
#endif // BLUR_GROUPSHARED_MEMORY_SOA
|
||||
|
||||
|
||||
void LDSBarrier()
|
||||
{
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
}
|
||||
|
||||
// index of the LDS tile in the ring buffer
|
||||
#if FFX_HALF
|
||||
#if BLUR_FP16_KERNEL_LOOPS
|
||||
FfxInt16 GetOutputCacheTile(FfxInt16 iTile) { return FAST_MOD16(iTile, FfxInt16(NUM_TILES_OUTPUT_CACHE)); }
|
||||
void CacheInOutputTile(FfxInt32x2 threadID, FfxInt16 iTile, FfxFloat16x3 color)
|
||||
{
|
||||
FfxInt16 iLDSTile = GetOutputCacheTile(iTile);
|
||||
FfxInt16x2 TileOffset = FfxInt16x2(0, FfxInt16(FFX_BLUR_TILE_SIZE_Y) * iLDSTile);
|
||||
FfxInt16x2 iLDS = FfxInt16x2(threadID) + TileOffset;
|
||||
SetOutputCache(iLDS, color);
|
||||
}
|
||||
FfxFloat16x3 LoadFromCachedOutputTile(FfxInt32x2 threadID, FfxInt16 iTile)
|
||||
{
|
||||
FfxInt16 iLDSTile = GetOutputCacheTile(iTile);
|
||||
FfxInt16x2 TileOffset = FfxInt16x2(0, FfxInt16(FFX_BLUR_TILE_SIZE_Y) * iLDSTile);
|
||||
FfxInt16x2 iLDS = FfxInt16x2(threadID) + TileOffset;
|
||||
return GetOutputCache(iLDS);
|
||||
}
|
||||
#else // BLUR_FP16_KERNEL_LOOPS
|
||||
FfxInt32 GetOutputCacheTile(FfxInt32 iTile) { return FAST_MOD(iTile, NUM_TILES_OUTPUT_CACHE); }
|
||||
void CacheInOutputTile(FfxInt32x2 threadID, FfxInt32 iTile, FfxFloat16x3 color)
|
||||
{
|
||||
FfxInt32 iLDSTile = GetOutputCacheTile(iTile);
|
||||
FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile);
|
||||
FfxInt32x2 iLDS = threadID + TileOffset;
|
||||
SetOutputCache(iLDS, color);
|
||||
}
|
||||
FfxFloat32x3 LoadFromCachedOutputTile(FfxInt32x2 threadID, FfxInt32 iTile)
|
||||
{
|
||||
FfxInt32 iLDSTile = GetOutputCacheTile(iTile);
|
||||
FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile);
|
||||
FfxInt32x2 iLDS = threadID + TileOffset;
|
||||
return GetOutputCache(iLDS);
|
||||
}
|
||||
#endif // BLUR_FP16_KERNEL_LOOPS
|
||||
|
||||
#else
|
||||
FfxInt32 GetOutputCacheTile(FfxInt32 iTile) { return FAST_MOD(iTile, NUM_TILES_OUTPUT_CACHE); }
|
||||
void CacheInOutputTile(FfxInt32x2 threadID, FfxInt32 iTile, FfxFloat32x3 color)
|
||||
{
|
||||
FfxInt32 iLDSTile = GetOutputCacheTile(iTile); // map image tile to LDS ring buffered tiles
|
||||
FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile); // pixel offset for this tile
|
||||
FfxInt32x2 iLDS = threadID + TileOffset; // 2D LDS coord based on local thread ID
|
||||
SetOutputCache(iLDS, color);
|
||||
}
|
||||
FfxFloat32x3 LoadFromCachedOutputTile(FfxInt32x2 threadID, FfxInt32 iTile)
|
||||
{
|
||||
FfxInt32 iLDSTile = GetOutputCacheTile(iTile); // map image tile to LDS ring buffered tiles
|
||||
FfxInt32x2 TileOffset = FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iLDSTile); // pixel offset for this tile
|
||||
FfxInt32x2 iLDS = threadID + TileOffset; // 2D LDS coord based on local thread ID
|
||||
return GetOutputCache(iLDS);
|
||||
}
|
||||
#endif // FFX_HALF
|
||||
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
#if FFX_HALF
|
||||
void CacheInInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset, FfxFloat16x3 c)
|
||||
#else
|
||||
void CacheInInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset, FfxFloat32x3 c)
|
||||
#endif
|
||||
{
|
||||
FfxInt32x2 InputCacheCoord = threadID + FfxInt32x2(KernelOffset, 0) + FfxInt32x2(FFX_BLUR_KERNEL_RANGE-1, 0);
|
||||
SetInputCache(InputCacheCoord, c);
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 LoadFromCachedInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset)
|
||||
#else
|
||||
FfxFloat32x3 LoadFromCachedInputTile(FfxInt32x2 threadID, FfxInt32 KernelOffset)
|
||||
#endif
|
||||
{
|
||||
FfxInt32x2 InputCacheCoord = threadID + FfxInt32x2(KernelOffset,0) + FfxInt32x2(FFX_BLUR_KERNEL_RANGE-1, 0);
|
||||
return GetInputCache(InputCacheCoord);
|
||||
}
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//==============================================================================================================================
|
||||
// BLUR FUNCTIONS
|
||||
//==============================================================================================================================
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 HorizontalBlurFromTexture(FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
|
||||
{
|
||||
#if BLUR_FP16_CLAMP // this uses 4 less VGPRs but not faster
|
||||
const FfxInt16 ImageSizeClampValueX = FfxInt16(ImageSize.x - 1);
|
||||
FfxFloat16x3 BlurredImage = BlurLoadInput(FfxInt16x2(CenterPixelLocation)) * BlurLoadKernelWeight(0);
|
||||
for (FfxInt32 i = 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
|
||||
{
|
||||
FfxInt32x2 Offset = FfxInt32x2(i, 0);
|
||||
FfxInt16x2 SampleCoordXX = FfxInt16x2(CenterPixelLocation.x + i, CenterPixelLocation.x - i);
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
SampleCoordXX = clamp(SampleCoordXX, FfxInt16x2(0, 0), FfxInt16x2(ImageSizeClampValueX, ImageSizeClampValueX));
|
||||
#endif
|
||||
BlurredImage += BlurLoadInput(FfxInt16x2(SampleCoordXX[0], CenterPixelLocation.y)) * BlurLoadKernelWeight(i);
|
||||
BlurredImage += BlurLoadInput(FfxInt16x2(SampleCoordXX[1], CenterPixelLocation.y)) * BlurLoadKernelWeight(i);
|
||||
}
|
||||
#else
|
||||
FfxFloat16x3 BlurredImage = FfxFloat16x3(0.f, 0.f, 0.f);
|
||||
for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
|
||||
{
|
||||
FfxInt32x2 SampleCoord = CenterPixelLocation + FfxInt32x2(i, 0); // horizontal blur
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
SampleCoord.x = clamp(SampleCoord.x, 0, ImageSize.x-1); // clamp
|
||||
#endif
|
||||
FfxFloat16x3 c = BlurLoadInput(SampleCoord);
|
||||
BlurredImage += c * BlurLoadKernelWeight(abs(i));
|
||||
}
|
||||
#endif // BLUR_FP16_CLAMP
|
||||
return BlurredImage;
|
||||
}
|
||||
#else // FFX_HALF
|
||||
FfxFloat32x3 HorizontalBlurFromTexture(FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
|
||||
{
|
||||
FfxFloat32x3 BlurredImage = FfxFloat32x3(0.f, 0.f, 0.f);
|
||||
for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
|
||||
{
|
||||
FfxInt32x2 SampleCoord = CenterPixelLocation + FfxInt32x2(i, 0); // horizontal blur
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
SampleCoord.x = clamp(SampleCoord.x, 0, ImageSize.x-1); // clamp
|
||||
#endif
|
||||
FfxFloat32x3 c = BlurLoadInput(SampleCoord);
|
||||
BlurredImage += c * BlurLoadKernelWeight(abs(i));
|
||||
}
|
||||
return BlurredImage;
|
||||
}
|
||||
#endif // FFX_HALF
|
||||
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 HorizontalBlurFromCachedInput(FfxInt32x2 threadID)
|
||||
#else
|
||||
FfxFloat32x3 HorizontalBlurFromCachedInput(FfxInt32x2 threadID)
|
||||
#endif
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 BlurredImage = FfxFloat16x3(0.f, 0.f, 0.f);
|
||||
#else
|
||||
FfxFloat32x3 BlurredImage = FfxFloat32x3(0.f, 0.f, 0.f);
|
||||
#endif // FFX_HALF
|
||||
|
||||
for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
|
||||
{
|
||||
BlurredImage += LoadFromCachedInputTile(threadID, i) * BlurLoadKernelWeight(abs(i));
|
||||
}
|
||||
return BlurredImage;
|
||||
}
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
|
||||
#if FFX_HALF
|
||||
#if BLUR_FP16_KERNEL_LOOPS
|
||||
FfxFloat16x3 VerticalBlurFromCachedOutput(FfxInt32x2 ThreadID, FfxInt32x2 WorkGroupID,FfxInt16x2 CenterPixelLocation, FfxInt16x2 ImageSize)
|
||||
{
|
||||
const FfxInt16x2 ImageSizeClampValueXY = ImageSize.xy - FfxInt16x2(1, 1);
|
||||
const FfxUInt32 iTileCount = DIV_AND_ROUND_UP(FfxUInt32(ImageSize.y), FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
|
||||
FfxFloat16x3 value = FfxFloat16x3(0, 0, 0);
|
||||
#ifndef FFX_HLSL
|
||||
// For some reason using 16 bit integer for this loop in glsl does not work. It seems to be due to the use of
|
||||
// a negative value as a starting value that is compared to a positive value, which seems to incorrectly cause
|
||||
// the condition to always be false.
|
||||
for (FfxInt32 i = (FfxInt32(-FFX_BLUR_KERNEL_RANGE) + FfxInt32(1)); i < FfxInt32(FFX_BLUR_KERNEL_RANGE); ++i)
|
||||
#else
|
||||
for (FfxInt16 i = (FfxInt16(-FFX_BLUR_KERNEL_RANGE) + FfxInt16(1)); i < FfxInt16(FFX_BLUR_KERNEL_RANGE); ++i)
|
||||
#endif
|
||||
{
|
||||
FfxInt16x2 KernelSampleLocation = CenterPixelLocation + FfxInt16x2(0, i);
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, FfxInt16x2(0, 0), ImageSizeClampValueXY);
|
||||
#endif
|
||||
|
||||
const FfxInt16 iTile_ImageSpace = FfxInt16(KernelSampleLocation.y * BLUR_TILE_SIZE_Y_INV);
|
||||
const FfxInt16 iTile = FfxInt16(iTile_ImageSpace - iTileCount * WorkGroupID.y);
|
||||
FfxInt16x2 TileThreadID = FfxInt16x2(ThreadID.x, FAST_MOD16(KernelSampleLocation.y, FfxInt16(FFX_BLUR_TILE_SIZE_Y)));
|
||||
|
||||
FfxFloat16x3 c = LoadFromCachedOutputTile(TileThreadID, iTile);
|
||||
value += c * BlurLoadKernelWeight(abs(i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
#else
|
||||
FfxFloat16x3 VerticalBlurFromCachedOutput(FfxInt32x2 ThreadID, FfxInt32x2 WorkGroupID, FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
|
||||
{
|
||||
const FfxUInt32 iTileCount = DIV_AND_ROUND_UP(ImageSize.y, FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
|
||||
FfxFloat16x3 value = FfxFloat16x3(0, 0, 0);
|
||||
#if BLUR_FP16_CLAMP
|
||||
const FfxInt16x2 ClampUpperLimitXY = ImageSize.xy - 1;
|
||||
for (FfxInt16 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
|
||||
{
|
||||
FfxInt16x2 KernelSampleLocation = CenterPixelLocation + FfxInt16x2(0, i);
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
#if BLUR_OPTIMIZED_CLAMP
|
||||
bool bNegative = firstbithigh(KernelSampleLocation.x) == 31;
|
||||
KernelSampleLocation.y = bNegative ? 0 : KernelSampleLocation.y;
|
||||
#else
|
||||
KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, FfxInt16x2(0, 0), ClampUpperLimitXY);
|
||||
#endif // BLUR_OPTIMIZED_CLAMP
|
||||
#endif
|
||||
const FfxInt16 iTile_ImageSpace = FfxInt16(KernelSampleLocation.y * FFX_BLUR_TILE_SIZE_Y_INV);
|
||||
const FfxInt16 iTile = iTile_ImageSpace - iTileCount * WorkGroupID.y;
|
||||
FfxInt16x2 TileThreadID = FfxInt16x2(ThreadID.x, FAST_MOD16(KernelSampleLocation.y, FfxInt16(FFX_BLUR_TILE_SIZE_Y)));
|
||||
|
||||
FfxFloat16x3 c = LoadFromCachedOutputTile(TileThreadID, iTile);
|
||||
value += c * BlurLoadKernelWeight(abs(i));
|
||||
}
|
||||
#else
|
||||
for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
|
||||
{
|
||||
FfxInt32x2 KernelSampleLocation = CenterPixelLocation + FfxInt32x2(0, i);
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
#if BLUR_OPTIMIZED_CLAMP
|
||||
bool bNegative = firstbithigh(KernelSampleLocation.x) == 31;
|
||||
KernelSampleLocation.y = bNegative ? 0 : KernelSampleLocation.y;
|
||||
#else
|
||||
KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, 0, ImageSize.xy-1);
|
||||
#endif // BLUR_OPTIMIZED_CLAMP
|
||||
#endif
|
||||
|
||||
const FfxInt32 iTile_ImageSpace = FfxInt32(KernelSampleLocation.y * FFX_BLUR_TILE_SIZE_Y_INV);
|
||||
const FfxInt32 iTile = iTile_ImageSpace - (iTileCountPerWorkgroup * WorkGroupID.y);
|
||||
|
||||
FfxInt32x2 TileThreadID = FfxInt32x2(ThreadID.x, FAST_MOD(KernelSampleLocation.y, FFX_BLUR_TILE_SIZE_Y));
|
||||
|
||||
FfxFloat16x3 c = LoadFromCachedOutputTile(TileThreadID, iTile);
|
||||
value += c * BlurLoadKernelWeight(abs(i));
|
||||
}
|
||||
#endif // BLUR_FP16_CLAMP
|
||||
return value;
|
||||
}
|
||||
#endif // BLUR_FP16_KERNEL_LOOPS
|
||||
#else // FFX_HALF
|
||||
FfxFloat32x3 VerticalBlurFromCachedOutput(FfxInt32x2 ThreadID, FfxInt32x2 WorkGroupID,FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
|
||||
{
|
||||
const FfxInt32 iTileCountPerWorkgroup = DIV_AND_ROUND_UP(ImageSize.y, FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
|
||||
|
||||
FfxFloat32x3 value = FfxFloat32x3(0,0,0);
|
||||
for (FfxInt32 i = -FFX_BLUR_KERNEL_RANGE + 1; i < FFX_BLUR_KERNEL_RANGE; ++i)
|
||||
{
|
||||
FfxInt32x2 KernelSampleLocation = CenterPixelLocation + FfxInt32x2(0, i);
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
KernelSampleLocation.xy = clamp(KernelSampleLocation.xy, FfxInt32x2(0, 0), ImageSize.xy-1);
|
||||
#endif
|
||||
|
||||
// which 'global' tile in the image space
|
||||
const FfxInt32 iTile_ImageSpace = FfxInt32(KernelSampleLocation.y * BLUR_TILE_SIZE_Y_INV);
|
||||
|
||||
// local tile in this workgroup - apply the offset to convert to local space tile coordinates
|
||||
// this is needed for workgroups that have WorkgroupID.y > 0: the previous workgroup's
|
||||
// tile mapping doesn't have to align with the current one's depending on the FFX_BLUR_TILE_SIZE_XY.
|
||||
// e.g. WorkGroupID=1's first tile will map to 0 in local space, but could be some non-0 index
|
||||
// in the local space of the previous workgroup (WorkGroupID=0).
|
||||
// Not correcting for this mapping will result in a chopped image on the workgroup borders.
|
||||
const FfxInt32 iTile = iTile_ImageSpace - (iTileCountPerWorkgroup * WorkGroupID.y);
|
||||
|
||||
FfxInt32x2 TileThreadID = FfxInt32x2(ThreadID.x, FAST_MOD(KernelSampleLocation.y, FFX_BLUR_TILE_SIZE_Y));
|
||||
//FfxInt32x2 TileThreadID = FfxInt32x2(ThreadID.x, KernelSampleLocation.y % BLUR_TILE_SIZE_Y);
|
||||
|
||||
value += LoadFromCachedOutputTile(TileThreadID, iTile) * BlurLoadKernelWeight(abs(i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
#endif // FFX_HALF
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//==============================================================================================================================
|
||||
// INPUT/OUTPUT CACHE HELPERS
|
||||
//==============================================================================================================================
|
||||
//
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
// Fills the input cache with the corresponding rgion from the image + kernel extents
|
||||
void FillInputCache(in FfxInt32x2 lxy, FfxInt32x2 CenterPixelLocation, FfxInt32x2 ImageSize)
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 c = FfxFloat16x3(0, 0, 0);
|
||||
#else
|
||||
FfxFloat32x3 c = FfxFloat32x3(0, 0, 0);
|
||||
#endif
|
||||
|
||||
// slide the thread group over the InputCache
|
||||
const FfxInt32 iNumLoops = DIV_AND_ROUND_UP(INPUT_CACHE_TILE_SIZE_X, FFX_BLUR_TILE_SIZE_X);
|
||||
for (FfxInt32 i = 0; i < iNumLoops; ++i)
|
||||
{
|
||||
FfxInt32x2 LDSCoord = lxy - FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0) + FfxInt32x2(i * FFX_BLUR_TILE_SIZE_X, 0);
|
||||
FfxInt32x2 SamplePosition = CenterPixelLocation - FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0) + FfxInt32x2(i * FFX_BLUR_TILE_SIZE_X, 0);
|
||||
#if !BLUR_DISABLE_CLAMP
|
||||
SamplePosition.x = clamp(SamplePosition.x, 0, ImageSize.x - 1);
|
||||
#endif
|
||||
c = BlurLoadInput(SamplePosition);
|
||||
|
||||
// clamp to LDS bounds if we're on the last iteration of the loop
|
||||
if (i == iNumLoops - 1)
|
||||
{
|
||||
// faster than 'if (LDSCoord.x < INPUT_CACHE_TILE_SIZE_X)', avoids a vmem sync at the cost of some ALU
|
||||
LDSCoord.x = clamp(LDSCoord.x, -FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0), (INPUT_CACHE_TILE_SIZE_X - 1) - FfxInt32x2(FFX_BLUR_KERNEL_RANGE - 1, 0));
|
||||
}
|
||||
CacheInInputTile(LDSCoord, 0, c);
|
||||
}
|
||||
LDSBarrier();
|
||||
}
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
// Fills the output cache with the horizontally-blurred image.
|
||||
void PreFillOutputCache(in FfxInt32x2 gxy, in FfxInt32x2 lxy, in FfxInt32x2 WorkGroupID, FfxInt32x2 ImageSize)
|
||||
{
|
||||
#if BLUR_DEBUG_PREFILL_OUTPUT_CACHE_WITH_COLOR
|
||||
FfxFloat32x3 FillColor = FfxFloat32x3(0, 0, 0); // black border color
|
||||
[unroll]
|
||||
for (FfxInt32 iTile = 0; iTile < NUM_TILES_OUTPUT_CACHE; ++iTile)
|
||||
{
|
||||
CacheInOutputTile(lxy, iTile, FillColor);
|
||||
}
|
||||
LDSBarrier();
|
||||
#endif
|
||||
|
||||
// load from VMEM the first NUM_PREFILL_TILES_OUTPUT_CACHE tiles
|
||||
// while doing the horizontal blur, going top down
|
||||
#if FFX_HALF
|
||||
for (FfxInt16 j = FfxInt16(0); j < FfxInt16(NUM_PREFILL_TILES_OUTPUT_CACHE); ++j)
|
||||
#else
|
||||
for (FfxInt32 j = 0; j < NUM_PREFILL_TILES_OUTPUT_CACHE; ++j)
|
||||
#endif
|
||||
{
|
||||
const FfxInt32x2 ImageCoordinate = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * j);
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 c = HorizontalBlurFromTexture(ImageCoordinate, ImageSize);
|
||||
#else
|
||||
FfxFloat32x3 c = HorizontalBlurFromTexture(ImageCoordinate, ImageSize);
|
||||
#endif
|
||||
CacheInOutputTile(lxy, j, c);
|
||||
}
|
||||
|
||||
#if FFX_BLUR_DISPATCH_Y != 1
|
||||
// for any workgroup that doesn't start frop the top of the image,
|
||||
// fill the cache from the tail, going upwards in the image space
|
||||
if (WorkGroupID.y != 0)
|
||||
{
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 c = FfxFloat16x3(0, 0, 0);
|
||||
#else
|
||||
FfxFloat32x3 c = FfxFloat32x3(0, 0, 0);
|
||||
#endif
|
||||
#if FFX_HALF
|
||||
for (FfxInt16 j = FfxInt16(1); j < FfxInt16(NUM_PREFILL_TILES_OUTPUT_CACHE+1 + (DIV_AND_ROUND_UP(FFX_BLUR_KERNEL_RANGE, FFX_BLUR_TILE_SIZE_Y))); ++j)
|
||||
#else
|
||||
for (FfxInt32 j = 1; j < NUM_PREFILL_TILES_OUTPUT_CACHE+1 + (DIV_AND_ROUND_UP(FFX_BLUR_KERNEL_RANGE, FFX_BLUR_TILE_SIZE_Y)); ++j)
|
||||
#endif
|
||||
{
|
||||
const FfxInt32x2 ImageCoordinate = gxy - FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * j);
|
||||
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
FillInputCache(lxy, ImageCoordinate, ImageSize);
|
||||
c = HorizontalBlurFromCachedInput(lxy);
|
||||
#else
|
||||
c = HorizontalBlurFromTexture(ImageCoordinate, ImageSize);
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
CacheInOutputTile(lxy, (FfxInt16(NUM_TILES_OUTPUT_CACHE) - j), c);
|
||||
#else
|
||||
CacheInOutputTile(lxy, (NUM_TILES_OUTPUT_CACHE - j), c);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
LDSBarrier(); // OutputCache Sync: Read -> Write =========================================
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//==============================================================================================================================
|
||||
// BLUR GAUSSIAN BLUR ALGORITHM
|
||||
//==============================================================================================================================
|
||||
|
||||
/// ffxBlur: The main idea of the algorithm is to utilize a number of tiles (8x8) that are cached on the groupshared memory
|
||||
/// in a ring-buffer fashion to speed up texture lookups in a hand-optimized compute shader.
|
||||
/// The tiles are defined by the FFX_BLUR_TILE_SIZE_X and FFX_BLUR_TILE_SIZE_Y defines, and are typically 8x8 pixels.
|
||||
/// The image is horizontally blurred while being cached on the groupshared memory,
|
||||
/// and when all the groupshared tiles are filled, a vertical blur pass is done on the groupshared memory
|
||||
/// and the result is stored in the UAV as the final destination.
|
||||
///
|
||||
/// The algorithm is as follows:
|
||||
/// - Pre-fill LDS with 8x8 tiles, storing vertical tiles, containing horizontally blurred color
|
||||
/// - Loop until the entire image is covered:
|
||||
/// - Run a vertical blur pass on the LDS and output to final destination UAV
|
||||
/// - Re-fill LDS with horizontally-blurred data
|
||||
/// - Finish off the remaining last row/section of the image
|
||||
///
|
||||
/// @param [in] GlobalThreadID The SV_DispatchThreadID.xy or gl_GlobalInvocationID.xy.
|
||||
/// @param [in] WorkGroupLocalThreadID The SV_GroupThreadID.xy or gl_LocalInvocationID.xy.
|
||||
/// @param [in] WorkGroupID The SV_GroupID.xy or gl_WorkGroupID.xy.
|
||||
/// @param [in] ImageSize The two dimensional size of the input and output image.
|
||||
///
|
||||
/// @ingroup FfxGPUBlur
|
||||
void ffxBlur(
|
||||
in FfxInt32x2 GlobalThreadID,
|
||||
in FfxInt32x2 WorkGroupLocalThreadID,
|
||||
in FfxInt32x2 WorkGroupID,
|
||||
FfxInt32x2 ImageSize)
|
||||
{
|
||||
// Each threadgroup processes a number of tiles of size FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_TILE_SIZE_X
|
||||
// This number depends on the image height and the vertical dimension (_Y) of the FFX_BLUR_TILE_SIZE
|
||||
//const FfxUInt32 iTileCount = DIV_AND_ROUND_UP(ImageSize.y, FFX_BLUR_TILE_SIZE_Y);
|
||||
const FfxUInt32 iTileCount =
|
||||
DIV_AND_ROUND_UP(
|
||||
ImageSize.y,
|
||||
FFX_BLUR_TILE_SIZE_Y * FFX_BLUR_DISPATCH_Y);
|
||||
|
||||
FfxInt32x2 gxy = FfxInt32x2(
|
||||
WorkGroupID.x * FFX_BLUR_TILE_SIZE_X + WorkGroupLocalThreadID.x
|
||||
, WorkGroupLocalThreadID.y + WorkGroupID.y * iTileCount * FFX_BLUR_TILE_SIZE_Y
|
||||
);
|
||||
FfxInt32x2 lxy = WorkGroupLocalThreadID;
|
||||
|
||||
if (gxy.x >= ImageSize.x)
|
||||
return;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// STEP #1
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Pre-fill the output cache with a few tiles of horizontally blurred image.
|
||||
// The tile count to pre-fill is a function of kernel width and TileSizeY.
|
||||
PreFillOutputCache(gxy, lxy, WorkGroupID, ImageSize); // doesn't sync waves
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// STEP #2
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// loop through the tiles and write out to UAV as we go from top to down
|
||||
FfxInt32 iTileOutput = 0;
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 c = FfxFloat16x3(0, 0, 0);
|
||||
#else
|
||||
FfxFloat32x3 c = FfxFloat32x3(0, 0, 0);
|
||||
#endif
|
||||
for (; iTileOutput < iTileCount - NUM_PREFILL_TILES_OUTPUT_CACHE; ++iTileOutput)
|
||||
{
|
||||
// index of next tile that we'll cache the output to
|
||||
// It runs ahead of the tile we will be writing out to UAV by NUM_PREFILL_TILES_OUTPUT_CACHE tiles
|
||||
FfxInt32 iNextTileOutputCache = iTileOutput + NUM_PREFILL_TILES_OUTPUT_CACHE;
|
||||
const FfxInt32x2 HorizontalBlurInputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iNextTileOutputCache);
|
||||
|
||||
// run horizontal blur & cache the next output tile
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
FillInputCache(lxy, HorizontalBlurInputCoord, ImageSize);
|
||||
c = HorizontalBlurFromCachedInput(lxy);
|
||||
#else
|
||||
// Number of image_load instructions will scale with FFX_BLUR_OPTION_KERNEL_DIMENSION.
|
||||
c = HorizontalBlurFromTexture(HorizontalBlurInputCoord, ImageSize);
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
|
||||
#if FFX_HALF
|
||||
CacheInOutputTile(lxy, FfxInt16(iNextTileOutputCache), c);
|
||||
#else
|
||||
CacheInOutputTile(lxy, iNextTileOutputCache, c);
|
||||
#endif
|
||||
|
||||
LDSBarrier(); // OutputCache Sync: Write -> Read =========================================
|
||||
|
||||
// Start writing out the pixel value which has its final value
|
||||
// convolved from the pixels aready in the LDS section.
|
||||
const FfxInt32x2 OutputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iTileOutput);
|
||||
#if FFX_HALF
|
||||
c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, FfxInt16x2(OutputCoord), FfxInt16x2(ImageSize));
|
||||
#else
|
||||
c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, OutputCoord, ImageSize);
|
||||
#endif
|
||||
BlurStoreOutput(OutputCoord, c);
|
||||
LDSBarrier(); // OutputCache Sync: Read -> Write =========================================
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// STEP #3
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// fill in the remaining last tiles (= loop for NUM_PREFILL_TILES_OUTPUT_CACHE)
|
||||
for (; iTileOutput < iTileCount; ++iTileOutput)
|
||||
{
|
||||
const FfxInt32x2 OutputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iTileOutput);
|
||||
if (iTileOutput >= iTileCount - NUM_PREFILL_TILES_OUTPUT_CACHE)
|
||||
{
|
||||
FfxInt32 iNextTileOutputCache = iTileOutput + NUM_PREFILL_TILES_OUTPUT_CACHE;
|
||||
const FfxInt32x2 HorizontalBlurInputCoord = gxy + FfxInt32x2(0, FFX_BLUR_TILE_SIZE_Y * iNextTileOutputCache);
|
||||
|
||||
// run horizontal blur & cache the next output tile
|
||||
#if BLUR_ENABLE_INPUT_CACHE
|
||||
FillInputCache(lxy, HorizontalBlurInputCoord, ImageSize);
|
||||
c = HorizontalBlurFromCachedInput(lxy);
|
||||
#else
|
||||
// Number of image_load instructions will scale with FFX_BLUR_OPTION_KERNEL_DIMENSION.
|
||||
c = HorizontalBlurFromTexture(HorizontalBlurInputCoord, ImageSize);
|
||||
#endif // BLUR_ENABLE_INPUT_CACHE
|
||||
|
||||
#if FFX_HALF
|
||||
CacheInOutputTile(lxy, FfxInt16(iNextTileOutputCache), c);
|
||||
#else
|
||||
CacheInOutputTile(lxy, iNextTileOutputCache, c);
|
||||
#endif
|
||||
|
||||
LDSBarrier(); // OutputCache Sync: Write -> Read =========================================
|
||||
}
|
||||
#if FFX_HALF
|
||||
c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, FfxInt16x2(OutputCoord), FfxInt16x2(ImageSize));
|
||||
#else
|
||||
c = VerticalBlurFromCachedOutput(lxy, WorkGroupID, OutputCoord, ImageSize);
|
||||
#endif
|
||||
BlurStoreOutput(OutputCoord, c);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !FFX_CPU
|
||||
#endif // FFX_BLUR_H
|
||||
65
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_blur.h
vendored
Normal file
65
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_blur.h
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
// 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_core.h"
|
||||
|
||||
FFX_BLUR_KERNEL_TYPE BlurLoadKernelWeight(FfxInt32 iKernelIndex)
|
||||
{
|
||||
return FfxBlurLoadKernelWeight(iKernelIndex);
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
void BlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat16x3 color)
|
||||
{
|
||||
FfxBlurStoreOutput(outPxCoord, color);
|
||||
}
|
||||
|
||||
FfxFloat16x3 BlurLoadInput(FfxInt16x2 inPxCoord)
|
||||
{
|
||||
return FfxBlurLoadInput(inPxCoord);
|
||||
}
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
void BlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color)
|
||||
{
|
||||
FfxBlurStoreOutput(outPxCoord, color);
|
||||
}
|
||||
|
||||
// DXIL generates load/sync/store blocks for each channel, ticket open: https://ontrack-internal.amd.com/browse/SWDEV-303837
|
||||
// this is 10x times slower!!!
|
||||
//void Blur_StoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color) { texColorOutput[outPxCoord].rgb = color; }
|
||||
FfxFloat32x3 BlurLoadInput(FfxInt32x2 inPxCoord)
|
||||
{
|
||||
return FfxBlurLoadInput(inPxCoord);
|
||||
}
|
||||
|
||||
#endif // !FFX_HALF
|
||||
|
||||
#include "blur/ffx_blur.h"
|
||||
|
||||
|
||||
void ffxBlurPass(FfxInt32x2 DispatchThreadID, FfxInt32x2 LocalThreadId, FfxInt32x2 WorkGroupId)
|
||||
{
|
||||
ffxBlur(DispatchThreadID, LocalThreadId, WorkGroupId, ImageSize());
|
||||
}
|
||||
216
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_callbacks_glsl.h
vendored
Normal file
216
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
// 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_blur_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core.h"
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #if defined(FFX_PREFER_WAVE64)
|
||||
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
|
||||
#if defined(FFX_BLUR_BIND_CB_BLUR)
|
||||
layout (set = 0, binding = FFX_BLUR_BIND_CB_BLUR, std140) uniform cbBLUR_t
|
||||
{
|
||||
FfxInt32x2 imageSize;
|
||||
} cbBLUR;
|
||||
#endif
|
||||
|
||||
FfxInt32x2 ImageSize()
|
||||
{
|
||||
return cbBLUR.imageSize;
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined FFX_BLUR_BIND_SRV_INPUT_SRC
|
||||
layout (set = 0, binding = FFX_BLUR_BIND_SRV_INPUT_SRC) uniform texture2D r_input_src;
|
||||
#endif
|
||||
|
||||
// UAV declarations
|
||||
#if defined FFX_BLUR_BIND_UAV_OUTPUT
|
||||
layout (set = 0, binding = FFX_BLUR_BIND_UAV_OUTPUT, rgba32f) uniform image2D rw_output;
|
||||
#endif
|
||||
|
||||
// FFX_BLUR_OPTION_KERNEL_DIMENSION to be defined by the client application
|
||||
// App should define e.g the following for 5x5 blur:
|
||||
// #define FFX_BLUR_OPTION_KERNEL_DIMENSION 5
|
||||
#ifndef FFX_BLUR_OPTION_KERNEL_DIMENSION
|
||||
#error Please define FFX_BLUR_OPTION_KERNEL_DIMENSION
|
||||
#endif
|
||||
|
||||
// FFX_BLUR_KERNEL_RANGE is center + half width of the kernel
|
||||
//
|
||||
// consider a blur kernel 5x5 - '*' indicates the center of the kernel
|
||||
// FFX_BLUR_OPTION_KERNEL_DIMENSION=5
|
||||
// |---------------|
|
||||
// x x x x x
|
||||
// x x x x x
|
||||
// x x x* x x
|
||||
// x x x x x
|
||||
// x x x x x
|
||||
//
|
||||
//
|
||||
// as separate 1D kernels
|
||||
//
|
||||
// x x x* x x
|
||||
// |-------|
|
||||
// FFX_BLUR_KERNEL_RANGE
|
||||
//
|
||||
#define FFX_BLUR_KERNEL_RANGE (((FFX_BLUR_OPTION_KERNEL_DIMENSION - 1) / 2) + 1)
|
||||
#define FFX_BLUR_KERNEL_RANGE_MINUS1 (FFX_BLUR_KERNEL_RANGE - 1)
|
||||
|
||||
//
|
||||
// FFX-Blur Callback definitions
|
||||
//
|
||||
#if FFX_HALF
|
||||
#define FFX_BLUR_KERNEL_TYPE FfxFloat16
|
||||
#else
|
||||
#define FFX_BLUR_KERNEL_TYPE FfxFloat32
|
||||
#endif
|
||||
|
||||
FFX_BLUR_KERNEL_TYPE FfxBlurLoadKernelWeight(FfxInt32 iKernelIndex)
|
||||
{
|
||||
// GAUSSIAN BLUR 1D KERNELS
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------------------------------------------------
|
||||
// Kernel Size: [3, 21]: odd numbers
|
||||
// Kernels are pregenerated using three different sigma values.
|
||||
// Larger sigmas are better for larger kernels.
|
||||
const FFX_BLUR_KERNEL_TYPE kernel_weights[FFX_BLUR_KERNEL_RANGE] =
|
||||
#if FFX_BLUR_OPTION_KERNEL_PERMUTATION == 0
|
||||
// Sigma: 1.6
|
||||
#if FFX_BLUR_KERNEL_RANGE == 2
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.3765770884), FFX_BLUR_KERNEL_TYPE(0.3117114558) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 3
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2782163289), FFX_BLUR_KERNEL_TYPE(0.230293397), FFX_BLUR_KERNEL_TYPE(0.1305984385) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 4
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2525903052), FFX_BLUR_KERNEL_TYPE(0.2090814714), FFX_BLUR_KERNEL_TYPE(0.1185692428), FFX_BLUR_KERNEL_TYPE(0.0460541333) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 5
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2465514351), FFX_BLUR_KERNEL_TYPE(0.2040828004), FFX_BLUR_KERNEL_TYPE(0.115734517), FFX_BLUR_KERNEL_TYPE(0.0449530818), FFX_BLUR_KERNEL_TYPE(0.0119538834) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 6
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.245483563), FFX_BLUR_KERNEL_TYPE(0.2031988699), FFX_BLUR_KERNEL_TYPE(0.1152332436), FFX_BLUR_KERNEL_TYPE(0.0447583794), FFX_BLUR_KERNEL_TYPE(0.0119021083), FFX_BLUR_KERNEL_TYPE(0.0021656173) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 7
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2453513488), FFX_BLUR_KERNEL_TYPE(0.2030894296), FFX_BLUR_KERNEL_TYPE(0.1151711805), FFX_BLUR_KERNEL_TYPE(0.0447342732), FFX_BLUR_KERNEL_TYPE(0.011895698), FFX_BLUR_KERNEL_TYPE(0.0021644509), FFX_BLUR_KERNEL_TYPE(0.0002692935) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 8
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2453401155), FFX_BLUR_KERNEL_TYPE(0.2030801313), FFX_BLUR_KERNEL_TYPE(0.1151659074), FFX_BLUR_KERNEL_TYPE(0.044732225), FFX_BLUR_KERNEL_TYPE(0.0118951533), FFX_BLUR_KERNEL_TYPE(0.0021643518), FFX_BLUR_KERNEL_TYPE(0.0002692811), FFX_BLUR_KERNEL_TYPE(2.28922E-05) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 9
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2453394635), FFX_BLUR_KERNEL_TYPE(0.2030795916), FFX_BLUR_KERNEL_TYPE(0.1151656014), FFX_BLUR_KERNEL_TYPE(0.0447321061), FFX_BLUR_KERNEL_TYPE(0.0118951217), FFX_BLUR_KERNEL_TYPE(0.0021643461), FFX_BLUR_KERNEL_TYPE(0.0002692804), FFX_BLUR_KERNEL_TYPE(2.28922E-05), FFX_BLUR_KERNEL_TYPE(1.3287E-06) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 10
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2453394377), FFX_BLUR_KERNEL_TYPE(0.2030795703), FFX_BLUR_KERNEL_TYPE(0.1151655892), FFX_BLUR_KERNEL_TYPE(0.0447321014), FFX_BLUR_KERNEL_TYPE(0.0118951205), FFX_BLUR_KERNEL_TYPE(0.0021643458), FFX_BLUR_KERNEL_TYPE(0.0002692804), FFX_BLUR_KERNEL_TYPE(2.28922E-05), FFX_BLUR_KERNEL_TYPE(1.3287E-06), FFX_BLUR_KERNEL_TYPE(5.26E-08) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 11
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2453394371), FFX_BLUR_KERNEL_TYPE(0.2030795697), FFX_BLUR_KERNEL_TYPE(0.1151655889), FFX_BLUR_KERNEL_TYPE(0.0447321013), FFX_BLUR_KERNEL_TYPE(0.0118951204), FFX_BLUR_KERNEL_TYPE(0.0021643458), FFX_BLUR_KERNEL_TYPE(0.0002692804), FFX_BLUR_KERNEL_TYPE(2.28922E-05), FFX_BLUR_KERNEL_TYPE(1.3287E-06), FFX_BLUR_KERNEL_TYPE(5.26E-08), FFX_BLUR_KERNEL_TYPE(1.4E-09) };
|
||||
#endif
|
||||
#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 1
|
||||
// Sigma: 2.8
|
||||
#if FFX_BLUR_KERNEL_RANGE == 2
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.3474999743), FFX_BLUR_KERNEL_TYPE(0.3262500129) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 3
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2256541468), FFX_BLUR_KERNEL_TYPE(0.2118551763), FFX_BLUR_KERNEL_TYPE(0.1753177504) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 4
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1796953063), FFX_BLUR_KERNEL_TYPE(0.1687067636), FFX_BLUR_KERNEL_TYPE(0.1396108926), FFX_BLUR_KERNEL_TYPE(0.1018346906) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 5
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1588894947), FFX_BLUR_KERNEL_TYPE(0.1491732476), FFX_BLUR_KERNEL_TYPE(0.1234462081), FFX_BLUR_KERNEL_TYPE(0.0900438796), FFX_BLUR_KERNEL_TYPE(0.0578919173) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 6
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1491060676), FFX_BLUR_KERNEL_TYPE(0.1399880866), FFX_BLUR_KERNEL_TYPE(0.1158451582), FFX_BLUR_KERNEL_TYPE(0.0844995374), FFX_BLUR_KERNEL_TYPE(0.054327293), FFX_BLUR_KERNEL_TYPE(0.0307868909) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 7
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1446570603), FFX_BLUR_KERNEL_TYPE(0.1358111404), FFX_BLUR_KERNEL_TYPE(0.1123885856), FFX_BLUR_KERNEL_TYPE(0.0819782513), FFX_BLUR_KERNEL_TYPE(0.0527062824), FFX_BLUR_KERNEL_TYPE(0.0298682757), FFX_BLUR_KERNEL_TYPE(0.0149189344) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 8
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1427814521), FFX_BLUR_KERNEL_TYPE(0.1340502275), FFX_BLUR_KERNEL_TYPE(0.110931367), FFX_BLUR_KERNEL_TYPE(0.0809153299), FFX_BLUR_KERNEL_TYPE(0.0520228983), FFX_BLUR_KERNEL_TYPE(0.0294810068), FFX_BLUR_KERNEL_TYPE(0.0147254971), FFX_BLUR_KERNEL_TYPE(0.0064829474) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 9
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1420666821), FFX_BLUR_KERNEL_TYPE(0.1333791663), FFX_BLUR_KERNEL_TYPE(0.1103760399), FFX_BLUR_KERNEL_TYPE(0.0805102644), FFX_BLUR_KERNEL_TYPE(0.0517624694), FFX_BLUR_KERNEL_TYPE(0.0293334236), FFX_BLUR_KERNEL_TYPE(0.0146517806), FFX_BLUR_KERNEL_TYPE(0.0064504935), FFX_BLUR_KERNEL_TYPE(0.0025030212) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 10
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1418238658), FFX_BLUR_KERNEL_TYPE(0.1331511984), FFX_BLUR_KERNEL_TYPE(0.1101873883), FFX_BLUR_KERNEL_TYPE(0.0803726585), FFX_BLUR_KERNEL_TYPE(0.0516739985), FFX_BLUR_KERNEL_TYPE(0.0292832877), FFX_BLUR_KERNEL_TYPE(0.0146267382), FFX_BLUR_KERNEL_TYPE(0.0064394685), FFX_BLUR_KERNEL_TYPE(0.0024987432), FFX_BLUR_KERNEL_TYPE(0.0008545858) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 11
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1417508359), FFX_BLUR_KERNEL_TYPE(0.1330826344), FFX_BLUR_KERNEL_TYPE(0.1101306491), FFX_BLUR_KERNEL_TYPE(0.0803312719), FFX_BLUR_KERNEL_TYPE(0.0516473898), FFX_BLUR_KERNEL_TYPE(0.0292682088), FFX_BLUR_KERNEL_TYPE(0.0146192064), FFX_BLUR_KERNEL_TYPE(0.0064361526), FFX_BLUR_KERNEL_TYPE(0.0024974565), FFX_BLUR_KERNEL_TYPE(0.0008541457), FFX_BLUR_KERNEL_TYPE(0.0002574667) };
|
||||
#endif
|
||||
#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 2
|
||||
// Sigma: 4
|
||||
#if FFX_BLUR_KERNEL_RANGE == 2
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.3402771036), FFX_BLUR_KERNEL_TYPE(0.3298614482) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 3
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.2125433723), FFX_BLUR_KERNEL_TYPE(0.2060375614), FFX_BLUR_KERNEL_TYPE(0.1876907525) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 4
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1608542243), FFX_BLUR_KERNEL_TYPE(0.1559305837), FFX_BLUR_KERNEL_TYPE(0.1420455978), FFX_BLUR_KERNEL_TYPE(0.1215967064) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 5
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1345347233), FFX_BLUR_KERNEL_TYPE(0.1304167051), FFX_BLUR_KERNEL_TYPE(0.1188036266), FFX_BLUR_KERNEL_TYPE(0.1017006505), FFX_BLUR_KERNEL_TYPE(0.0818116562) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 6
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1197258568), FFX_BLUR_KERNEL_TYPE(0.1160611281), FFX_BLUR_KERNEL_TYPE(0.1057263555), FFX_BLUR_KERNEL_TYPE(0.090505984), FFX_BLUR_KERNEL_TYPE(0.0728062644), FFX_BLUR_KERNEL_TYPE(0.0550373395) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 7
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1110429695), FFX_BLUR_KERNEL_TYPE(0.1076440182), FFX_BLUR_KERNEL_TYPE(0.0980587551), FFX_BLUR_KERNEL_TYPE(0.0839422118), FFX_BLUR_KERNEL_TYPE(0.0675261302), FFX_BLUR_KERNEL_TYPE(0.0510458624), FFX_BLUR_KERNEL_TYPE(0.0362615375) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 8
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1059153311), FFX_BLUR_KERNEL_TYPE(0.1026733334), FFX_BLUR_KERNEL_TYPE(0.0935306896), FFX_BLUR_KERNEL_TYPE(0.0800660068), FFX_BLUR_KERNEL_TYPE(0.0644079717), FFX_BLUR_KERNEL_TYPE(0.0486887143), FFX_BLUR_KERNEL_TYPE(0.0345870861), FFX_BLUR_KERNEL_TYPE(0.0230885324) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 9
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1029336421), FFX_BLUR_KERNEL_TYPE(0.0997829119), FFX_BLUR_KERNEL_TYPE(0.0908976484), FFX_BLUR_KERNEL_TYPE(0.0778120183), FFX_BLUR_KERNEL_TYPE(0.0625947824), FFX_BLUR_KERNEL_TYPE(0.0473180477), FFX_BLUR_KERNEL_TYPE(0.0336134033), FFX_BLUR_KERNEL_TYPE(0.0224385526), FFX_BLUR_KERNEL_TYPE(0.0140758142) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 10
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1012533395), FFX_BLUR_KERNEL_TYPE(0.0981540422), FFX_BLUR_KERNEL_TYPE(0.089413823), FFX_BLUR_KERNEL_TYPE(0.0765418045), FFX_BLUR_KERNEL_TYPE(0.0615729768), FFX_BLUR_KERNEL_TYPE(0.0465456216), FFX_BLUR_KERNEL_TYPE(0.0330646936), FFX_BLUR_KERNEL_TYPE(0.0220722627), FFX_BLUR_KERNEL_TYPE(0.0138460388), FFX_BLUR_KERNEL_TYPE(0.0081620671) };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 11
|
||||
{ FFX_BLUR_KERNEL_TYPE(0.1003459368), FFX_BLUR_KERNEL_TYPE(0.0972744146), FFX_BLUR_KERNEL_TYPE(0.0886125226), FFX_BLUR_KERNEL_TYPE(0.0758558594), FFX_BLUR_KERNEL_TYPE(0.0610211779), FFX_BLUR_KERNEL_TYPE(0.0461284934), FFX_BLUR_KERNEL_TYPE(0.0327683775), FFX_BLUR_KERNEL_TYPE(0.0218744576), FFX_BLUR_KERNEL_TYPE(0.0137219546), FFX_BLUR_KERNEL_TYPE(0.008088921), FFX_BLUR_KERNEL_TYPE(0.0044808529) };
|
||||
#endif
|
||||
#else
|
||||
#error FFX_BLUR_OPTION_KERNEL_PERMUTATION is not a valid value.
|
||||
#endif // FFX_BLUR_OPTION_KERNEL_PERMUTATIONs
|
||||
|
||||
return kernel_weights[iKernelIndex];
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#if defined (FFX_BLUR_BIND_UAV_OUTPUT)
|
||||
void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat16x3 color)
|
||||
{
|
||||
imageStore(rw_output, outPxCoord, FfxFloat16x4(color, 1));
|
||||
}
|
||||
#endif // #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
|
||||
|
||||
#if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
|
||||
FfxFloat16x3 FfxBlurLoadInput(FfxInt16x2 inPxCoord)
|
||||
{
|
||||
return FfxFloat16x3(texelFetch(r_input_src, inPxCoord, 0).rgb);
|
||||
}
|
||||
#endif // #if defined FFX_BLUR_BIND_SRV_INPUT_SRC
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
#if defined (FFX_BLUR_BIND_UAV_OUTPUT)
|
||||
void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color)
|
||||
{
|
||||
imageStore(rw_output, outPxCoord, FfxFloat32x4(color, 1));
|
||||
}
|
||||
#endif // #if defined FFX_BLUR_BIND_UAV_OUTPUT
|
||||
|
||||
// DXIL generates load/sync/store blocks for each channel, ticket open: https://ontrack-internal.amd.com/browse/SWDEV-303837
|
||||
// this is 10x times slower!!!
|
||||
//void Blur_StoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color) { texColorOutput[outPxCoord].rgb = color; }
|
||||
#if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
|
||||
FfxFloat32x3 FfxBlurLoadInput(FfxInt32x2 inPxCoord)
|
||||
{
|
||||
return texelFetch(r_input_src, inPxCoord, 0).rgb;
|
||||
}
|
||||
#endif // #if defined FFX_BLUR_BIND_SRV_INPUT_SRC
|
||||
|
||||
#endif // !FFX_HALF
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
254
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_callbacks_hlsl.h
vendored
Normal file
254
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,254 @@
|
||||
// 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_blur_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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
|
||||
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
|
||||
#define DECLARE_CB_REGISTER(regIndex) b##regIndex
|
||||
#define FFX_BLUR_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_BLUR_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_BLUR_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(FFX_BLUR_BIND_CB_BLUR)
|
||||
cbuffer cbBLUR : FFX_BLUR_DECLARE_CB(FFX_BLUR_BIND_CB_BLUR)
|
||||
{
|
||||
FfxInt32x2 imageSize;
|
||||
#define FFX_BLUR_CONSTANT_BUFFER_1_SIZE 2 // Number of 32-bit values. This must be kept in sync with the cbBLUR size.
|
||||
};
|
||||
#else
|
||||
#define imageSize 0
|
||||
#endif
|
||||
|
||||
#define FFX_BLUR_ROOTSIG_STRINGIFY(p) FFX_BLUR_ROOTSIG_STR(p)
|
||||
#define FFX_BLUR_ROOTSIG_STR(p) #p
|
||||
#define FFX_BLUR_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_BLUR_ROOTSIG_STRINGIFY(FFX_BLUR_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_BLUR_ROOTSIG_STRINGIFY(FFX_BLUR_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0)" )]
|
||||
|
||||
#if defined(FFX_BLUR_EMBED_ROOTSIG)
|
||||
#define FFX_BLUR_EMBED_ROOTSIG_CONTENT FFX_BLUR_ROOTSIG
|
||||
#else
|
||||
#define FFX_BLUR_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_BLUR_EMBED_ROOTSIG
|
||||
|
||||
FfxInt32x2 ImageSize()
|
||||
{
|
||||
return imageSize;
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined FFX_BLUR_BIND_SRV_INPUT_SRC
|
||||
#if FFX_HALF
|
||||
Texture2D<FfxFloat16x4> r_input_src : FFX_BLUR_DECLARE_SRV(FFX_BLUR_BIND_SRV_INPUT_SRC);
|
||||
#else
|
||||
Texture2D<FfxFloat32x4> r_input_src : FFX_BLUR_DECLARE_SRV(FFX_BLUR_BIND_SRV_INPUT_SRC);
|
||||
#endif // FFX_HALF
|
||||
#endif
|
||||
|
||||
// UAV declarations
|
||||
#if defined FFX_BLUR_BIND_UAV_OUTPUT
|
||||
#if FFX_HALF
|
||||
RWTexture2D<FfxFloat16x4> rw_output : FFX_BLUR_DECLARE_UAV(FFX_BLUR_BIND_UAV_OUTPUT);
|
||||
#else
|
||||
RWTexture2D<FfxFloat32x4> rw_output : FFX_BLUR_DECLARE_UAV(FFX_BLUR_BIND_UAV_OUTPUT);
|
||||
#endif // FFX_HALF
|
||||
#endif
|
||||
|
||||
// FFX_BLUR_OPTION_KERNEL_DIMENSION to be defined by the client application
|
||||
// App should define e.g the following for 5x5 blur:
|
||||
// #define FFX_BLUR_OPTION_KERNEL_DIMENSION 5
|
||||
#ifndef FFX_BLUR_OPTION_KERNEL_DIMENSION
|
||||
#error Please define FFX_BLUR_OPTION_KERNEL_DIMENSION
|
||||
#endif
|
||||
|
||||
// FFX_BLUR_KERNEL_RANGE is center + half width of the kernel
|
||||
//
|
||||
// consider a blur kernel 5x5 - '*' indicates the center of the kernel
|
||||
// FFX_BLUR_OPTION_KERNEL_DIMENSION=5
|
||||
// |---------------|
|
||||
// x x x x x
|
||||
// x x x x x
|
||||
// x x x* x x
|
||||
// x x x x x
|
||||
// x x x x x
|
||||
//
|
||||
//
|
||||
// as separate 1D kernels
|
||||
//
|
||||
// x x x* x x
|
||||
// |-------|
|
||||
// FFX_BLUR_KERNEL_RANGE
|
||||
//
|
||||
#define FFX_BLUR_KERNEL_RANGE (((FFX_BLUR_OPTION_KERNEL_DIMENSION - 1) / 2) + 1)
|
||||
#define FFX_BLUR_KERNEL_RANGE_MINUS1 (FFX_BLUR_KERNEL_RANGE - 1)
|
||||
|
||||
//
|
||||
// FFX-Blur Callback definitions
|
||||
//
|
||||
#if FFX_HALF
|
||||
#define FFX_BLUR_KERNEL_TYPE FfxFloat16
|
||||
#else
|
||||
#define FFX_BLUR_KERNEL_TYPE FfxFloat32
|
||||
#endif
|
||||
|
||||
inline FFX_BLUR_KERNEL_TYPE FfxBlurLoadKernelWeight(FfxInt32 iKernelIndex)
|
||||
{
|
||||
// GAUSSIAN BLUR 1D KERNELS
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------------------
|
||||
// Kernel Size: [3, 21]: odd numbers
|
||||
// Kernels are pregenerated using three different sigma values.
|
||||
// Larger sigmas are better for larger kernels.
|
||||
const FFX_BLUR_KERNEL_TYPE kernel_weights[FFX_BLUR_KERNEL_RANGE] =
|
||||
#if FFX_BLUR_OPTION_KERNEL_PERMUTATION == 0
|
||||
// Sigma: 1.6
|
||||
#if FFX_BLUR_KERNEL_RANGE == 2
|
||||
{ 0.3765770884, 0.3117114558 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 3
|
||||
{ 0.2782163289, 0.230293397, 0.1305984385 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 4
|
||||
{ 0.2525903052, 0.2090814714, 0.1185692428, 0.0460541333 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 5
|
||||
{ 0.2465514351, 0.2040828004, 0.115734517, 0.0449530818, 0.0119538834 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 6
|
||||
{ 0.245483563, 0.2031988699, 0.1152332436, 0.0447583794, 0.0119021083, 0.0021656173 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 7
|
||||
{ 0.2453513488, 0.2030894296, 0.1151711805, 0.0447342732, 0.011895698, 0.0021644509, 0.0002692935 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 8
|
||||
{ 0.2453401155, 0.2030801313, 0.1151659074, 0.044732225, 0.0118951533, 0.0021643518, 0.0002692811, 2.28922E-05 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 9
|
||||
{ 0.2453394635, 0.2030795916, 0.1151656014, 0.0447321061, 0.0118951217, 0.0021643461, 0.0002692804, 2.28922E-05, 1.3287E-06 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 10
|
||||
{ 0.2453394377, 0.2030795703, 0.1151655892, 0.0447321014, 0.0118951205, 0.0021643458, 0.0002692804, 2.28922E-05, 1.3287E-06, 5.26E-08 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 11
|
||||
{ 0.2453394371, 0.2030795697, 0.1151655889, 0.0447321013, 0.0118951204, 0.0021643458, 0.0002692804, 2.28922E-05, 1.3287E-06, 5.26E-08, 1.4E-09 };
|
||||
#endif
|
||||
#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 1
|
||||
// Sigma: 2.8
|
||||
#if FFX_BLUR_KERNEL_RANGE == 2
|
||||
{ 0.3474999743, 0.3262500129 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 3
|
||||
{ 0.2256541468, 0.2118551763, 0.1753177504 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 4
|
||||
{ 0.1796953063, 0.1687067636, 0.1396108926, 0.1018346906 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 5
|
||||
{ 0.1588894947, 0.1491732476, 0.1234462081, 0.0900438796, 0.0578919173 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 6
|
||||
{ 0.1491060676, 0.1399880866, 0.1158451582, 0.0844995374, 0.054327293, 0.0307868909 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 7
|
||||
{ 0.1446570603, 0.1358111404, 0.1123885856, 0.0819782513, 0.0527062824, 0.0298682757, 0.0149189344 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 8
|
||||
{ 0.1427814521, 0.1340502275, 0.110931367, 0.0809153299, 0.0520228983, 0.0294810068, 0.0147254971, 0.0064829474 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 9
|
||||
{ 0.1420666821, 0.1333791663, 0.1103760399, 0.0805102644, 0.0517624694, 0.0293334236, 0.0146517806, 0.0064504935, 0.0025030212 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 10
|
||||
{ 0.1418238658, 0.1331511984, 0.1101873883, 0.0803726585, 0.0516739985, 0.0292832877, 0.0146267382, 0.0064394685, 0.0024987432, 0.0008545858 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 11
|
||||
{ 0.1417508359, 0.1330826344, 0.1101306491, 0.0803312719, 0.0516473898, 0.0292682088, 0.0146192064, 0.0064361526, 0.0024974565, 0.0008541457, 0.0002574667 };
|
||||
#endif
|
||||
#elif FFX_BLUR_OPTION_KERNEL_PERMUTATION == 2
|
||||
// Sigma: 4
|
||||
#if FFX_BLUR_KERNEL_RANGE == 2
|
||||
{ 0.3402771036, 0.3298614482 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 3
|
||||
{ 0.2125433723, 0.2060375614, 0.1876907525 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 4
|
||||
{ 0.1608542243, 0.1559305837, 0.1420455978, 0.1215967064 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 5
|
||||
{ 0.1345347233, 0.1304167051, 0.1188036266, 0.1017006505, 0.0818116562 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 6
|
||||
{ 0.1197258568, 0.1160611281, 0.1057263555, 0.090505984, 0.0728062644, 0.0550373395 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 7
|
||||
{ 0.1110429695, 0.1076440182, 0.0980587551, 0.0839422118, 0.0675261302, 0.0510458624, 0.0362615375 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 8
|
||||
{ 0.1059153311, 0.1026733334, 0.0935306896, 0.0800660068, 0.0644079717, 0.0486887143, 0.0345870861, 0.0230885324 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 9
|
||||
{ 0.1029336421, 0.0997829119, 0.0908976484, 0.0778120183, 0.0625947824, 0.0473180477, 0.0336134033, 0.0224385526, 0.0140758142 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 10
|
||||
{ 0.1012533395, 0.0981540422, 0.089413823, 0.0765418045, 0.0615729768, 0.0465456216, 0.0330646936, 0.0220722627, 0.0138460388, 0.0081620671 };
|
||||
#elif FFX_BLUR_KERNEL_RANGE == 11
|
||||
{ 0.1003459368, 0.0972744146, 0.0886125226, 0.0758558594, 0.0610211779, 0.0461284934, 0.0327683775, 0.0218744576, 0.0137219546, 0.008088921, 0.0044808529 };
|
||||
#endif
|
||||
#else
|
||||
#error FFX_BLUR_OPTION_KERNEL_PERMUTATION is not a valid value.
|
||||
#endif // FFX_BLUR_OPTION_KERNEL_PERMUTATIONs
|
||||
|
||||
return kernel_weights[iKernelIndex];
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#if defined (FFX_BLUR_BIND_UAV_OUTPUT)
|
||||
void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat16x3 color)
|
||||
{
|
||||
rw_output[outPxCoord] = FfxFloat16x4(color, 1);
|
||||
}
|
||||
#endif // #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
|
||||
|
||||
#if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
|
||||
FfxFloat16x3 FfxBlurLoadInput(FfxInt16x2 inPxCoord)
|
||||
{
|
||||
return r_input_src[inPxCoord].rgb;
|
||||
}
|
||||
#endif // #if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
#if defined (FFX_BLUR_BIND_UAV_OUTPUT)
|
||||
void FfxBlurStoreOutput(FfxInt32x2 outPxCoord, FfxFloat32x3 color)
|
||||
{
|
||||
rw_output[outPxCoord] = FfxFloat32x4(color, 1);
|
||||
}
|
||||
#endif // #if defined (FFX_BLUR_BIND_UAV_OUTPUT)
|
||||
|
||||
#if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
|
||||
FfxFloat32x3 FfxBlurLoadInput(FfxInt32x2 inPxCoord)
|
||||
{
|
||||
return r_input_src[inPxCoord].rgb;
|
||||
}
|
||||
#endif // #if defined (FFX_BLUR_BIND_SRV_INPUT_SRC)
|
||||
|
||||
#endif // !FFX_HALF
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
39
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_resources.h
vendored
Normal file
39
manul/thirdparty/fsr2/include/FidelityFX/gpu/blur/ffx_blur_resources.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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_BLUR_RESOURCES_H
|
||||
#define FFX_BLUR_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#define FFX_BLUR_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_BLUR_RESOURCE_IDENTIFIER_INPUT_SRC 1
|
||||
#define FFX_BLUR_RESOURCE_IDENTIFIER_OUTPUT 2
|
||||
|
||||
#define FFX_BLUR_RESOURCE_IDENTIFIER_COUNT 3
|
||||
|
||||
// CBV resource definitions
|
||||
#define FFX_BLUR_CONSTANTBUFFER_IDENTIFIER_BLUR 0
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif // FFX_BLUR_RESOURCES_H
|
||||
74
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/CMakeCompileBrixelizerShaders.txt
vendored
Normal file
74
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/CMakeCompileBrixelizerShaders.txt
vendored
Normal 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.
|
||||
|
||||
set(BRIXELIZER_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(BRIXELIZER_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/brixelizer")
|
||||
|
||||
if (NOT BRIXELIZER_SHADER_EXT)
|
||||
set(BRIXELIZER_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB BRIXELIZER_SHADERS
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_build_tree_aabb_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_brick_storage_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_build_counters_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_job_counter_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_clear_ref_counters_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_coarse_culling_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_compact_references_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_compress_brick_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_emit_sdf_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_free_cascade_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_initialize_cascade_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_invalidate_job_areas_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_mark_cascade_uninitialized_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_reset_cascade_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_scan_jobs_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_scan_references_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_scroll_cascade_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_cascade_ops_voxelize_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_clear_brick_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_clear_counters_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_collect_clear_bricks_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_collect_dirty_bricks_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_eikonal_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_merge_bricks_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_merge_cascades_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_prepare_clear_bricks_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_prepare_eikonal_args_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_context_ops_prepare_merge_bricks_args_pass.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_debug_draw_aabb_tree.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_debug_draw_instance_aabbs.${BRIXELIZER_SHADER_EXT}"
|
||||
"shaders/brixelizer/ffx_brixelizer_debug_visualization_pass.${BRIXELIZER_SHADER_EXT}")
|
||||
|
||||
# compile all the shaders
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${BRIXELIZER_BASE_ARGS}" "${BRIXELIZER_API_BASE_ARGS}" "" "${BRIXELIZER_INCLUDE_ARGS}"
|
||||
"${BRIXELIZER_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" BRIXELIZER_PERMUTATION_OUTPUTS)
|
||||
|
||||
# add the header files they generate to the main list of dependencies
|
||||
add_shader_output("${BRIXELIZER_PERMUTATION_OUTPUTS}")
|
||||
117
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common.h
vendored
Normal file
117
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common.h
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// 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_BRIXELIZER_BRICK_COMMON_H
|
||||
#define FFX_BRIXELIZER_BRICK_COMMON_H
|
||||
|
||||
#include "ffx_brixelizer_common.h"
|
||||
|
||||
FfxUInt32 FfxBrixelizerBrickGetIndex(FfxUInt32 brick_id)
|
||||
{
|
||||
return brick_id & FFX_BRIXELIZER_BRICK_ID_MASK;
|
||||
}
|
||||
|
||||
FfxUInt32x3 FfxBrixelizerWrapCoords(FfxInt32x3 clipmap_offset, FfxUInt32 wrap_mask, FfxUInt32x3 voxel_coord)
|
||||
{
|
||||
return (voxel_coord + FfxUInt32x3(clipmap_offset)) & FfxUInt32x3(wrap_mask, wrap_mask, wrap_mask);
|
||||
}
|
||||
|
||||
FfxUInt32x3 FfxBrixelizerWrapCoords(FfxBrixelizerCascadeInfo cinfo, FfxUInt32x3 voxel_coord)
|
||||
{
|
||||
return (voxel_coord + cinfo.clipmap_offset) & FfxUInt32x3(FFX_BRIXELIZER_CASCADE_WRAP_MASK, FFX_BRIXELIZER_CASCADE_WRAP_MASK, FFX_BRIXELIZER_CASCADE_WRAP_MASK);
|
||||
}
|
||||
|
||||
FfxUInt32 FfxBrixelizerLoadBrickIDUniform(FfxUInt32 voxel_flat_id, FfxUInt32 cascade_id)
|
||||
{
|
||||
return LoadCascadeBrickMapArrayUniform(cascade_id, voxel_flat_id);
|
||||
}
|
||||
|
||||
FfxUInt32x3 FfxBrixelizerGetSDFAtlasOffset(FfxUInt32 brick_id)
|
||||
{
|
||||
FfxUInt32 dim = 8;
|
||||
FfxUInt32 offset = FfxBrixelizerBrickGetIndex(brick_id);
|
||||
FfxUInt32 bperdim = FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / dim;
|
||||
FfxUInt32 xoffset = offset % bperdim;
|
||||
FfxUInt32 yoffset = (offset / bperdim) % bperdim;
|
||||
FfxUInt32 zoffset = (offset / bperdim / bperdim);
|
||||
return FfxUInt32x3(xoffset, yoffset, zoffset) * dim;
|
||||
}
|
||||
|
||||
struct FfxBxAtlasBounds
|
||||
{
|
||||
FfxUInt32 brick_dim;
|
||||
FfxFloat32x3 uvw_min;
|
||||
FfxFloat32x3 uvw_max;
|
||||
};
|
||||
|
||||
FfxBxAtlasBounds FfxBrixelizerGetAtlasBounds(FfxUInt32 brick_id)
|
||||
{
|
||||
FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
|
||||
FfxBxAtlasBounds bounds;
|
||||
bounds.brick_dim = FfxUInt32(8);
|
||||
bounds.uvw_min = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(0.5)) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
bounds.uvw_max = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(float(8.0 - 0.5))) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
return bounds;
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerSampleBrixelDistance(FfxUInt32 brick_id, FfxFloat32x3 uvw)
|
||||
{
|
||||
FfxUInt32 brick_dim = FfxUInt32(8);
|
||||
FfxFloat32 idim = FfxFloat32(1.0) / FfxFloat32(brick_dim);
|
||||
FfxUInt32 texture_offset = FfxBrixelizerBrickGetIndex(brick_id);
|
||||
|
||||
// Offset for 7x7x7 region
|
||||
|
||||
FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
|
||||
FfxFloat32x3 uvw_min = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(0.5)) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
FfxFloat32x3 uvw_max = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(FfxFloat32(brick_dim - FfxFloat32(0.5)))) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
uvw = ffxLerp(uvw_min, uvw_max, uvw);
|
||||
|
||||
return SampleSDFAtlas(uvw);
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerSampleBrixelDistance(FfxFloat32x3 uvw_min, FfxFloat32x3 uvw_max, FfxFloat32x3 uvw)
|
||||
{
|
||||
uvw = ffxLerp(uvw_min, uvw_max, uvw);
|
||||
return SampleSDFAtlas(uvw);
|
||||
}
|
||||
|
||||
FfxFloat32x3 FfxBrixelizerGetBrixelGrad(FfxFloat32x3 uvw_min, FfxFloat32x3 uvw_max, FfxFloat32x3 uvw) {
|
||||
FfxFloat32 EPS = FfxFloat32(0.25) / (FfxFloat32(8.0) - FfxFloat32(1.0));
|
||||
|
||||
FfxFloat32x4 k = FfxFloat32x4(1.0, 1.0, 1.0, 0.0);
|
||||
if (uvw.x > FfxFloat32(0.5)) k.x = -k.x;
|
||||
if (uvw.y > FfxFloat32(0.5)) k.y = -k.y;
|
||||
if (uvw.z > FfxFloat32(0.5)) k.z = -k.z;
|
||||
FfxFloat32 fcenter = FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw);
|
||||
FfxFloat32x3 grad = normalize(
|
||||
k.xww * (FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw + k.xww * EPS) - fcenter) +
|
||||
k.wyw * (FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw + k.wyw * EPS) - fcenter) +
|
||||
k.wwz * (FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw + k.wwz * EPS) - fcenter)
|
||||
);
|
||||
if (any(isnan(grad))) {
|
||||
return normalize(uvw - FFX_BROADCAST_FLOAT32X3(0.5));
|
||||
}
|
||||
return grad;
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_BRICK_COMMON_H
|
||||
58
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common_private.h
vendored
Normal file
58
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_brick_common_private.h
vendored
Normal 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_BRIXELIZER_BRICK_COMMON_PRIVATE_H
|
||||
#define FFX_BRIXELIZER_BRICK_COMMON_PRIVATE_H
|
||||
|
||||
#include "ffx_brixelizer_common_private.h"
|
||||
#include "ffx_brixelizer_brick_common.h"
|
||||
|
||||
FfxUInt32 FfxBrixelizerVoxelGetIndex(FfxUInt32 voxel_id)
|
||||
{
|
||||
return voxel_id & FFX_BRIXELIZER_VOXEL_ID_MASK;
|
||||
}
|
||||
|
||||
FfxUInt32 FfxBrixelizerGetVoxelCascade(FfxUInt32 voxel_id)
|
||||
{
|
||||
return voxel_id >> FFX_BRIXELIZER_CASCADE_ID_SHIFT;
|
||||
}
|
||||
|
||||
FfxUInt32 WrapFlatCoords(FfxBrixelizerCascadeInfo CINFO, FfxUInt32 voxel_idx)
|
||||
{
|
||||
return FfxBrixelizerFlattenPOT((FfxBrixelizerUnflattenPOT(voxel_idx, FFX_BRIXELIZER_CASCADE_DEGREE) + CINFO.clipmap_offset) & FFX_BROADCAST_UINT32X3(FFX_BRIXELIZER_CASCADE_WRAP_MASK), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
}
|
||||
|
||||
FfxUInt32 FfxBrixelizerMakeBrickID(FfxUInt32 offset)
|
||||
{
|
||||
return offset;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FfxBrixelizerGetBrixelGrad(FfxUInt32 brick_id, FfxFloat32x3 uvw)
|
||||
{
|
||||
FfxFloat32 EPS = FfxFloat32(0.1) / (FfxFloat32(8.0) - FfxFloat32(1.0));
|
||||
FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
|
||||
FfxFloat32x3 uvw_min = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(0.5)) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
FfxFloat32x3 uvw_max = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(float(8.0 - float(0.5)))) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
return FfxBrixelizerGetBrixelGrad(uvw_min, uvw_max, uvw);
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_BRICK_COMMON_PRIVATE_H
|
||||
39
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_build_common.h
vendored
Normal file
39
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_build_common.h
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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_BRIXELIZER_BUILD_COMMON_H
|
||||
#define FFX_BRIXELIZER_BUILD_COMMON_H
|
||||
|
||||
#include "ffx_brixelizer_common_private.h"
|
||||
|
||||
void FfxBrixelizerMarkBrickFree(FfxUInt32 brick_id)
|
||||
{
|
||||
StoreBricksVoxelMap(FfxBrixelizerBrickGetIndex(brick_id), FFX_BRIXELIZER_INVALID_ID);
|
||||
}
|
||||
|
||||
FfxUInt32 FfxBrixelizerLoadBrickVoxelID(FfxUInt32 brick_id)
|
||||
{
|
||||
return LoadBricksVoxelMap(FfxBrixelizerBrickGetIndex(brick_id));
|
||||
}
|
||||
// FfxUInt32 FfxBrixelizerLoadBrickCascadeID(FfxUInt32 brick_id) { return LoadBricksVoxelMap(FfxBrixelizerBrickGetIndex(brick_id)) >> FFX_BRIXELIZER_CASCADE_ID_SHIFT; }
|
||||
|
||||
#endif // FFX_BRIXELIZER_BUILD_COMMON_H
|
||||
1287
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_glsl.h
vendored
Normal file
1287
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_glsl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1188
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_hlsl.h
vendored
Normal file
1188
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_callbacks_hlsl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1477
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_cascade_ops.h
vendored
Normal file
1477
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_cascade_ops.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_common.h
vendored
Normal file
103
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_common.h
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
// 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_BRIXELIZER_COMMON_H
|
||||
#define FFX_BRIXELIZER_COMMON_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
#include "ffx_brixelizer_host_gpu_shared.h"
|
||||
|
||||
#define ffxassert(x)
|
||||
|
||||
FfxBoolean FfxBrixelizerIsValidID(FfxUInt32 id)
|
||||
{
|
||||
return (id & FFX_BRIXELIZER_INVALID_ID) != FFX_BRIXELIZER_INVALID_ID;
|
||||
}
|
||||
|
||||
FfxBoolean FfxBrixelizerIntersectAABB(FfxFloat32x3 ray_origin, FfxFloat32x3 ray_invdir, FfxFloat32x3 box_min, FfxFloat32x3 box_max, FFX_PARAMETER_OUT FfxFloat32 hit_min, FFX_PARAMETER_OUT FfxFloat32 hit_max)
|
||||
{
|
||||
FfxFloat32x3 tbot = ray_invdir * (box_min - ray_origin);
|
||||
FfxFloat32x3 ttop = ray_invdir * (box_max - ray_origin);
|
||||
FfxFloat32x3 tmin = min(ttop, tbot);
|
||||
FfxFloat32x3 tmax = max(ttop, tbot);
|
||||
FfxFloat32x2 t = max(tmin.xx, tmin.yz);
|
||||
FfxFloat32 t0 = max(t.x, t.y);
|
||||
t = min(tmax.xx, tmax.yz);
|
||||
FfxFloat32 t1 = min(t.x, t.y);
|
||||
hit_min = max(t0, FfxFloat32(0.0));
|
||||
hit_max = max(t1, FfxFloat32(0.0));
|
||||
return hit_max > hit_min;
|
||||
}
|
||||
|
||||
FfxUInt32 FfxBrixelizerFlattenPOT(FfxUInt32x3 voxel_coord, FfxUInt32 degree)
|
||||
{
|
||||
return voxel_coord.x | (voxel_coord.y << degree) | (voxel_coord.z << (2 * degree));
|
||||
}
|
||||
|
||||
FfxUInt32x3 FfxBrixelizerUnflattenPOT(FfxUInt32 flat_bx_coord, FfxUInt32 degree)
|
||||
{
|
||||
return FfxUInt32x3(flat_bx_coord & ((FfxUInt32(1) << degree) - 1), (flat_bx_coord >> degree) & ((FfxUInt32(1) << degree) - 1), flat_bx_coord >> (2 * degree));
|
||||
}
|
||||
|
||||
FfxUInt32 FfxBrixelizerPackUnsigned8Bits(FfxFloat32 a)
|
||||
{
|
||||
return FfxUInt32(ffxSaturate(a) * FfxFloat32(255.0)) & 0xffu;
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerUnpackUnsigned8Bits(FfxUInt32 uval)
|
||||
{
|
||||
return FfxFloat32(uval & 0xff) / FfxFloat32(255.0);
|
||||
}
|
||||
|
||||
FfxUInt32 PackUVWC(FfxFloat32x4 uvwc)
|
||||
{
|
||||
FfxUInt32 pack = //
|
||||
(FfxBrixelizerPackUnsigned8Bits(uvwc.x) << 0) //
|
||||
| (FfxBrixelizerPackUnsigned8Bits(uvwc.y) << 8) //
|
||||
| (FfxBrixelizerPackUnsigned8Bits(uvwc.z) << 16) //
|
||||
| (FfxBrixelizerPackUnsigned8Bits(uvwc.w) << 24); //
|
||||
return pack;
|
||||
}
|
||||
|
||||
FfxFloat32x2 FfxBrixelizerOctahedronToUV(FfxFloat32x3 N)
|
||||
{
|
||||
N.xy = FfxFloat32x2(N.xy) / dot(FFX_BROADCAST_FLOAT32X3(1.0), abs(N));
|
||||
FfxFloat32x2 k;
|
||||
k.x = N.x >= float(0.0) ? float(1.0) : -float(1.0);
|
||||
k.y = N.y >= float(0.0) ? float(1.0) : -float(1.0);
|
||||
if (N.z <= float(0.0)) N.xy = (float(1.0) - abs(FfxFloat32x2(N.yx))) * k;
|
||||
return N.xy * float(0.5) + float(0.5);
|
||||
}
|
||||
|
||||
FfxFloat32x3 FfxBrixelizerUVToOctahedron(FfxFloat32x2 UV)
|
||||
{
|
||||
UV = float(2.0) * (UV - float(0.5));
|
||||
FfxFloat32x3 N = FfxFloat32x3(UV, float(1.0) - abs(UV.x) - abs(UV.y));
|
||||
float t = max(-N.z, float(0.0));
|
||||
FfxFloat32x2 k;
|
||||
k.x = N.x >= float(0.0) ? -t : t;
|
||||
k.y = N.y >= float(0.0) ? -t : t;
|
||||
N.xy += k;
|
||||
return normalize(N);
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_COMMON_H
|
||||
243
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_common_private.h
vendored
Normal file
243
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_common_private.h
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
// 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_BRIXELIZER_COMMON_PRIVATE_H
|
||||
#define FFX_BRIXELIZER_COMMON_PRIVATE_H
|
||||
|
||||
#include "ffx_brixelizer_common.h"
|
||||
#include "ffx_brixelizer_host_gpu_shared_private.h"
|
||||
|
||||
FfxInt32x3 to_int3(FfxUInt32x3 a) { return FfxInt32x3(FfxInt32(a.x), FfxInt32(a.y), FfxInt32(a.z)); }
|
||||
FfxFloat32x3 to_float3(FfxUInt32x3 a) { return FfxFloat32x3(FfxFloat32(a.x), FfxFloat32(a.y), FfxFloat32(a.z)); }
|
||||
FfxFloat32x3 to_float3(FfxInt32x3 a) { return FfxFloat32x3(FfxFloat32(a.x), FfxFloat32(a.y), FfxFloat32(a.z)); }
|
||||
|
||||
FfxUInt32 FfxBrixelizerPackDistance(FfxFloat32 distance)
|
||||
{
|
||||
FfxUInt32 uval = ffxAsUInt32(distance);
|
||||
FfxUInt32 sign_bit = uval >> FfxUInt32(31);
|
||||
return (uval << 1) | sign_bit;
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerUnpackDistance(FfxUInt32 uval)
|
||||
{
|
||||
FfxUInt32 sign_bit = (uval & 1);
|
||||
return ffxAsFloat((uval >> FfxUInt32(1)) | (sign_bit << FfxUInt32(31)));
|
||||
}
|
||||
|
||||
// Returns the minimal absolute value with its sign unchanged
|
||||
FfxFloat32 FfxBrixelizerUnsignedMin(FfxFloat32 a, FfxFloat32 b) { return abs(a) < abs(b) ? a : b; }
|
||||
// sign without zero
|
||||
FfxFloat32 FfxBrixelizerGetSign(FfxFloat32 v) { return v < FfxFloat32(0.0) ? -FfxFloat32(1.0) : FfxFloat32(1.0); }
|
||||
|
||||
FfxFloat32 dot2(FfxFloat32x3 v) { return dot(v, v); }
|
||||
FfxFloat32 dot2(FfxFloat32x2 v) { return dot(v, v); }
|
||||
|
||||
// https://www.shadertoy.com/view/4sXXRN
|
||||
// The MIT License
|
||||
// Copyright © 2014 Inigo Quilez
|
||||
// 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.
|
||||
//
|
||||
// It computes the distance to a triangle.
|
||||
//
|
||||
// See here: http://iquilezles.org/www/articles/triangledistance/triangledistance.htm
|
||||
//
|
||||
// In case a mesh was rendered, only one square root would be needed for the
|
||||
// whole mesh. In this example the triangle is given a thckness of 0.01 units
|
||||
// for display purposes. Like the square root, this thickness should be added
|
||||
// only once for the whole mesh too.
|
||||
FfxFloat32 CalculateDistanceToTriangle(FfxFloat32x3 p, FfxFloat32x3 a, FfxFloat32x3 b, FfxFloat32x3 c) {
|
||||
FfxFloat32x3 ba = b - a;
|
||||
FfxFloat32x3 pa = p - a;
|
||||
FfxFloat32x3 cb = c - b;
|
||||
FfxFloat32x3 pb = p - b;
|
||||
FfxFloat32x3 ac = a - c;
|
||||
FfxFloat32x3 pc = p - c;
|
||||
FfxFloat32x3 nor = cross(ba, ac);
|
||||
|
||||
return sqrt( //
|
||||
(sign(dot(cross(ba, nor), pa)) + //
|
||||
sign(dot(cross(cb, nor), pb)) + //
|
||||
sign(dot(cross(ac, nor), pc)) < //
|
||||
FfxFloat32(2.0)) //
|
||||
? //
|
||||
min(min( //
|
||||
dot2(ba * ffxSaturate(dot(ba, pa) / dot2(ba)) - pa), //
|
||||
dot2(cb * ffxSaturate(dot(cb, pb) / dot2(cb)) - pb)), //
|
||||
dot2(ac * ffxSaturate(dot(ac, pc) / dot2(ac)) - pc)) //
|
||||
: //
|
||||
dot(nor, pa) * dot(nor, pa) / dot2(nor) //
|
||||
); //
|
||||
}
|
||||
|
||||
FfxFloat32 CalculateDistanceToTriangleSquared(FfxFloat32x3 ba, //
|
||||
FfxFloat32x3 pa, //
|
||||
FfxFloat32x3 cb, //
|
||||
FfxFloat32x3 pb, //
|
||||
FfxFloat32x3 ac, //
|
||||
FfxFloat32x3 pc, //
|
||||
FfxFloat32x3 nor, //
|
||||
FfxFloat32x3 cross_ba_nor, //
|
||||
FfxFloat32x3 cross_cb_nor, //
|
||||
FfxFloat32x3 cross_ac_nor, //
|
||||
FfxFloat32 dot2_ba, //
|
||||
FfxFloat32 dot2_cb, //
|
||||
FfxFloat32 dot2_ac, //
|
||||
FfxFloat32 dot2_nor //
|
||||
) {
|
||||
return //
|
||||
( //
|
||||
(sign(dot(cross_ba_nor, pa)) + //
|
||||
sign(dot(cross_cb_nor, pb)) + //
|
||||
sign(dot(cross_ac_nor, pc)) < //
|
||||
FfxFloat32(2.0)) //
|
||||
? //
|
||||
min(min( //
|
||||
dot2(ba * ffxSaturate(dot(ba, pa) / dot2_ba) - pa), //
|
||||
dot2(cb * ffxSaturate(dot(cb, pb) / dot2_cb) - pb)), //
|
||||
dot2(ac * ffxSaturate(dot(ac, pc) / dot2_ac) - pc)) //
|
||||
: //
|
||||
dot(nor, pa) * dot(nor, pa) / dot2_nor //
|
||||
); //
|
||||
}
|
||||
|
||||
#define brixelizerreal FfxFloat32
|
||||
#define brixelizerreal2 FfxFloat32x2
|
||||
#define brixelizerreal3 FfxFloat32x3
|
||||
#define brixelizerreal4 FfxFloat32x4
|
||||
|
||||
#ifdef FFX_HLSL
|
||||
# define brixelizerreal3x2 float3x2
|
||||
#else
|
||||
# define brixelizerreal3x2 mat3x2
|
||||
#endif
|
||||
|
||||
brixelizerreal3 to_brixelizerreal3(FfxUInt32x3 a) { return brixelizerreal3(brixelizerreal(a.x), brixelizerreal(a.y), brixelizerreal(a.z)); }
|
||||
|
||||
// Offsets the plane equation for the nearest grid point
|
||||
brixelizerreal FfxBrixelizerOffsetByMax(brixelizerreal de, brixelizerreal2 ne, brixelizerreal offset)
|
||||
{
|
||||
de += max(FfxFloat32(0.0), ne.x) + abs(ne.x * offset);
|
||||
de += max(FfxFloat32(0.0), ne.y) + abs(ne.y * offset);
|
||||
return de;
|
||||
}
|
||||
|
||||
// Offsets the plane equation for the next grid point
|
||||
brixelizerreal FfxBrixelizerOffsetByMin(brixelizerreal de, brixelizerreal2 ne, brixelizerreal offset)
|
||||
{
|
||||
de += min(FfxFloat32(0.0), ne.x) - abs(ne.x * offset);
|
||||
de += min(FfxFloat32(0.0), ne.y) - abs(ne.x * offset);
|
||||
return de;
|
||||
}
|
||||
|
||||
void FfxBrixelizerGet2DEdge(FFX_PARAMETER_OUT brixelizerreal2 ne,
|
||||
FFX_PARAMETER_OUT brixelizerreal de,
|
||||
brixelizerreal orientation,
|
||||
brixelizerreal edge_x,
|
||||
brixelizerreal edge_y,
|
||||
brixelizerreal vertex_x,
|
||||
brixelizerreal vertex_y,
|
||||
brixelizerreal offset)
|
||||
{
|
||||
ne = brixelizerreal2(-orientation * edge_y, orientation * edge_x);
|
||||
de = -(ne.x * vertex_x + ne.y * vertex_y);
|
||||
de = FfxBrixelizerOffsetByMax(de, ne, offset);
|
||||
}
|
||||
|
||||
void FfxBrixelizerGet2DEdges(
|
||||
FFX_PARAMETER_OUT brixelizerreal3 de_xy,
|
||||
FFX_PARAMETER_OUT brixelizerreal3x2 ne_xy,
|
||||
FFX_PARAMETER_OUT brixelizerreal3 de_xz,
|
||||
FFX_PARAMETER_OUT brixelizerreal3x2 ne_xz,
|
||||
FFX_PARAMETER_OUT brixelizerreal3 de_yz,
|
||||
FFX_PARAMETER_OUT brixelizerreal3x2 ne_yz,
|
||||
FFX_PARAMETER_OUT brixelizerreal3 gn,
|
||||
brixelizerreal3 TRIANGLE_VERTEX_0,
|
||||
brixelizerreal3 TRIANGLE_VERTEX_1,
|
||||
brixelizerreal3 TRIANGLE_VERTEX_2,
|
||||
brixelizerreal offset,
|
||||
bool invert)
|
||||
{
|
||||
brixelizerreal3 e0 = TRIANGLE_VERTEX_1.xyz - TRIANGLE_VERTEX_0.xyz;
|
||||
brixelizerreal3 e1 = TRIANGLE_VERTEX_2.xyz - TRIANGLE_VERTEX_1.xyz;
|
||||
brixelizerreal3 e2 = TRIANGLE_VERTEX_0.xyz - TRIANGLE_VERTEX_2.xyz;
|
||||
if (invert) {
|
||||
e0 = -e0;
|
||||
e1 = -e1;
|
||||
e2 = -e2;
|
||||
}
|
||||
|
||||
gn = normalize(cross(e2, e0));
|
||||
|
||||
brixelizerreal orientation_xy = brixelizerreal(gn.z < FfxFloat32(0.0) ? -FfxFloat32(1.0) : FfxFloat32(1.0));
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_xy[0], /* out */ de_xy[0], orientation_xy, e0.x, e0.y, TRIANGLE_VERTEX_0.x, TRIANGLE_VERTEX_0.y, offset);
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_xy[1], /* out */ de_xy[1], orientation_xy, e1.x, e1.y, TRIANGLE_VERTEX_1.x, TRIANGLE_VERTEX_1.y, offset);
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_xy[2], /* out */ de_xy[2], orientation_xy, e2.x, e2.y, TRIANGLE_VERTEX_2.x, TRIANGLE_VERTEX_2.y, offset);
|
||||
brixelizerreal orientation_xz = brixelizerreal(gn.y > FfxFloat32(0.0) ? -FfxFloat32(1.0) : FfxFloat32(1.0));
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_xz[0], /* out */ de_xz[0], orientation_xz, e0.x, e0.z, TRIANGLE_VERTEX_0.x, TRIANGLE_VERTEX_0.z, offset);
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_xz[1], /* out */ de_xz[1], orientation_xz, e1.x, e1.z, TRIANGLE_VERTEX_1.x, TRIANGLE_VERTEX_1.z, offset);
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_xz[2], /* out */ de_xz[2], orientation_xz, e2.x, e2.z, TRIANGLE_VERTEX_2.x, TRIANGLE_VERTEX_2.z, offset);
|
||||
brixelizerreal orientation_yz = brixelizerreal(gn.x < FfxFloat32(0.0) ? -FfxFloat32(1.0) : FfxFloat32(1.0));
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_yz[0], /* out */ de_yz[0], orientation_yz, e0.y, e0.z, TRIANGLE_VERTEX_0.y, TRIANGLE_VERTEX_0.z, offset);
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_yz[1], /* out */ de_yz[1], orientation_yz, e1.y, e1.z, TRIANGLE_VERTEX_1.y, TRIANGLE_VERTEX_1.z, offset);
|
||||
FfxBrixelizerGet2DEdge(/* out */ ne_yz[2], /* out */ de_yz[2], orientation_yz, e2.y, e2.z, TRIANGLE_VERTEX_2.y, TRIANGLE_VERTEX_2.z, offset);
|
||||
}
|
||||
|
||||
bool FfxBrixelizerEvalEdge(brixelizerreal2 vertex, brixelizerreal3 de, brixelizerreal3x2 ne)
|
||||
{
|
||||
return (ne[0].x * vertex.x + ne[0].y * vertex.y + de[0] >= brixelizerreal(FfxFloat32(0.0))) &&
|
||||
(ne[1].x * vertex.x + ne[1].y * vertex.y + de[1] >= brixelizerreal(FfxFloat32(0.0))) &&
|
||||
(ne[2].x * vertex.x + ne[2].y * vertex.y + de[2] >= brixelizerreal(FfxFloat32(0.0)));
|
||||
}
|
||||
|
||||
// We need those non-POT versions around for culling
|
||||
FfxUInt32x3 FfxBrixelizerUnflatten(FfxUInt32 flat_bx_coord, FfxUInt32x3 dim)
|
||||
{
|
||||
return FfxUInt32x3(flat_bx_coord % dim.x, (flat_bx_coord / dim.x) % dim.y, flat_bx_coord / (dim.x * dim.y));
|
||||
}
|
||||
|
||||
FfxUInt32x2 FfxBrixelizerUnflatten(FfxUInt32 flat_bx_coord, FfxUInt32x2 dim)
|
||||
{
|
||||
return FfxUInt32x2(flat_bx_coord % dim.x, (flat_bx_coord / dim.x) % dim.y);
|
||||
}
|
||||
|
||||
FfxUInt32 FfxBrixelizerFlatten(FfxUInt32x3 voxel_coord, FfxUInt32x3 dim)
|
||||
{
|
||||
return voxel_coord.x + voxel_coord.y * dim.x + voxel_coord.z * dim.x * dim.y;
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_COMMON_PRIVATE_H
|
||||
306
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_context_ops.h
vendored
Normal file
306
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_context_ops.h
vendored
Normal file
@@ -0,0 +1,306 @@
|
||||
// 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_BRIXELIZER_CONTEXT_OPS_H
|
||||
#define FFX_BRIXELIZER_CONTEXT_OPS_H
|
||||
|
||||
#include "ffx_brixelizer_host_gpu_shared_private.h"
|
||||
#include "ffx_brixelizer_brick_common_private.h"
|
||||
#include "ffx_brixelizer_build_common.h"
|
||||
#include "ffx_brixelizer_common_private.h"
|
||||
|
||||
void FfxBrixelizerAppendClearBrick(FfxUInt32 brick_id)
|
||||
{
|
||||
FfxUInt32 offset;
|
||||
IncrementContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_CLEAR_BRICKS, FfxUInt32(1), offset);
|
||||
StoreBricksClearList(offset, brick_id);
|
||||
}
|
||||
|
||||
void FfxBrixelizerAppendDirtyBrick(FfxUInt32 brick_id)
|
||||
{
|
||||
FfxUInt32 offset;
|
||||
IncrementContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_DIRTY_BRICKS, FfxUInt32(1), offset);
|
||||
StoreBricksDirtyList(offset, brick_id);
|
||||
}
|
||||
|
||||
void FfxBrixelizerClearCounters()
|
||||
{
|
||||
for (FfxUInt32 i = 0; i < FFX_BRIXELIZER_NUM_CONTEXT_COUNTERS; i++) {
|
||||
StoreContextCounter(i, FfxUInt32(0));
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerAddBrickToFreeList(FfxUInt32 brick_id)
|
||||
{
|
||||
FfxUInt32 offset;
|
||||
IncrementContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_FREE_BRICKS, FfxUInt32(1), offset);
|
||||
StoreBricksFreeList(offset, brick_id);
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerLoadBrixelDist(FfxUInt32 brick_id, FfxInt32x3 coord)
|
||||
{
|
||||
if (any(FFX_GREATER_THAN(coord, FFX_BROADCAST_INT32X3(7))) || any(FFX_LESS_THAN(coord, FFX_BROADCAST_INT32X3(0)))) return FfxFloat32(1.0);
|
||||
return LoadSDFAtlas(FfxBrixelizerGetSDFAtlasOffset(brick_id) + coord);
|
||||
}
|
||||
|
||||
void FfxBrixelizerStoreBrixelDist(FfxUInt32 brick_id, FfxUInt32x3 coord, FfxFloat32 dist)
|
||||
{
|
||||
StoreSDFAtlas(FfxBrixelizerGetSDFAtlasOffset(brick_id) + coord, clamp(dist, FfxFloat32(0.0), FfxFloat32(1.0)));
|
||||
}
|
||||
|
||||
void FfxBrixelizerClearBrick(FfxUInt32 brick_id, FfxUInt32x3 voxel_coord)
|
||||
{
|
||||
FfxBrixelizerStoreBrixelDist(brick_id, voxel_coord, FfxFloat32(1.0));
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerEikonalMin(FfxFloat32 a, FfxFloat32 b)
|
||||
{
|
||||
return FfxBrixelizerUnsignedMin(a, b);
|
||||
}
|
||||
|
||||
// Eikonal solver, enforce |gradient|==d
|
||||
// Generic form for n dimensions:
|
||||
// U = 1/n * (sum(U_i) + sqrt(sum(U_i) * sum(U_i) - n * (sum(U_i * U_i) - D)))
|
||||
// when sqrt is non real then fall back to min of lower dimensions
|
||||
FfxFloat32 FfxBrixelizerEikonal1D(FfxFloat32 x, FfxFloat32 y, FfxFloat32 z, FfxFloat32 d)
|
||||
{
|
||||
FfxFloat32 xyz = FfxBrixelizerEikonalMin(x, FfxBrixelizerEikonalMin(y, z));
|
||||
return (xyz + d * FfxBrixelizerGetSign(xyz));
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerEikonal2D(FfxFloat32 x, FfxFloat32 y, FfxFloat32 d)
|
||||
{
|
||||
const FfxFloat32 k = FfxFloat32(1.0) / FfxFloat32(2.0);
|
||||
FfxFloat32 xy = x + y;
|
||||
FfxFloat32 v = xy * xy - FfxFloat32(2.0) * (x * x + y * y - d * d);
|
||||
if (v < FfxFloat32(0.0)) return FfxFloat32(1.0);
|
||||
return k * (xy + sqrt(v) * FfxBrixelizerGetSign(xy));
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerEikonal3D(FfxFloat32 x, FfxFloat32 y, FfxFloat32 z, FfxFloat32 d)
|
||||
{
|
||||
const FfxFloat32 k = FfxFloat32(1.0) / FfxFloat32(3.0);
|
||||
FfxFloat32 xyz = x + y + z;
|
||||
FfxFloat32 v = xyz * xyz - FfxFloat32(3.0) * (x * x + y * y + z * z - d * d);
|
||||
if (v < FfxFloat32(0.0)) return FfxFloat32(1.0);
|
||||
return k * (xyz + sqrt(v) * FfxBrixelizerGetSign(xyz));
|
||||
}
|
||||
|
||||
FFX_GROUPSHARED FfxFloat32 lds_eikonal_sdf_cache[512];
|
||||
FfxFloat32 FfxBrixelizerLDSLoadSDF(FfxInt32x3 coord)
|
||||
{
|
||||
if (any(FFX_LESS_THAN(coord, FFX_BROADCAST_INT32X3(0))) || any(FFX_GREATER_THAN(coord, FFX_BROADCAST_INT32X3(7)))) return FfxFloat32(1.0);
|
||||
return lds_eikonal_sdf_cache[FfxUInt32(coord.x) + FfxUInt32(coord.y) * FfxUInt32(8) + FfxUInt32(coord.z) * FfxUInt32(8 * 8)];
|
||||
}
|
||||
|
||||
void FfxBrixelizerLDSStoreSDF(FfxInt32x3 coord, FfxFloat32 sdf)
|
||||
{
|
||||
lds_eikonal_sdf_cache[FfxUInt32(coord.x) + FfxUInt32(coord.y) * FfxUInt32(8) + FfxUInt32(coord.z) * FfxUInt32(8 * 8)] = sdf;
|
||||
}
|
||||
|
||||
// Collects a list of bricks to clear for indirect args
|
||||
// those don't have a brick_id->voxel_id mapping are considered free
|
||||
// those that got eikonal counter are considered dirty as they had something baked in them
|
||||
// DEFINE_ENTRY(64, 1, 1, CollectClearBricks)
|
||||
void FfxBrixelizerCollectClearBricks(FfxUInt32 brick_offset)
|
||||
{
|
||||
if (brick_offset >= GetContextInfoNumBricks()) return;
|
||||
|
||||
FfxUInt32 brick_id = FfxBrixelizerMakeBrickID(brick_offset);
|
||||
FfxUInt32 dim = 8;
|
||||
FfxUInt32 voxel_id = FfxBrixelizerLoadBrickVoxelID(brick_id);
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerVoxelGetIndex(voxel_id);
|
||||
FfxUInt32 cascade_id = FfxBrixelizerGetVoxelCascade(voxel_id);
|
||||
FfxUInt32 eikonal_counter = LoadBricksEikonalCounters(brick_id);
|
||||
|
||||
// @TODO cleanup this mess
|
||||
if (GetBuildInfoDoInitialization() > 0) {
|
||||
StoreBricksEikonalCounters(brick_id, 0);
|
||||
FfxBrixelizerMarkBrickFree(brick_id);
|
||||
FfxBrixelizerAddBrickToFreeList(brick_id);
|
||||
FfxBrixelizerAppendClearBrick(brick_id);
|
||||
} else {
|
||||
#ifdef FFX_BRIXELIZER_DEBUG_FORCE_REBUILD
|
||||
StoreBricksEikonalCounters(brick_id, 0);
|
||||
FfxBrixelizerMarkBrickFree(brick_id);
|
||||
FfxBrixelizerAddBrickToFreeList(brick_id);
|
||||
FfxBrixelizerAppendClearBrick(brick_id);
|
||||
|
||||
#else // !FFX_BRIXELIZER_DEBUG_FORCE_REBUILD
|
||||
|
||||
if (FfxBrixelizerIsInvalidID(voxel_id)) {
|
||||
FfxBrixelizerAddBrickToFreeList(brick_id);
|
||||
if (eikonal_counter > 0) { // Means there's been some baking using this brick so need to clear
|
||||
FfxBrixelizerAppendClearBrick(brick_id);
|
||||
StoreBricksEikonalCounters(brick_id, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !FFX_BRIXELIZER_DEBUG_FORCE_REBUILD
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerPrepareClearBricks()
|
||||
{
|
||||
FfxUInt32 tier_cnt = LoadContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_CLEAR_BRICKS);
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_CLEAR_BRICKS_32 + FfxUInt32(0), tier_cnt * FfxUInt32(1 << (3)));
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_CLEAR_BRICKS_32 + FfxUInt32(1), FfxUInt32(1));
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_CLEAR_BRICKS_32 + FfxUInt32(2), FfxUInt32(1));
|
||||
}
|
||||
|
||||
void FfxBrixelizerClearBrickEntry(FfxUInt32 gtid, FfxUInt32 group_id)
|
||||
{
|
||||
FfxUInt32 brick_offset = group_id.x >> (3);
|
||||
FfxUInt32 stamp_id = group_id.x & ((1 << (3)) - 1);
|
||||
FfxUInt32 brick_id = LoadBricksClearList(brick_offset);
|
||||
FfxUInt32 brick_dim = 8;
|
||||
FfxUInt32x3 local_coord = FfxBrixelizerUnflattenPOT(gtid, 2) + FfxBrixelizerUnflattenPOT(stamp_id, 1) * FfxUInt32(4);
|
||||
|
||||
FfxBrixelizerClearBrick(brick_id, local_coord);
|
||||
}
|
||||
|
||||
void FfxBrixelizerCollectDirtyBricks(FfxUInt32 brick_offset)
|
||||
{
|
||||
FfxUInt32 brick_id = FfxBrixelizerMakeBrickID(brick_offset);
|
||||
FfxUInt32 eikonal_counter = LoadBricksEikonalCounters(brick_id);
|
||||
FfxUInt32 dim = 8;
|
||||
FfxUInt32 voxel_id = FfxBrixelizerLoadBrickVoxelID(brick_id);
|
||||
|
||||
if (FfxBrixelizerIsValidID(voxel_id)) {
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerVoxelGetIndex(voxel_id);
|
||||
FfxUInt32 cascade_idx = FfxBrixelizerGetVoxelCascade(voxel_id);
|
||||
FfxUInt32x3 clipmap_offset = GetContextInfoCascadeClipmapOffset(cascade_idx);
|
||||
FfxUInt32x3 voxel_offset = FfxBrixelizerUnflattenPOT(voxel_idx, FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
FfxUInt32 wrapped_voxel_idx = FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(FfxInt32x3(clipmap_offset), FFX_BRIXELIZER_CASCADE_WRAP_MASK, voxel_offset), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
if (eikonal_counter < 16) {
|
||||
FfxBrixelizerAppendDirtyBrick(brick_id);
|
||||
StoreBricksEikonalCounters(brick_id, eikonal_counter + 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DEFINE_ENTRY(512, 1, 1, Eikonal)
|
||||
void FfxBrixelizerEikonal(FfxUInt32 local_coord_packed, FfxUInt32 brick_offset)
|
||||
{
|
||||
FfxUInt32 brick_id = LoadBricksDirtyList(brick_offset);
|
||||
FfxUInt32 voxel_id = FfxBrixelizerLoadBrickVoxelID(brick_id);
|
||||
FfxUInt32x3 local_coord = FfxBrixelizerUnflattenPOT(local_coord_packed, 3);
|
||||
if (FfxBrixelizerIsValidID(voxel_id)) {
|
||||
FfxFloat32 cell_distance = FfxFloat32(1.0) / (FfxFloat32(8));
|
||||
FfxFloat32 e = FfxBrixelizerLoadBrixelDist(brick_id, FfxInt32x3(local_coord));
|
||||
|
||||
FfxBrixelizerLDSStoreSDF(FfxInt32x3(local_coord), e);
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
for (FfxUInt32 j = FfxUInt32(0); j < FfxUInt32(3); j++) {
|
||||
for (FfxUInt32 i = FfxUInt32(0); i < FfxUInt32(4); i++) {
|
||||
FfxUInt32 d = FfxUInt32(1) << (FfxUInt32(3) - i);
|
||||
FfxFloat32x3 min_dists = FFX_BROADCAST_FLOAT32X3(FfxFloat32(1.0));
|
||||
min_dists.x = FfxBrixelizerEikonalMin(FfxBrixelizerLDSLoadSDF(FfxInt32x3(local_coord) + FfxInt32x3(d, 0, 0)), FfxBrixelizerLDSLoadSDF(FfxInt32x3(local_coord) + FfxInt32x3(-d, 0, 0)));
|
||||
min_dists.y = FfxBrixelizerEikonalMin(FfxBrixelizerLDSLoadSDF(FfxInt32x3(local_coord) + FfxInt32x3(0, d, 0)), FfxBrixelizerLDSLoadSDF(FfxInt32x3(local_coord) + FfxInt32x3(0, -d, 0)));
|
||||
min_dists.z = FfxBrixelizerEikonalMin(FfxBrixelizerLDSLoadSDF(FfxInt32x3(local_coord) + FfxInt32x3(0, 0, d)), FfxBrixelizerLDSLoadSDF(FfxInt32x3(local_coord) + FfxInt32x3(0, 0, -d)));
|
||||
min_dists = abs(min_dists);
|
||||
FfxFloat32 e10 = FfxBrixelizerEikonal1D(min_dists.x, min_dists.y, min_dists.z, d * cell_distance);
|
||||
FfxFloat32 e20 = FfxBrixelizerEikonal2D(min_dists.x, min_dists.y, d * cell_distance);
|
||||
FfxFloat32 e21 = FfxBrixelizerEikonal2D(min_dists.x, min_dists.z, d * cell_distance);
|
||||
FfxFloat32 e22 = FfxBrixelizerEikonal2D(min_dists.z, min_dists.y, d * cell_distance);
|
||||
FfxFloat32 e30 = FfxBrixelizerEikonal3D(min_dists.x, min_dists.y, min_dists.z, d * cell_distance);
|
||||
e = FfxBrixelizerEikonalMin(e, FfxBrixelizerEikonalMin(e10, FfxBrixelizerEikonalMin(e20, FfxBrixelizerEikonalMin(e21, FfxBrixelizerEikonalMin(e22, e30)))));
|
||||
e = FfxBrixelizerEikonalMin(e, e10);
|
||||
FfxBrixelizerLDSStoreSDF(FfxInt32x3(local_coord), e);
|
||||
}
|
||||
}
|
||||
|
||||
FfxBrixelizerStoreBrixelDist(brick_id, local_coord, e);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerMergeBricks(FfxUInt32 gtid, FfxUInt32 group_id)
|
||||
{
|
||||
FfxUInt32 cnt = LoadContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_MERGE_BRICKS);
|
||||
FfxUInt32 merge_idx = group_id / FfxUInt32(8);
|
||||
FfxUInt32 stamp_idx = group_id % FfxUInt32(8);
|
||||
FfxUInt32 voxel_idx = gtid + stamp_idx * FfxUInt32(64);
|
||||
FfxUInt32x3 voxel_offset = FfxBrixelizerUnflattenPOT(voxel_idx, FfxUInt32(3));
|
||||
if (merge_idx >= cnt) return;
|
||||
FfxUInt32 brick_A = LoadBricksMergeList(merge_idx * FfxUInt32(2) + FfxUInt32(0));
|
||||
FfxUInt32 brick_B = LoadBricksMergeList(merge_idx * FfxUInt32(2) + FfxUInt32(1));
|
||||
FfxUInt32x3 atlas_offset_A = FfxBrixelizerGetSDFAtlasOffset(brick_A);
|
||||
FfxUInt32x3 atlas_offset_B = FfxBrixelizerGetSDFAtlasOffset(brick_B);
|
||||
{
|
||||
FfxFloat32 sdf_val_A = LoadSDFAtlas(atlas_offset_A + voxel_offset);
|
||||
FfxFloat32 sdf_val_B = LoadSDFAtlas(atlas_offset_B + voxel_offset);
|
||||
StoreSDFAtlas(atlas_offset_B + voxel_offset, min(sdf_val_A, sdf_val_B));
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerMergeCascades(FfxUInt32 voxel_idx)
|
||||
{
|
||||
// Assume the same clipmap state so no need to wrap the coords
|
||||
FfxUInt32 brick_A = LoadCascadeBrickMapArrayUniform(GetBuildInfo().src_cascade_A, voxel_idx);
|
||||
FfxUInt32 brick_B = LoadCascadeBrickMapArrayUniform(GetBuildInfo().src_cascade_B, voxel_idx);
|
||||
if (FfxBrixelizerIsValidID(brick_A) && FfxBrixelizerIsValidID(brick_B)) {
|
||||
FfxUInt32 offset;
|
||||
IncrementContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_MERGE_BRICKS, FfxUInt32(1), /* out */ offset);
|
||||
StoreBricksMergeList(offset * FfxUInt32(2) + FfxUInt32(0), brick_A);
|
||||
StoreBricksMergeList(offset * FfxUInt32(2) + FfxUInt32(1), brick_B);
|
||||
StoreCascadeBrickMapArrayUniform(GetBuildInfo().dst_cascade, voxel_idx, brick_B); // we store the 2nd brick and merge into it
|
||||
|
||||
FfxUInt32 brick_A_aabb_pack = LoadBricksAABB(FfxBrixelizerBrickGetIndex(brick_A));
|
||||
FfxUInt32x3 brick_A_aabb_umin = FfxBrixelizerUnflattenPOT(brick_A_aabb_pack & ((FfxUInt32(1) << FfxUInt32(9)) - FfxUInt32(1)), FfxUInt32(3));
|
||||
FfxUInt32x3 brick_A_aabb_umax = FfxBrixelizerUnflattenPOT((brick_A_aabb_pack >> FfxUInt32(9)) & ((FfxUInt32(1) << FfxUInt32(9)) - FfxUInt32(1)), FfxUInt32(3));
|
||||
|
||||
FfxUInt32 brick_B_aabb_pack = LoadBricksAABB(FfxBrixelizerBrickGetIndex(brick_B));
|
||||
FfxUInt32x3 brick_B_aabb_umin = FfxBrixelizerUnflattenPOT(brick_B_aabb_pack & ((FfxUInt32(1) << FfxUInt32(9)) - FfxUInt32(1)), FfxUInt32(3));
|
||||
FfxUInt32x3 brick_B_aabb_umax = FfxBrixelizerUnflattenPOT((brick_B_aabb_pack >> FfxUInt32(9)) & ((FfxUInt32(1) << FfxUInt32(9)) - FfxUInt32(1)), FfxUInt32(3));
|
||||
|
||||
brick_B_aabb_umin = min(brick_A_aabb_umin, brick_B_aabb_umin);
|
||||
brick_B_aabb_umax = max(brick_A_aabb_umax, brick_B_aabb_umax);
|
||||
brick_B_aabb_pack = FfxBrixelizerFlattenPOT(brick_B_aabb_umin, 3) | (FfxBrixelizerFlattenPOT(brick_B_aabb_umax, 3) << 9);
|
||||
|
||||
StoreBricksAABB(FfxBrixelizerBrickGetIndex(brick_B), brick_B_aabb_pack);
|
||||
} else if (brick_B == FFX_BRIXELIZER_UNINITIALIZED_ID || brick_A == FFX_BRIXELIZER_UNINITIALIZED_ID) {
|
||||
StoreCascadeBrickMapArrayUniform(GetBuildInfo().dst_cascade, voxel_idx, FFX_BRIXELIZER_UNINITIALIZED_ID);
|
||||
} else if (FfxBrixelizerIsValidID(brick_B)) {
|
||||
StoreCascadeBrickMapArrayUniform(GetBuildInfo().dst_cascade, voxel_idx, brick_B);
|
||||
} else {
|
||||
StoreCascadeBrickMapArrayUniform(GetBuildInfo().dst_cascade, voxel_idx, brick_A);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerPrepareEikonalArgs()
|
||||
{
|
||||
FfxUInt32 tier_cnt = LoadContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_DIRTY_BRICKS);
|
||||
StoreContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_DIRTY_BRICKS, 0);
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_EIKONAL_32 + 0, tier_cnt);
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_EIKONAL_32 + FfxUInt32(1), 1);
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_EIKONAL_32 + 2, 1);
|
||||
}
|
||||
|
||||
void FfxBrixelizerPrepareMergeBricksArgs()
|
||||
{
|
||||
FfxUInt32 cnt = LoadContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_MERGE_BRICKS);
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_MERGE_BRICKS_32 + FfxUInt32(0), cnt * FfxUInt32(8)); // 2^3 of 4^3 lanes
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_MERGE_BRICKS_32 + FfxUInt32(1), FfxUInt32(1));
|
||||
StoreIndirectArgs(FFX_BRIXELIZER_INDIRECT_OFFSETS_MERGE_BRICKS_32 + FfxUInt32(2), FfxUInt32(1));
|
||||
}
|
||||
|
||||
#endif // ifndef FFX_BRIXELIZER_CONTEXT_OPS_H
|
||||
105
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_debug_aabbs.h
vendored
Normal file
105
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_debug_aabbs.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// 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_brixelizer_common.h"
|
||||
#include "ffx_brixelizer_host_gpu_shared.h"
|
||||
|
||||
void PushAABB(FfxBrixelizerDebugAABB aabb)
|
||||
{
|
||||
FfxUInt32 offset;
|
||||
IncrementContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_NUM_DEBUG_AABBS, 1, offset);
|
||||
if (offset < GetDebugInfoMaxAABBs()) {
|
||||
StoreDebugAABB(offset, aabb);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerDrawAABBTreeAABB(FfxUInt32 aabb_index)
|
||||
{
|
||||
// if g_debug_info.debug_state is set to 1 we only want to draw the cascade bounding box
|
||||
if (GetDebugInfoDebugState() == 1 && aabb_index > 0) {
|
||||
return;
|
||||
}
|
||||
if (aabb_index == 0) {
|
||||
FfxBrixelizerCascadeInfo cascade_info = GetCascadeInfo();
|
||||
FfxBrixelizerDebugAABB debug_aabb;
|
||||
debug_aabb.color = FfxFloat32x3(1.0f, 0.0f, 0.0f);
|
||||
debug_aabb.aabbMin = cascade_info.grid_min;
|
||||
debug_aabb.aabbMax = cascade_info.grid_max;
|
||||
PushAABB(debug_aabb);
|
||||
} else if (aabb_index == 1) {
|
||||
// root aabb
|
||||
FfxUInt32 index = 16*16*16 + 4*4*4*6;
|
||||
FfxBrixelizerDebugAABB debug_aabb;
|
||||
debug_aabb.color = FfxFloat32x3(0.0f, 1.0f, 1.0f);
|
||||
debug_aabb.aabbMin = LoadCascadeAABBTreeFloat3(index);
|
||||
debug_aabb.aabbMax = LoadCascadeAABBTreeFloat3(index + 3);
|
||||
PushAABB(debug_aabb);
|
||||
} else if (aabb_index <= 1 + 4*4*4) {
|
||||
// second level aabb
|
||||
FfxUInt32 index = 16*16*16 + (aabb_index - 2)*6;
|
||||
FfxBrixelizerDebugAABB debug_aabb;
|
||||
debug_aabb.color = FfxFloat32x3(1.0f, 1.0f, 0.0f);
|
||||
debug_aabb.aabbMin = LoadCascadeAABBTreeFloat3(index);
|
||||
debug_aabb.aabbMax = LoadCascadeAABBTreeFloat3(index + 3);
|
||||
|
||||
if (ffxAsUInt32(debug_aabb.aabbMin.x) == ffxAsUInt32(debug_aabb.aabbMax.x)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PushAABB(debug_aabb);
|
||||
|
||||
} else if (aabb_index <= 1 + 4*4*4 + 16*16*16) {
|
||||
// leaf aabb
|
||||
FfxBrixelizerCascadeInfo cascade_info = GetCascadeInfo();
|
||||
FfxUInt32 index = aabb_index - (4*4*4 + 1 + 1);
|
||||
FfxUInt32 packedAABB = LoadCascadeAABBTreeUInt(index);
|
||||
if (packedAABB == FFX_BRIXELIZER_INVALID_BOTTOM_AABB_NODE) {
|
||||
return;
|
||||
}
|
||||
|
||||
FfxUInt32x3 leaf_offset = FfxBrixelizerUnflattenPOT(index, 4) * 32;
|
||||
FfxUInt32x3 aabbMin = leaf_offset + FfxBrixelizerUnflattenPOT(packedAABB & ((1 << 15) - 1), 5);
|
||||
FfxUInt32x3 aabbMax = leaf_offset + FfxBrixelizerUnflattenPOT((packedAABB >> 16) & ((1 << 15) - 1), 5) + 1;
|
||||
|
||||
FfxBrixelizerDebugAABB debug_aabb;
|
||||
debug_aabb.color = FfxFloat32x3(0.0f, 1.0f, 0.0f);
|
||||
debug_aabb.aabbMin = cascade_info.grid_min + FfxFloat32x3(aabbMin) * cascade_info.voxel_size / 8.0f;
|
||||
debug_aabb.aabbMax = cascade_info.grid_min + FfxFloat32x3(aabbMax) * cascade_info.voxel_size / 8.0f;
|
||||
PushAABB(debug_aabb);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerDrawInstanceAABB(FfxUInt32 index)
|
||||
{
|
||||
// XXX -- use debug_state to pass in number of instance IDs
|
||||
if (index >= GetDebugInfoDebugState()) {
|
||||
return;
|
||||
}
|
||||
|
||||
FfxUInt32 instance_id = GetDebugInstanceID(index);
|
||||
FfxBrixelizerInstanceInfo instance_info = LoadInstanceInfo(instance_id);
|
||||
FfxBrixelizerDebugAABB debug_aabb;
|
||||
debug_aabb.color = FfxFloat32x3(0.0f, 0.0f, 1.0f);
|
||||
debug_aabb.aabbMin = instance_info.aabbMin;
|
||||
debug_aabb.aabbMax = instance_info.aabbMax;
|
||||
PushAABB(debug_aabb);
|
||||
}
|
||||
199
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_debug_visualization.h
vendored
Normal file
199
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_debug_visualization.h
vendored
Normal file
@@ -0,0 +1,199 @@
|
||||
// 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_BRIXELIZER_DEBUG_VISUALIZATION_H
|
||||
#define FFX_BRIXELIZER_DEBUG_VISUALIZATION_H
|
||||
|
||||
#include "ffx_brixelizer_host_gpu_shared.h"
|
||||
|
||||
#define FFX_BRIXELIZER_TRAVERSAL_EPS (GetDebugInfoPreviewSDFSolveEpsilon() / FfxFloat32(8.0))
|
||||
|
||||
#include "ffx_brixelizer_trace_ops.h"
|
||||
|
||||
// XXX -- tmp
|
||||
FfxUInt32 FfxBrixelizerGetVoxelCascade(FfxUInt32 voxel_id)
|
||||
{
|
||||
return voxel_id >> FFX_BRIXELIZER_CASCADE_ID_SHIFT;
|
||||
}
|
||||
|
||||
#define FLT_INF 1e30f
|
||||
|
||||
// By Morgan McGuire @morgan3d, http://graphicscodex.com
|
||||
// Reuse permitted under the BSD license.
|
||||
// https://www.shadertoy.com/view/4dsSzr
|
||||
FfxFloat32x3 FFX_HeatmapGradient(FfxFloat32 t)
|
||||
{
|
||||
return clamp((pow(t, 1.5) * 0.8 + 0.2) * FfxFloat32x3(smoothstep(0.0, 0.35, t) + t * 0.5, smoothstep(0.5, 1.0, t), max(1.0 - t * 1.7, t * 7.0 - 6.0)), 0.0, 1.0);
|
||||
}
|
||||
|
||||
// License?
|
||||
FfxFloat32x3 FFX_RandomColor(FfxFloat32x2 uv) {
|
||||
uv = ffxFract(uv * FfxFloat32(15.718281828459045));
|
||||
FfxFloat32x3 seeds = FfxFloat32x3(FfxFloat32(0.123), FfxFloat32(0.456), FfxFloat32(0.789));
|
||||
seeds = ffxFract((uv.x + FfxFloat32(0.5718281828459045) + seeds) * ((seeds + FFX_MODULO(uv.x, FfxFloat32(0.141592653589793))) * FfxFloat32(27.61803398875) + FfxFloat32(4.718281828459045)));
|
||||
seeds = ffxFract((uv.y + FfxFloat32(0.5718281828459045) + seeds) * ((seeds + FFX_MODULO(uv.y, FfxFloat32(0.141592653589793))) * FfxFloat32(27.61803398875) + FfxFloat32(4.718281828459045)));
|
||||
seeds = ffxFract((FfxFloat32(0.5718281828459045) + seeds) * ((seeds + FFX_MODULO(uv.x, FfxFloat32(0.141592653589793))) * FfxFloat32(27.61803398875) + FfxFloat32(4.718281828459045)));
|
||||
return seeds;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_ViewSpaceToWorldSpace(FfxFloat32x4 view_space_coord)
|
||||
{
|
||||
return FFX_TRANSFORM_VECTOR(GetDebugInfoInvView(), view_space_coord).xyz;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_InvProjectPosition(FfxFloat32x3 coord, FfxFloat32x4x4 mat)
|
||||
{
|
||||
coord.y = (FfxFloat32(1.0) - coord.y);
|
||||
coord.xy = FfxFloat32(2.0) * coord.xy - 1;
|
||||
FfxFloat32x4 projected = FFX_TRANSFORM_VECTOR(mat, FfxFloat32x4(coord, 1));
|
||||
projected.xyz /= projected.w;
|
||||
return projected.xyz;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_ScreenSpaceToViewSpace(FfxFloat32x3 screen_uv_coord)
|
||||
{
|
||||
return FFX_InvProjectPosition(screen_uv_coord, GetDebugInfoInvProj());
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_HitEdgeDist(FfxFloat32x3 hit, FfxFloat32x3 boxMin, FfxFloat32x3 boxMax)
|
||||
{
|
||||
FfxFloat32x3 a = min(abs(hit - boxMin), abs(hit - boxMax));
|
||||
return min(min(a.x + a.y, a.x + a.z), a.y + a.z);
|
||||
}
|
||||
|
||||
// modified from inigo quilez
|
||||
FfxFloat32 FFX_BoxHitDist(FfxUInt32x2 tid, FfxFloat32x3 ro, FfxFloat32x3 rd, FfxFloat32x3 boxMin, FfxFloat32x3 boxMax)
|
||||
{
|
||||
FfxFloat32x3 halfSize = (boxMax - boxMin) / 2.0f;
|
||||
FfxFloat32x3 center = boxMin + halfSize;
|
||||
FfxFloat32x3 rop = ro - center;
|
||||
FfxFloat32x3 ird = 1.0f / rd;
|
||||
FfxFloat32x3 n = rop * ird;
|
||||
FfxFloat32x3 k = abs(ird) * halfSize;
|
||||
FfxFloat32x3 t1 = -n - k;
|
||||
FfxFloat32x3 t2 = -n + k;
|
||||
|
||||
FfxFloat32 tNear = max(max(t1.x, t1.y), t1.z);
|
||||
FfxFloat32 tFar = min(min(t2.x, t2.y), t2.z);
|
||||
|
||||
if (tNear > tFar || tFar < 0.0f) return FLT_INF;
|
||||
|
||||
FfxFloat32 nearEdgeDist = FFX_HitEdgeDist(ro + tNear * rd, boxMin, boxMax);
|
||||
FfxFloat32 farEdgeDist = FFX_HitEdgeDist(ro + tFar * rd, boxMin, boxMax);
|
||||
|
||||
const FfxFloat32 nearClip = 0.1f;
|
||||
if (tNear > nearClip && nearEdgeDist / tNear < 0.001f) {
|
||||
return tNear;
|
||||
} else if (tFar > nearClip && farEdgeDist / tFar < 0.001f) {
|
||||
return tFar;
|
||||
}
|
||||
return FLT_INF;
|
||||
}
|
||||
|
||||
void FfxBrixelizerDebugVisualization(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxUInt32 width, height;
|
||||
GetDebugOutputDimensions(width, height);
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(tid.xy) + FfxFloat32(0.5).xx) / FfxFloat32x2(width, height);
|
||||
|
||||
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, FfxFloat32(0.5));
|
||||
FfxFloat32x3 view_space_ray = FFX_ScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
||||
FfxFloat32x3 view_space_ray_direction = normalize(view_space_ray);
|
||||
FfxFloat32x3 ray_direction = normalize(FFX_ViewSpaceToWorldSpace(FfxFloat32x4(view_space_ray_direction, FfxFloat32(0.0))));
|
||||
FfxFloat32x3 ray_origin = FFX_ViewSpaceToWorldSpace(FfxFloat32x4(0.0, 0.0, 0.0, 1.0));
|
||||
|
||||
FfxBrixelizerRayDesc ray_desc;
|
||||
ray_desc.start_cascade_id = GetDebugInfoStartCascadeIndex();
|
||||
ray_desc.end_cascade_id = GetDebugInfoEndCascadeIndex();
|
||||
ray_desc.t_min = GetDebugInfoTMin();
|
||||
ray_desc.t_max = GetDebugInfoTMax();
|
||||
ray_desc.origin = ray_origin;
|
||||
ray_desc.direction = ray_direction;
|
||||
|
||||
FfxBrixelizerHitRaw hit_payload;
|
||||
FfxBoolean hit = FfxBrixelizerTraverseRaw(ray_desc, hit_payload);
|
||||
FfxFloat32 hit_dist = FLT_INF;
|
||||
FfxFloat32x3 out_color = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
if (hit) {
|
||||
hit_dist = hit_payload.t;
|
||||
switch (GetDebugInfoDebugState()) {
|
||||
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_DISTANCE: {
|
||||
FfxFloat32 dist = (hit_payload.t - ray_desc.t_min) / (ray_desc.t_max - ray_desc.t_min);
|
||||
out_color = FfxFloat32x3(0.0f, smoothstep(0.0f, 1.0f, dist), smoothstep(0.0f, 1.0f, 1.0f - dist));
|
||||
break;
|
||||
}
|
||||
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_UVW: {
|
||||
FfxFloat32x3 uvw = FfxFloat32x3(
|
||||
FfxBrixelizerUnpackUnsigned8Bits((hit_payload.uvwc >> 0) & 0xff),
|
||||
FfxBrixelizerUnpackUnsigned8Bits((hit_payload.uvwc >> 8) & 0xff),
|
||||
FfxBrixelizerUnpackUnsigned8Bits((hit_payload.uvwc >> 16) & 0xff)
|
||||
);
|
||||
out_color = uvw;
|
||||
break;
|
||||
}
|
||||
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_ITERATIONS:
|
||||
out_color = FFX_HeatmapGradient(FfxFloat32(hit_payload.iter_count) / FfxFloat32(64));
|
||||
break;
|
||||
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_GRAD: {
|
||||
out_color = FfxBrixelizerGetHitNormal(hit_payload) * FfxFloat32(0.5) + FfxFloat32(0.5);
|
||||
break;
|
||||
}
|
||||
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_BRICK_ID:
|
||||
out_color = FFX_RandomColor(FfxFloat32x2(FfxFloat32(hit_payload.brick_id % 256) / FfxFloat32(256.0), FfxFloat32((hit_payload.brick_id / 256) % 256) / FfxFloat32(256.0)));
|
||||
break;
|
||||
case FFX_BRIXELIZER_TRACE_DEBUG_MODE_CASCADE_ID: {
|
||||
FfxUInt32 voxel_id = LoadBricksVoxelMap(FfxBrixelizerBrickGetIndex(hit_payload.brick_id));
|
||||
FfxUInt32 cascade_id = FfxBrixelizerGetVoxelCascade(voxel_id);
|
||||
out_color = FFX_RandomColor(FfxFloat32x2(FfxFloat32(cascade_id % 256) / FfxFloat32(256.0), FfxFloat32((cascade_id / 256) % 256) / FfxFloat32(256.0)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
out_color = FFX_HeatmapGradient(FfxFloat32(hit_payload.iter_count) / FfxFloat32(64));
|
||||
}
|
||||
|
||||
FfxFloat32 aabb_hit_dist = FLT_INF;
|
||||
FfxFloat32x3 aabb_color = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
FfxUInt32 num_debug_aabbs = min(GetDebugInfoMaxAABBs(), LoadContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_NUM_DEBUG_AABBS));
|
||||
|
||||
for (FfxUInt32 i = 0; i < num_debug_aabbs; ++i) {
|
||||
FfxBrixelizerDebugAABB aabb = GetDebugAABB(i);
|
||||
|
||||
FfxFloat32 this_hit_dist = FFX_BoxHitDist(tid, ray_desc.origin, ray_desc.direction, aabb.aabbMin, aabb.aabbMax);
|
||||
if (this_hit_dist < aabb_hit_dist) {
|
||||
aabb_hit_dist = this_hit_dist;
|
||||
aabb_color = aabb.color;
|
||||
}
|
||||
}
|
||||
|
||||
if (aabb_hit_dist < hit_dist) {
|
||||
out_color = aabb_color;
|
||||
} else if (aabb_hit_dist < FLT_INF) {
|
||||
out_color = ffxLerp(out_color, aabb_color, 0.25f);
|
||||
}
|
||||
|
||||
StoreDebugOutput(tid, out_color);
|
||||
}
|
||||
|
||||
#endif // ifndef FFX_BRIXELIZER_DEBUG_VISUALIZATION_H
|
||||
230
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_host_gpu_shared.h
vendored
Normal file
230
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_host_gpu_shared.h
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
// 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_BRIXELIZER_HOST_GPU_SHARED_H
|
||||
#define FFX_BRIXELIZER_HOST_GPU_SHARED_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
|
||||
#define FFX_BRIXELIZER_MAX_CASCADES 24
|
||||
#define FFX_BRIXELIZER_MAX_INSTANCES (FfxUInt32(1) << FfxUInt32(16))
|
||||
#define FFX_BRIXELIZER_CASCADE_RESOLUTION 64
|
||||
#define FFX_BRIXELIZER_MAX_INSTANCES (FfxUInt32(1) << FfxUInt32(16))
|
||||
#define FFX_BRIXELIZER_INVALID_ID 0x00ffffffu
|
||||
#define FFX_BRIXELIZER_UNINITIALIZED_ID 0xffffffffu
|
||||
#define FFX_BRIXELIZER_INVALID_BOTTOM_AABB_NODE 0x7fff
|
||||
#define FFX_BRIXELIZER_MAX_BRICKS_X8 (1 << 18)
|
||||
#define FFX_BRIXELIZER_MAX_BRICKS FFX_BRIXELIZER_MAX_BRICKS_X8
|
||||
#define FFX_BRIXELIZER_BRICK_AABBS_STRIDE (sizeof(FfxUInt32))
|
||||
#define FFX_BRIXELIZER_BRICK_AABBS_SIZE (FFX_BRIXELIZER_MAX_BRICKS_X8 * FFX_BRIXELIZER_BRICK_AABBS_STRIDE)
|
||||
#define FFX_BRIXELIZER_CASCADE_AABB_TREE_SIZE ((16 * 16 * 16) * sizeof(FfxUInt32) + (4 * 4 * 4 + 1) * sizeof(FfxFloat32x3) * 2)
|
||||
#define FFX_BRIXELIZER_CASCADE_AABB_TREE_STRIDE (sizeof(FfxUInt32))
|
||||
#define FFX_BRIXELIZER_CASCADE_BRICK_MAP_SIZE (FFX_BRIXELIZER_CASCADE_RESOLUTION * FFX_BRIXELIZER_CASCADE_RESOLUTION * FFX_BRIXELIZER_CASCADE_RESOLUTION * sizeof(FfxUInt32))
|
||||
#define FFX_BRIXELIZER_CASCADE_BRICK_MAP_STRIDE (sizeof(FfxUInt32))
|
||||
|
||||
#define FFX_BRIXELIZER_BRICK_ID_MASK 0xffffff
|
||||
|
||||
#define FFX_BRIXELIZER_CASCADE_DEGREE FfxUInt32(6)
|
||||
#define FFX_BRIXELIZER_CASCADE_WRAP_MASK FfxUInt32(63)
|
||||
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE FfxUInt32(512)
|
||||
|
||||
#if defined(FFX_CPU)
|
||||
#define FFX_BRIXELIZER_CONST static const
|
||||
#elif defined(FFX_HLSL)
|
||||
#define FFX_BRIXELIZER_CONST static const
|
||||
#elif defined(FFX_GLSL)
|
||||
#define FFX_BRIXELIZER_CONST const
|
||||
#else
|
||||
FFX_STATIC_ASSERT(0)
|
||||
#endif
|
||||
|
||||
#ifdef FFX_CPU
|
||||
#define FFX_BRIXELIZER_BEGIN_STRUCT(name) typedef struct name {
|
||||
#define FFX_BRIXELIZER_END_STRUCT(name) } name;
|
||||
#define FFX_BRIXELIZER_BEGIN_ENUM(name) typedef enum name {
|
||||
#define FFX_BRIXELIZER_END_ENUM(name) } name;
|
||||
#define FFX_BRIXELIZER_ENUM_VALUE(name, value) name = value,
|
||||
#else
|
||||
#define FFX_BRIXELIZER_BEGIN_STRUCT(name) struct name {
|
||||
#define FFX_BRIXELIZER_END_STRUCT(name) };
|
||||
#define FFX_BRIXELIZER_BEGIN_ENUM(name)
|
||||
#define FFX_BRIXELIZER_END_ENUM(name)
|
||||
#define FFX_BRIXELIZER_ENUM_VALUE(name, value) FFX_BRIXELIZER_CONST FfxUInt32 name = value;
|
||||
#endif
|
||||
|
||||
/// An enumeration of flags which can be specified for different options when doing a cascade update.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FFX_BRIXELIZER_BEGIN_ENUM(FfxBrixelizerCascadeUpdateFlags)
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_CASCADE_UPDATE_FLAG_NONE, FfxUInt32(0)) ///< No flags.
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_CASCADE_UPDATE_FLAG_RESET, FfxUInt32(1) << FfxUInt32(0)) ///< Reset the cascade. This clears and frees all bricks currently in the cascade ready to rebuild the cascade completely.
|
||||
FFX_BRIXELIZER_END_ENUM(FfxBrixelizerCascadeUpdateFlags)
|
||||
|
||||
/// An enumeration of the different possible debug outputs for the Brixelizer debug visualization.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FFX_BRIXELIZER_BEGIN_ENUM(FfxBrixelizerTraceDebugModes)
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_TRACE_DEBUG_MODE_DISTANCE, 0) ///< Display a visualisation of the distance to hit, with closer hits in blue and further hits in green.
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_TRACE_DEBUG_MODE_UVW, 1) ///< Display the UVW coordinates of hits.
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_TRACE_DEBUG_MODE_ITERATIONS, 2) ///< Display a heatmap visualizing number of iterations in the scene.
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_TRACE_DEBUG_MODE_GRAD, 3) ///< Display the normals at hits.
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_TRACE_DEBUG_MODE_BRICK_ID, 4) ///< Display each brick in its own color.
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_TRACE_DEBUG_MODE_CASCADE_ID, 5) ///< Display each cascade in itw own color.
|
||||
FFX_BRIXELIZER_END_ENUM(FfxBrixelizerTraceDebugModes)
|
||||
|
||||
/// A structure of parameters describing a cascade. This structure is primarily for Brixelizer
|
||||
/// internal use.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerCascadeInfo)
|
||||
FfxFloat32x3 grid_min;
|
||||
FfxFloat32 voxel_size;
|
||||
|
||||
FfxFloat32x3 grid_max;
|
||||
FfxUInt32 flags; ///< the latest build_flags; see FfxBrixelizerCascadeUpdateFlags
|
||||
|
||||
FfxUInt32x3 clipmap_offset;
|
||||
FfxUInt32 pad00;
|
||||
|
||||
FfxInt32x3 clipmap_invalidation_offset;
|
||||
FfxUInt32 pad33;
|
||||
|
||||
FfxInt32x3 ioffset;
|
||||
FfxUInt32 index;
|
||||
|
||||
FfxFloat32x3 grid_mid;
|
||||
FfxUInt32 is_enabled;
|
||||
|
||||
FfxUInt32x2 rel_grid_min_fp16;
|
||||
FfxUInt32x2 rel_grid_max_fp16;
|
||||
|
||||
FfxUInt32 pad11;
|
||||
FfxUInt32 pad22;
|
||||
FfxFloat32 ivoxel_size;
|
||||
FfxUInt32 is_initialized;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerCascadeInfo)
|
||||
|
||||
/// A structure of parameters describing the Brixelizer context. This structure is primarily
|
||||
/// for Brixelizer internal use.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerContextInfo)
|
||||
FfxUInt32 num_bricks;
|
||||
FfxUInt32 frame_index;
|
||||
FfxFloat32 imesh_unit;
|
||||
FfxFloat32 mesh_unit;
|
||||
|
||||
FfxBrixelizerCascadeInfo cascades[FFX_BRIXELIZER_MAX_CASCADES];
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerContextInfo)
|
||||
|
||||
// =============================================================================
|
||||
// Debug/context counters
|
||||
// =============================================================================
|
||||
// Important to match the first a couple of counters with the FfxBrixelizerScratchCounters to share code
|
||||
#define MEMBER_LIST \
|
||||
MEMBER(brickCount, BRICK_COUNT, 0) \
|
||||
MEMBER(dirtyBricks, DIRTY_BRICKS, 1) \
|
||||
MEMBER(freeBricks, FREE_BRICKS, 2) \
|
||||
MEMBER(clearBricks, CLEAR_BRICKS, 3) \
|
||||
MEMBER(mergeBricks, MERGE_BRICKS, 4) \
|
||||
MEMBER(numDebugAABBs, NUM_DEBUG_AABBS, 5)
|
||||
|
||||
/// A structure containing all the counters used by the Brixelizer context. These can
|
||||
/// be read back from the context after processing each update for analysis.
|
||||
/// <c><i>brickCount</i></c> gives the total number of bricks allocated.
|
||||
/// <c><i>dirtyBricks</i></c> gives the total number of bricks requiring an eikonal pass for completion.
|
||||
/// <c><i>freeBricks</i></c> gives the total number of free bricks. This is the maximum number of bricks which can be allocated within a frame.
|
||||
/// <c><i>clearBricks</i></c> gives the total number of bricks to be cleared in a frame. Bricks are cleared by having all distance values reset to 1.
|
||||
/// <c><i>mergeBricks</i></c> gives the total number of bricks to be merged in a frame.
|
||||
/// <c><i>numDebugAABBs</i></c> gives the total number of debug AABBs requested to be drawn in a debug visualization.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerDebugCounters)
|
||||
#define MEMBER(camel_name, _upper_name, _index) FfxUInt32 camel_name;
|
||||
MEMBER_LIST
|
||||
#undef MEMBER
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerDebugCounters)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_ENUM(FfxBrixelizerContextCounterIndex)
|
||||
#define MEMBER(_camel_name, upper_name, index) FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_CONTEXT_COUNTER_##upper_name, index)
|
||||
MEMBER_LIST
|
||||
#undef MEMBER
|
||||
FFX_BRIXELIZER_END_ENUM(FfxBrixelizerContextCounterIndex)
|
||||
|
||||
#define MEMBER(_camel_name, _upper_name, _index) + 1
|
||||
FFX_BRIXELIZER_CONST FfxUInt32 FFX_BRIXELIZER_NUM_CONTEXT_COUNTERS = 0 MEMBER_LIST;
|
||||
#undef MEMBER
|
||||
#undef MEMBER_LIST
|
||||
|
||||
// =============================================================================
|
||||
// Scratch counters
|
||||
// =============================================================================
|
||||
#define MEMBER_LIST \
|
||||
MEMBER(triangles, TRIANGLES, 0) \
|
||||
MEMBER(maxTriangles, MAX_TRIANGLES, 1) \
|
||||
MEMBER(references, REFERENCES, 2) \
|
||||
MEMBER(maxReferences, MAX_REFERENCES, 3) \
|
||||
MEMBER(groupIndex, GROUP_INDEX, 4) \
|
||||
MEMBER(compressionBricks, COMPRESSION_BRICKS, 5) \
|
||||
MEMBER(storageOffset, STORAGE_OFFSET, 6) \
|
||||
MEMBER(storageSize, STORAGE_SIZE, 7) \
|
||||
MEMBER(numBricksAllocated, NUM_BRICKS_ALLOCATED, 8) \
|
||||
MEMBER(clearBricks, CLEAR_BRICKS, 9)
|
||||
|
||||
/// A structure containing the counters used by the Brixelizer context for each cascade
|
||||
/// update. This can be readback and used for analysis after each update. The following
|
||||
/// members contain useful information for analysing Brixelizer resource usage.
|
||||
///
|
||||
/// <c><i>triangles</i></c> is used to store the total amount of storage space requested within the triangle buffer during an update. This is useful for determining a sensible value of <c><i>triangleSwapSize</i></c> in either <c><i>FfxBrixelizerRawCascadeUpdateDescription</i></c> or <c><i>FfxBrixelizerUpdateDescription</i></c>.
|
||||
/// <c><i>references</i></c> is used to store the total number of reference allocations requested by Brixelizer during an update. This is useful for determining a sensible value of <c><i>maxReferences</i></c> in either <c><i>FfxBrixelizerRawCascadeUpdateDescription</i></c> or <c><i>FfxBrixelizerUpdateDescription</i></c>.
|
||||
/// <c><i>numBricksAllocated</i></c> is used to store the number of brick allocations requested in an update. This is useful for determining a sensible value of <c><i>maxBricksPerBake</i></c> in either <c><i>FfxBrixelizerRawCascadeUpdateDescription</i></c> or <c><i>FfxBrixelizerUpdateDescription</i></c>.
|
||||
///
|
||||
/// The following counters are used internally by Brixelizer.
|
||||
///
|
||||
/// <c><i>maxTriangles</i></c> is used to store the storage size of the triangle buffer.
|
||||
/// <c><i>maxReferences</i></c> is used to store the maxmimum number of references that can be stored.
|
||||
/// <c><i>groupIndex</i></c> is used as a global atomic for wavefront synchronisation.
|
||||
/// <c><i>compressionBricks</i></c> the number of bricks to compress (i.e. calculate AABBs for) this udpate.
|
||||
/// <c><i>storageOffset</i></c> the next free position in the bricks scratch buffer.
|
||||
/// <c><i>storageSize</i></c> the size of the bricks scratch buffer.
|
||||
/// <c><i>clearBricks</i></c> the amount of bricks in the scratch buffer to initialize.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerScratchCounters)
|
||||
#define MEMBER(camel_name, _upper_name, _index) FfxUInt32 camel_name;
|
||||
MEMBER_LIST
|
||||
#undef MEMBER
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerScratchCounters)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_ENUM(FfxBrixelizerScratchCounterIndex)
|
||||
#define MEMBER(_camel_name, upper_name, index) FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_SCRATCH_COUNTER_##upper_name, index)
|
||||
MEMBER_LIST
|
||||
#undef MEMBER
|
||||
FFX_BRIXELIZER_END_ENUM(FfxBrixelizerScratchCounterIndex)
|
||||
|
||||
#define MEMBER(_camel_name, _upper_name, _index) + 1
|
||||
FFX_BRIXELIZER_CONST FfxUInt32 FFX_BRIXELIZER_NUM_SCRATCH_COUNTERS = 0 MEMBER_LIST;
|
||||
#undef MEMBER
|
||||
#undef MEMBER_LIST
|
||||
|
||||
#endif
|
||||
222
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_host_gpu_shared_private.h
vendored
Normal file
222
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_host_gpu_shared_private.h
vendored
Normal file
@@ -0,0 +1,222 @@
|
||||
// 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_BRIXELIZER_HOST_GPU_SHARED_PRIVATE_H
|
||||
#define FFX_BRIXELIZER_HOST_GPU_SHARED_PRIVATE_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
#include "ffx_brixelizer_host_gpu_shared.h"
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_ENUM(FfxBrixelizerInstanceFlagsInternal)
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INSTANCE_FLAG_USE_U16_INDEX, (FfxUInt32(1) << FfxUInt32(0)))
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INSTANCE_FLAG_USE_RGBA16_VERTEX, (FfxUInt32(1) << FfxUInt32(2)))
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INSTANCE_FLAG_USE_INDEXLESS_QUAD_LIST, (FfxUInt32(1) << FfxUInt32(3)))
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INSTANCE_FLAG_UV_FORMAT_RG16_UNORM, (FfxUInt32(1) << FfxUInt32(4)))
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INSTANCE_FLAG_UV_FORMAT_RG32_FLOAT, (FfxUInt32(1) << FfxUInt32(5)))
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INSTANCE_FLAG_COLOR_FORMAT_RGBA32_FLOAT, (FfxUInt32(1) << FfxUInt32(6)))
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INSTANCE_FLAG_COLOR_FORMAT_RGBA8_UNORM, (FfxUInt32(1) << FfxUInt32(7)))
|
||||
FFX_BRIXELIZER_END_ENUM(FfxBrixelizerInstanceFlagsInternal)
|
||||
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_VOXELIZER_GROUP_SIZE FfxUInt32(256)
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_SCAN_REFERENCES_GROUP_SIZE FfxUInt32(256)
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_MAX_VERTEX_BUFFERS FfxUInt32(8192)
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_COMPACT_REFERENCES_GROUP_SIZE FfxUInt32(64)
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_EMIT_SDF_GROUP_SIZE FfxUInt32(32)
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_EMIT_SDF_REFS_PER_GROUP FFX_BRIXELIZER_STATIC_CONFIG_EMIT_SDF_GROUP_SIZE
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_INDIRECT_DISPATCH_STRIDE32 FfxUInt32(4)
|
||||
#define FFX_BRIXELIZER_STATIC_CONFIG_INDIRECT_DISPATCH_STRIDE FfxUInt32(16)
|
||||
|
||||
// index deliberately starts at 1
|
||||
#define MEMBER_LIST \
|
||||
MEMBER(CompactReferences, COMPACT_REFERENCES, 1) \
|
||||
MEMBER(EmitSDF, EMIT_SDF, 2) \
|
||||
MEMBER(Voxelize, VOXELIZE, 3) \
|
||||
MEMBER(Compress, COMPRESS, 4) \
|
||||
MEMBER(Eikonal, EIKONAL, 5) \
|
||||
MEMBER(ClearBricks, CLEAR_BRICKS, 6) \
|
||||
MEMBER(MergeBricks, MERGE_BRICKS, 7) \
|
||||
MEMBER(InstanceOpsTrianglePass1, INSTANCE_OPS_TRIANGLE_PASS_1, 8) \
|
||||
MEMBER(InstanceOpsDeferredReleaseBrits, INSTANCE_OPS_DEFERRED_RELEASE_BRITS, 9) \
|
||||
MEMBER(ClearBrits, CLEAR_BRITS, 10)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerIndirectOffsets)
|
||||
FfxUInt32x4 pad;
|
||||
#define MEMBER(pascal_name, _upper_name, _index) FfxUInt32x4 pascal_name;
|
||||
MEMBER_LIST
|
||||
#undef MEMBER
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerIndirectOffsets)
|
||||
|
||||
#define MEMBER(_pascal_name, _upper_name, _index) + 1
|
||||
FFX_BRIXELIZER_CONST FfxUInt32 FFX_BRIXELIZER_NUM_INDIRECT_OFFSETS = 1 MEMBER_LIST;
|
||||
#undef MEMBER
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_ENUM(FfxBrixelizerIndirectOffsetsEnum)
|
||||
#define MEMBER(_pascal_name, upper_name, index) FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INDIRECT_OFFSETS_##upper_name, index * FFX_BRIXELIZER_STATIC_CONFIG_INDIRECT_DISPATCH_STRIDE)
|
||||
MEMBER_LIST
|
||||
#undef MEMBER
|
||||
#define MEMBER(_pascal_name, upper_name, index) FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_INDIRECT_OFFSETS_##upper_name##_32, index * FFX_BRIXELIZER_STATIC_CONFIG_INDIRECT_DISPATCH_STRIDE32)
|
||||
MEMBER_LIST
|
||||
#undef MEMBER
|
||||
FFX_BRIXELIZER_END_ENUM(FfxBrixelizerIndirectOffsetsEnum)
|
||||
|
||||
#undef MEMBER_LIST
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_ENUM(FfxBrixelizerJobFlagsInternal)
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_JOB_FLAG_NONE, FfxUInt32(0))
|
||||
FFX_BRIXELIZER_ENUM_VALUE(FFX_BRIXELIZER_JOB_FLAG_INVALIDATE, (FfxUInt32(1) << FfxUInt32(0)))
|
||||
FFX_BRIXELIZER_END_ENUM(FfxBrixelizerJobFlagsInternal)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerBasicMeshInfo)
|
||||
FfxUInt32 flags;
|
||||
FfxUInt32 indexBufferID;
|
||||
FfxUInt32 indexBufferOffset;
|
||||
FfxUInt32 vertexBufferID;
|
||||
FfxUInt32 vertexBufferOffset;
|
||||
FfxUInt32 vertexCount;
|
||||
FfxUInt32 vertexStride;
|
||||
FfxUInt32 triangleCount;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerBasicMeshInfo)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerInstanceInfo)
|
||||
FfxFloat32x3 aabbMin; // voxel aligned
|
||||
FfxUInt32 pack0; // | 16: vertex buffer id | 16: index buffer id |
|
||||
|
||||
FfxFloat32x3 aabbMax; // voxel aligned
|
||||
FfxUInt32 pack1; // ! 6: vertex stride | 10: flags | | |
|
||||
|
||||
FfxUInt32 indexBufferOffset;
|
||||
FfxUInt32 vertexBufferOffset;
|
||||
FfxUInt32 vertexCount;
|
||||
FfxUInt32 triangleCount;
|
||||
|
||||
FfxUInt32x3 padding;
|
||||
FfxUInt32 index;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerInstanceInfo)
|
||||
|
||||
#ifdef FFX_GPU
|
||||
FfxBrixelizerBasicMeshInfo ffxBrixelizerInstanceInfoGetMeshInfo(FFX_PARAMETER_IN FfxBrixelizerInstanceInfo instance_info)
|
||||
{
|
||||
FfxBrixelizerBasicMeshInfo info;
|
||||
info.flags = (instance_info.pack1 >> 16) & FfxUInt32(0x1ff);
|
||||
info.triangleCount = instance_info.triangleCount;
|
||||
info.indexBufferID = (instance_info.pack0 >> 0) & FfxUInt32(0xffff);
|
||||
info.indexBufferOffset = instance_info.indexBufferOffset;
|
||||
info.vertexBufferID = (instance_info.pack0 >> 16) & FfxUInt32(0xffff);
|
||||
info.vertexBufferOffset = instance_info.vertexBufferOffset;
|
||||
info.vertexStride = (instance_info.pack1 >> 26) & 0x3f;
|
||||
return info;
|
||||
}
|
||||
#endif
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerBrixelizationJob)
|
||||
FfxUInt32x3 aabbMin; // in local cascade voxel size
|
||||
FfxUInt32 instanceIdx;
|
||||
|
||||
FfxUInt32x3 aabbMax; // in local cascade voxel size
|
||||
FfxUInt32 flags;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerBrixelizationJob)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerIndexRef)
|
||||
FfxUInt32 surface_id;
|
||||
FfxUInt32 instance_id;
|
||||
FfxUInt32 triangle_index;
|
||||
FfxUInt32 pad0;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerIndexRef)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerTriangleReference)
|
||||
FfxUInt32 voxel_idx;
|
||||
FfxUInt32 triangle_id;
|
||||
FfxUInt32 local_ref_idx;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerTriangleReference)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerInstanceReference)
|
||||
FfxUInt32 voxel_idx;
|
||||
FfxUInt32 instance_id;
|
||||
FfxUInt32 local_ref_idx;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerInstanceReference)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerTriangle)
|
||||
FfxUInt32 job_idx;
|
||||
FfxUInt32 triangle_index;
|
||||
FfxUInt32x3 face3;
|
||||
|
||||
FfxFloat32x3 wp0;
|
||||
FfxFloat32x3 wp1;
|
||||
FfxFloat32x3 wp2;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerTriangle)
|
||||
|
||||
#define FFX_BRIXELIZER_TRIANGLE_SMALL_FLAG (FfxUInt32(1) << FfxUInt32(31))
|
||||
#define FFX_BRIXELIZER_TRIANGLE_OFFSET_MASK (0x7fffffffu)
|
||||
|
||||
#define FFX_BRIXELIZER_INVALID_ALLOCATION 0x00ffffffu
|
||||
#define FFX_BRIXELIZER_VOXEL_ID_MASK 0xffffff
|
||||
#define FFX_BRIXELIZER_CASCADE_ID_SHIFT 24
|
||||
|
||||
#ifdef FFX_GPU
|
||||
FfxBoolean FfxBrixelizerTriangleIsSmall(FfxUInt32 id) { return ((id & FFX_BRIXELIZER_TRIANGLE_SMALL_FLAG) != 0); }
|
||||
FfxUInt32 FfxBrixelizerTriangleIDGetOffset(FfxUInt32 id) { return id & FFX_BRIXELIZER_TRIANGLE_OFFSET_MASK; }
|
||||
FfxBoolean FfxBrixelizerIsInvalidID(FfxUInt32 id) { return (id & FFX_BRIXELIZER_INVALID_ID) == FFX_BRIXELIZER_INVALID_ID; }
|
||||
#endif
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerBuildInfo)
|
||||
FfxInt32 tree_iteration;
|
||||
FfxUInt32 max_bricks_per_bake;
|
||||
FfxUInt32 num_jobs;
|
||||
FfxUInt32 cascade_index;
|
||||
|
||||
FfxUInt32 cascade_shift; // [1, 2, 4] for 1x, 2x and 4x
|
||||
FfxUInt32 is_dynamic;
|
||||
FfxUInt32 do_initialization;
|
||||
FfxUInt32 num_job_voxels;
|
||||
|
||||
FfxUInt32 src_cascade_A;
|
||||
FfxUInt32 src_cascade_B;
|
||||
FfxUInt32 dst_cascade;
|
||||
FfxUInt32 merge_instance_idx;
|
||||
|
||||
FfxUInt32x3 _padding;
|
||||
FfxUInt32 build_flags;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerBuildInfo)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerDebugAABB)
|
||||
FfxFloat32x3 color;
|
||||
FfxFloat32x3 aabbMin;
|
||||
FfxFloat32x3 aabbMax;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerDebugAABB)
|
||||
|
||||
FFX_BRIXELIZER_BEGIN_STRUCT(FfxBrixelizerDebugInfo)
|
||||
FfxFloat32x4x4 inv_view; ///< Stored in row-major order.
|
||||
|
||||
FfxFloat32x4x4 inv_proj; ///< Stored in row-major order.
|
||||
|
||||
FfxFloat32 t_min;
|
||||
FfxFloat32 t_max;
|
||||
FfxFloat32 preview_sdf_solve_eps;
|
||||
FfxUInt32 start_cascade_idx;
|
||||
|
||||
FfxUInt32 end_cascade_idx;
|
||||
FfxUInt32 debug_state;
|
||||
FfxUInt32 max_aabbs;
|
||||
FfxUInt32 _padding;
|
||||
FFX_BRIXELIZER_END_STRUCT(FfxBrixelizerDebugInfo)
|
||||
|
||||
#endif // FFX_BRIXELIZER_HOST_GPU_SHARED_PRIVATE_H
|
||||
173
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_mesh_common.h
vendored
Normal file
173
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_mesh_common.h
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
// 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_BRIXELIZER_MESH_COMMON_H
|
||||
#define FFX_BRIXELIZER_MESH_COMMON_H
|
||||
|
||||
#include "ffx_brixelizer_common_private.h"
|
||||
|
||||
struct FfxBrixelizerTrianglePos {
|
||||
FfxUInt32x3 face3;
|
||||
|
||||
FfxFloat32x3 wp0;
|
||||
FfxFloat32x3 wp1;
|
||||
FfxFloat32x3 wp2;
|
||||
};
|
||||
|
||||
FfxFloat32x3 FFX_Fetch_PositionRGBA16(FfxUInt32 buffer_id, FfxUInt32 offset, FfxUInt32 vertex_id, FfxUInt32 stride)
|
||||
{
|
||||
FfxUInt32x2 pack = LoadVertexBufferUInt2(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
|
||||
FfxFloat32x2 xy = ffxUnpackF32(pack.x);
|
||||
FfxFloat32x2 zw = ffxUnpackF32(pack.y);
|
||||
|
||||
#if 0
|
||||
FfxFloat32 x = f16tof32((pack.x >> FfxUInt32(0)) & FfxUInt32(0xFFFF));
|
||||
FfxFloat32 y = f16tof32((pack.x >> FfxUInt32(16)) & FfxUInt32(0xFFFF));
|
||||
FfxFloat32 z = f16tof32((pack.y >> FfxUInt32(0)) & FfxUInt32(0xFFFF));
|
||||
FfxFloat32 w = f16tof32((pack.y >> FfxUInt32(16)) & FfxUInt32(0xFFFF));
|
||||
#endif
|
||||
|
||||
return FfxFloat32x4(xy, zw).xyz;
|
||||
}
|
||||
|
||||
FfxFloat32x4 FFX_Fetch_Unorm4(FfxUInt32 buffer_id, FfxUInt32 offset, FfxUInt32 vertex_id, FfxUInt32 stride)
|
||||
{
|
||||
FfxUInt32 pack = LoadVertexBufferUInt(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
FfxFloat32 x = FfxFloat32((pack >> FfxUInt32(0)) & FfxUInt32(0xFF)) / FfxFloat32(255.0);
|
||||
FfxFloat32 y = FfxFloat32((pack >> FfxUInt32(8)) & FfxUInt32(0xFF)) / FfxFloat32(255.0);
|
||||
FfxFloat32 z = FfxFloat32((pack >> FfxUInt32(16)) & FfxUInt32(0xFF)) / FfxFloat32(255.0);
|
||||
FfxFloat32 w = FfxFloat32((pack >> FfxUInt32(24)) & FfxUInt32(0xFF)) / FfxFloat32(255.0);
|
||||
return FfxFloat32x4(x, y, z, w);
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_Fetch_RG16_UNORM(FfxUInt32 buffer_id, FfxUInt32 offset, FfxUInt32 vertex_id, FfxUInt32 stride)
|
||||
{
|
||||
FfxUInt32 pack = LoadVertexBufferUInt(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
FfxFloat32 x = FfxFloat32((pack >> FfxUInt32(0)) & 0xFFFFu) / FfxFloat32(65535.0);
|
||||
FfxFloat32 y = FfxFloat32((pack >> FfxUInt32(16)) & 0xFFFFu) / FfxFloat32(65535.0);
|
||||
return FfxFloat32x2(x, y);
|
||||
}
|
||||
|
||||
void FFX_Fetch_Face_Indices_U32(FfxUInt32 buffer_id, FFX_PARAMETER_OUT FfxUInt32x3 face3, FfxUInt32 offset, FfxUInt32 triangle_id)
|
||||
{
|
||||
face3 = LoadVertexBufferUInt3(buffer_id, (offset + FfxUInt32(12) * triangle_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
}
|
||||
|
||||
void FFX_Fetch_Face_Indices_U16(FfxUInt32 buffer_id, FFX_PARAMETER_OUT FfxUInt32x3 face3, FfxUInt32 offset, FfxUInt32 triangle_id)
|
||||
{
|
||||
FfxUInt32 word_offset = offset / 2;
|
||||
|
||||
FfxUInt32 word_id_0 = word_offset + triangle_id * FfxUInt32(3) + FfxUInt32(0);
|
||||
FfxUInt32 dword_id_0 = word_id_0 / FfxUInt32(2);
|
||||
FfxUInt32 shift_0 = FfxUInt32(16) * (word_id_0 & FfxUInt32(1));
|
||||
|
||||
FfxUInt32 word_id_1 = word_offset + triangle_id * FfxUInt32(3) + FfxUInt32(1);
|
||||
FfxUInt32 dword_id_1 = word_id_1 / FfxUInt32(2);
|
||||
FfxUInt32 shift_1 = FfxUInt32(16) * (word_id_1 & FfxUInt32(1));
|
||||
|
||||
FfxUInt32 word_id_2 = word_offset + triangle_id * FfxUInt32(3) + FfxUInt32(2);
|
||||
FfxUInt32 dword_id_2 = word_id_2 / FfxUInt32(2);
|
||||
FfxUInt32 shift_2 = FfxUInt32(16) * (word_id_2 & FfxUInt32(1));
|
||||
|
||||
FfxUInt32 u0 = LoadVertexBufferUInt(buffer_id, dword_id_0);
|
||||
u0 = (u0 >> shift_0) & FfxUInt32(0xFFFF);
|
||||
FfxUInt32 u1 = LoadVertexBufferUInt(buffer_id, dword_id_1);
|
||||
u1 = (u1 >> shift_1) & FfxUInt32(0xFFFF);
|
||||
FfxUInt32 u2 = LoadVertexBufferUInt(buffer_id, dword_id_2);
|
||||
u2 = (u2 >> shift_2) & FfxUInt32(0xFFFF);
|
||||
face3 = FfxUInt32x3(u0, u1, u2);
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_Fetch_float2(FfxUInt32 buffer_id, FfxUInt32 offset, FfxUInt32 vertex_id, FfxUInt32 stride)
|
||||
{
|
||||
return LoadVertexBufferFloat2(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_Fetch_float3(FfxUInt32 buffer_id, FfxUInt32 offset, FfxUInt32 vertex_id, FfxUInt32 stride)
|
||||
{
|
||||
return LoadVertexBufferFloat3(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
}
|
||||
|
||||
FfxFloat32x4 FFX_Fetch_float4(FfxUInt32 buffer_id, FfxUInt32 offset, FfxUInt32 vertex_id, FfxUInt32 stride)
|
||||
{
|
||||
return LoadVertexBufferFloat4(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_Fetch_Position(FfxUInt32 flags, FfxUInt32 buffer_id, FfxUInt32 offset, FfxUInt32 vertex_id, FfxUInt32 stride)
|
||||
{
|
||||
if (FFX_HAS_FLAG(flags, FFX_BRIXELIZER_INSTANCE_FLAG_USE_RGBA16_VERTEX)) {
|
||||
FfxUInt32x2 pack = LoadVertexBufferUInt2(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
|
||||
FfxFloat32x2 xy = ffxUnpackF32(pack.x);
|
||||
FfxFloat32x2 zw = ffxUnpackF32(pack.y);
|
||||
|
||||
return FfxFloat32x4(xy, zw).xyz;
|
||||
} else
|
||||
return LoadVertexBufferFloat3(buffer_id, (offset + stride * vertex_id) / FFX_BRIXELIZER_SIZEOF_UINT);
|
||||
}
|
||||
|
||||
FfxUInt32x3 FfxBrixelizerFetchFace(FfxUInt32 flags, FfxUInt32 indexBufferID, FfxUInt32 indexBufferOffset, FfxUInt32 triangle_idx)
|
||||
{
|
||||
if (FFX_HAS_FLAG(flags, FFX_BRIXELIZER_INSTANCE_FLAG_USE_INDEXLESS_QUAD_LIST)) { // Procedural quad index buffer
|
||||
FfxUInt32 quad_id = triangle_idx / FfxUInt32(2); // 2 triangles per quad
|
||||
FfxUInt32 base_vertex = quad_id * FfxUInt32(4); // 4 vertices per quad
|
||||
if (FFX_HAS_FLAG(triangle_idx, FfxUInt32(1))) {
|
||||
return FFX_BROADCAST_UINT32X3(base_vertex) + FfxUInt32x3(FfxUInt32(2), FfxUInt32(3), FfxUInt32(0));
|
||||
} else {
|
||||
return FFX_BROADCAST_UINT32X3(base_vertex) + FfxUInt32x3(FfxUInt32(0), FfxUInt32(1), FfxUInt32(2));
|
||||
}
|
||||
} else {
|
||||
FfxUInt32x3 face3;
|
||||
if (FFX_HAS_FLAG(flags, FFX_BRIXELIZER_INSTANCE_FLAG_USE_U16_INDEX)) {
|
||||
FFX_Fetch_Face_Indices_U16(indexBufferID, /* out */ face3, /* in */ indexBufferOffset, /* in */ triangle_idx);
|
||||
} else { // FFX_BRIXELIZER_INDEX_TYPE_U32
|
||||
FFX_Fetch_Face_Indices_U32(indexBufferID, /* out */ face3, /* in */ indexBufferOffset, /* in */ triangle_idx);
|
||||
}
|
||||
return face3;
|
||||
}
|
||||
}
|
||||
|
||||
FfxBrixelizerTrianglePos FfxBrixelizerFetchTriangle(FfxUInt32 flags, FfxUInt32 indexBufferID, FfxUInt32 indexBufferOffset, FfxUInt32 vertexBufferID, FfxUInt32 vertexBufferOffset, FfxUInt32 vertexBufferStride,
|
||||
FfxUInt32 instance_idx, FfxUInt32 triangle_idx)
|
||||
{
|
||||
FfxUInt32x3 face3 = FfxBrixelizerFetchFace(flags, indexBufferID, indexBufferOffset, triangle_idx);
|
||||
FfxFloat32x3 p0 = FFX_Fetch_Position(flags, vertexBufferID, vertexBufferOffset, face3.x, vertexBufferStride);
|
||||
FfxFloat32x3 p1 = FFX_Fetch_Position(flags, vertexBufferID, vertexBufferOffset, face3.y, vertexBufferStride);
|
||||
FfxFloat32x3 p2 = FFX_Fetch_Position(flags, vertexBufferID, vertexBufferOffset, face3.z, vertexBufferStride);
|
||||
FfxBrixelizerTrianglePos tri;
|
||||
|
||||
FfxFloat32x3x4 obj_to_anchor = LoadInstanceTransform(instance_idx);
|
||||
tri.face3 = face3;
|
||||
tri.wp0 = FFX_TRANSFORM_VECTOR(obj_to_anchor, FfxFloat32x4(p0, FfxFloat32(1.0))).xyz;
|
||||
tri.wp1 = FFX_TRANSFORM_VECTOR(obj_to_anchor, FfxFloat32x4(p1, FfxFloat32(1.0))).xyz;
|
||||
tri.wp2 = FFX_TRANSFORM_VECTOR(obj_to_anchor, FfxFloat32x4(p2, FfxFloat32(1.0))).xyz;
|
||||
return tri;
|
||||
}
|
||||
|
||||
FfxBrixelizerTrianglePos FfxBrixelizerFetchTriangle(FfxBrixelizerBasicMeshInfo mesh_info, FfxUInt32 instance_id, FfxUInt32 triangle_id)
|
||||
{
|
||||
return FfxBrixelizerFetchTriangle(mesh_info.flags, mesh_info.indexBufferID, mesh_info.indexBufferOffset, mesh_info.vertexBufferID, mesh_info.vertexBufferOffset,
|
||||
mesh_info.vertexStride, instance_id, triangle_id);
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_MESH_COMMON_H
|
||||
91
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_resources.h
vendored
Normal file
91
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_resources.h
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// 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_BRIXELIZER_RESOURCES_H
|
||||
#define FFX_BRIXELIZER_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CASCADE_AABB_TREE 1 // 24 elements
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CASCADE_AABB_TREES 1 // 24 elements (Same as the previous ID, used for binding the descriptor array)
|
||||
// The cascade octree previously occupied 24 elements here.
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CASCADE_BRICK_MAP 25 // 24 elements
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CASCADE_BRICK_MAPS 25 // 24 elements (Same as the previous ID, used for binding the descriptor array)
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CASCADE_READBACK_BUFFERS 49 // 3 * 24 elements
|
||||
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_INSTANCE_INFO_BUFFER 121
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_INSTANCE_TRANSFORM_BUFFER 122
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_JOB_BUFFER 123
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_JOB_INDEX_BUFFER 124
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_INDIRECT_ARGS_1 125
|
||||
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_COUNTERS 126
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_INDEX_SWAP 127
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_VOXEL_ALLOCATION_FAIL_COUNTER 128
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_BRICKS_STORAGE 129
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_BRICKS_STORAGE_OFFSETS 130
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_BRICKS_COMPRESSION_LIST 131
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_BRICKS_CLEAR_LIST 132
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_JOB_COUNTERS 133
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_JOB_COUNTERS_SCAN 134
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_JOB_GLOBAL_COUNTERS_SCAN 135
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_CR1_REFERENCES 136
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_CR1_COMPACTED_REFERENCES 137
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_CR1_REF_COUNTERS 138
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_CR1_REF_COUNTER_SCAN 139
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_CR1_REF_GLOBAL_SCAN 140
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_CR1_STAMP_SCAN 141
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_CR1_STAMP_GLOBAL_SCAN 142
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_DEBUG_AABBS 143
|
||||
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_BRICKS_VOXEL_MAP 144
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_BRICKS_AABB 145
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_BRICKS_FREE_LIST 146
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_BRICKS_CLEAR_LIST 147
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_BRICKS_EIKONAL_LIST 148
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_BRICKS_MERGE_LIST 149
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_BRICKS_EIKONAL_COUNTERS 150
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_COUNTERS 151
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_COUNTERS_READBACK_0 152
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_COUNTERS_READBACK_1 153
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_COUNTERS_READBACK_2 154
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_CONTEXT_SDF_ATLAS 155
|
||||
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_UPLOAD_INSTANCE_INFO_BUFFER 156
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_UPLOAD_INSTANCE_TRANSFORM_BUFFER 157
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_UPLOAD_JOB_BUFFER 158
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_UPLOAD_JOB_INDEX_BUFFER 159
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_DEBUG_OUTPUT 160
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_SCRATCH_BUFFER 161
|
||||
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_UPLOAD_DEBUG_INSTANCE_ID_BUFFER 162
|
||||
|
||||
#define FFX_BRIXELIZER_RESOURCE_IDENTIFIER_COUNT 163
|
||||
|
||||
#define FFX_BRIXELIZER_CONSTANTBUFFER_IDENTIFIER_CASCADE_INFO 0
|
||||
#define FFX_BRIXELIZER_CONSTANTBUFFER_IDENTIFIER_CONTEXT_INFO 1
|
||||
#define FFX_BRIXELIZER_CONSTANTBUFFER_IDENTIFIER_BUILD_INFO 2
|
||||
#define FFX_BRIXELIZER_CONSTANTBUFFER_IDENTIFIER_DEBUG_INFO 3
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif //!defined( FFX_BRIXELIZER_RESOURCES_H )
|
||||
354
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_trace_ops.h
vendored
Normal file
354
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizer/ffx_brixelizer_trace_ops.h
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
// 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_BRIXELIZER_TRACE_OPS_H
|
||||
#define FFX_BRIXELIZER_TRACE_OPS_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
|
||||
#include "ffx_brixelizer_host_gpu_shared.h"
|
||||
|
||||
FfxFloat32x3 LoadCascadeAABBTreesFloat3(FfxUInt32 cascadeID, FfxUInt32 elementIndex);
|
||||
FfxUInt32 LoadCascadeAABBTreesUInt(FfxUInt32 cascadeID, FfxUInt32 elementIndex);
|
||||
FfxUInt32 LoadBricksAABB(FfxUInt32 elementIndex);
|
||||
FfxBrixelizerCascadeInfo GetCascadeInfo(FfxUInt32 cascadeID);
|
||||
FfxFloat32 SampleSDFAtlas(FfxFloat32x3 uvw);
|
||||
FfxUInt32 LoadCascadeBrickMapArrayUniform(FfxUInt32 cascadeID, FfxUInt32 elementIndex);
|
||||
|
||||
#include "ffx_brixelizer_brick_common.h"
|
||||
|
||||
/// A structure encapsulating the parameters for a ray to be marched using Brixelizer.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
struct FfxBrixelizerRayDesc {
|
||||
FfxUInt32 start_cascade_id; ///< The index of the most detailed cascade for ray traversal.
|
||||
FfxUInt32 end_cascade_id; ///< The index of the least detailed cascade for ray traversal.
|
||||
FfxFloat32 t_min; ///< The minimum distance at which to accept a hit.
|
||||
FfxFloat32 t_max; ///< The maximum distance at which to accept a hit.
|
||||
FfxFloat32x3 origin; ///< The origin of the ray.
|
||||
FfxFloat32x3 direction; ///< The direction of the ray. This input should be normalized.
|
||||
};
|
||||
|
||||
/// A structure encapsulating all data associated with a ray SDF hit.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
struct FfxBrixelizerHitRaw {
|
||||
FfxFloat32 t; ///< The distance from the ray origin to the hit.
|
||||
FfxUInt32 brick_id; ///< The ID of a hit brick.
|
||||
FfxUInt32 uvwc; ///< Packed UVW coordinates of the hit location. UVW coordinates are in brick space.
|
||||
FfxUInt32 iter_count; ///< The count of iterations to find the intersection.
|
||||
};
|
||||
|
||||
/// A structure encapsulating minimal data associated with a ray SDF hit.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
struct FfxBrixelizerHit {
|
||||
FfxFloat32 t; ///< The distance from the ray origin to the hit.
|
||||
};
|
||||
|
||||
/// A structure encapsulating the distance to a ray hit and the normal of the surface hit.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
struct FfxBrixelizerHitWithNormal {
|
||||
FfxFloat32 t; ///< The distance from the ray origin to the hit.
|
||||
FfxFloat32x3 normal; ///< The normal of the SDF surface at the hit location.
|
||||
};
|
||||
|
||||
FfxFloat32 FfxBrixelizerGetIntersectCorner(FfxBrixelizerCascadeInfo CINFO, FfxFloat32x3 corner_sign, FfxFloat32x3 ray_cursor, FfxFloat32x3 ray_idirection, FfxFloat32 EPS, inout FfxUInt32x3 coord, FfxFloat32 voxel_k)
|
||||
{
|
||||
FfxFloat32x3 relative_cascade_origin = CINFO.grid_min - ray_cursor;
|
||||
coord = FfxUInt32x3(-relative_cascade_origin / (CINFO.voxel_size * voxel_k));
|
||||
FfxFloat32x3 node_max = relative_cascade_origin + (FfxFloat32x3(coord.x, coord.y, coord.z) + corner_sign) * (CINFO.voxel_size * voxel_k);
|
||||
FfxFloat32x3 tbot = ray_idirection * node_max;
|
||||
FfxFloat32 hit_max = min(tbot.x, min(tbot.y, tbot.z)) + EPS;
|
||||
return hit_max;
|
||||
}
|
||||
|
||||
/// This function is used for running a ray query against the Brixelizer SDF acceleration structure.
|
||||
/// The "raw" version returns the data immediately accessible from the SDF structure generated by a hit.
|
||||
///
|
||||
/// @param [in] ray_desc A structure encapsulating the parameters of the ray for ray traversal. See <c><i>FfxBrixelizerRayDesc</i></c>.
|
||||
/// @param [out] hit A structure of values to be filled in with details of any hit.
|
||||
///
|
||||
/// @retval
|
||||
/// true The ray hit the SDF and hit data has been written to the <c><i>hit</i></c> parameter.
|
||||
/// @retval
|
||||
/// false The ray did not intersect the SDF and no hit data has been written.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FfxBoolean FfxBrixelizerTraverseRaw(in FfxBrixelizerRayDesc ray_desc, out FfxBrixelizerHitRaw hit)
|
||||
{
|
||||
FfxUInt32 cascade_id = ray_desc.start_cascade_id;
|
||||
FfxUInt32 g_end_cascade = ray_desc.end_cascade_id;
|
||||
|
||||
FfxFloat32x3 ray_origin = ray_desc.origin;
|
||||
FfxFloat32 ray_t = ray_desc.t_min;
|
||||
FfxFloat32x3 ray_direction = ray_desc.direction;
|
||||
FfxFloat32x3 ray_idirection = FfxFloat32(1.0) / ray_desc.direction;
|
||||
FfxFloat32x3 corner_sign = FfxFloat32x3(
|
||||
ray_direction.x > FfxFloat32(0.0) ? FfxFloat32(1.0) : FfxFloat32(0.0),
|
||||
ray_direction.y > FfxFloat32(0.0) ? FfxFloat32(1.0) : FfxFloat32(0.0),
|
||||
ray_direction.z > FfxFloat32(0.0) ? FfxFloat32(1.0) : FfxFloat32(0.0)
|
||||
);
|
||||
hit.iter_count = 0;
|
||||
FfxUInt32 local_iter_cnt = 0;
|
||||
cascade_id = ffxWaveMin(cascade_id);
|
||||
for (; cascade_id <= g_end_cascade; cascade_id++) {
|
||||
cascade_id = ffxWaveReadLaneFirstU1(cascade_id);
|
||||
FfxBrixelizerCascadeInfo CINFO = GetCascadeInfo(cascade_id);
|
||||
const FfxFloat32 voxel_size = CINFO.voxel_size;
|
||||
local_iter_cnt = 0;
|
||||
|
||||
FfxFloat32 orig_ray_t = ray_t;
|
||||
|
||||
FfxFloat32 EPS = CINFO.voxel_size / FfxFloat32(1024.0);
|
||||
FfxFloat32 cascade_hit_min;
|
||||
FfxFloat32 cascade_hit_max;
|
||||
FfxFloat32x3 ray_cursor = ray_origin + ray_direction * ray_t;
|
||||
FfxFloat32 top_level_max;
|
||||
const FfxUInt32 ITER_LIMIT = 32;
|
||||
FfxFloat32x3 cascade_aabb_min = LoadCascadeAABBTreesFloat3(cascade_id, (16 * 16 * 16) + (2 * 4 * 4 * 4 + 0) * 3);
|
||||
FfxFloat32x3 cascade_aabb_max = LoadCascadeAABBTreesFloat3(cascade_id, (16 * 16 * 16) + (2 * 4 * 4 * 4 + 1) * 3);
|
||||
|
||||
// if the ray cursor isn't inside the current cascade skip to the next one
|
||||
if (!((CINFO.is_enabled > 0) && all(FFX_GREATER_THAN(ray_cursor, CINFO.grid_min)) && all(FFX_LESS_THAN(ray_cursor, CINFO.grid_max)))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FfxBrixelizerIntersectAABB(ray_origin, ray_idirection, cascade_aabb_min, cascade_aabb_max,
|
||||
/* out */ cascade_hit_min,
|
||||
/* out */ cascade_hit_max)) {
|
||||
FfxFloat32 stamp_size = FfxFloat32(16.0);
|
||||
FfxUInt32 level = 0;
|
||||
cascade_hit_max = min(cascade_hit_max, ray_desc.t_max);
|
||||
|
||||
while (ray_t < cascade_hit_max) {
|
||||
hit.iter_count++;
|
||||
local_iter_cnt++;
|
||||
if (local_iter_cnt > ITER_LIMIT)
|
||||
break;
|
||||
|
||||
ray_cursor = ray_origin + ray_direction * ray_t;
|
||||
|
||||
FfxFloat32x3 stamp_aabb_min;
|
||||
FfxFloat32x3 stamp_aabb_max;
|
||||
|
||||
FfxUInt32x3 stamp_coord;
|
||||
FfxFloat32 stamp_hit_max = ray_t + FfxBrixelizerGetIntersectCorner(CINFO, corner_sign, ray_cursor, ray_idirection, EPS, /* inout */ stamp_coord, stamp_size);
|
||||
FfxUInt32 stamp_idx = FfxBrixelizerFlattenPOT(stamp_coord, FfxUInt32(2) << level);
|
||||
if (level == 0) {
|
||||
top_level_max = stamp_hit_max;
|
||||
stamp_aabb_min = LoadCascadeAABBTreesFloat3(cascade_id, (16 * 16 * 16) + (2 * stamp_idx + 0) * 3);
|
||||
stamp_aabb_max = LoadCascadeAABBTreesFloat3(cascade_id, (16 * 16 * 16) + (2 * stamp_idx + 1) * 3);
|
||||
} else {
|
||||
FfxUInt32 bottom_stamp_pack = LoadCascadeAABBTreesUInt(cascade_id, stamp_idx);
|
||||
if (bottom_stamp_pack == FFX_BRIXELIZER_INVALID_BOTTOM_AABB_NODE) {
|
||||
stamp_aabb_min = FFX_BROADCAST_FLOAT32X3(0.0);
|
||||
stamp_aabb_max = FFX_BROADCAST_FLOAT32X3(0.0);
|
||||
} else {
|
||||
FfxUInt32x3 bottom_iaabb_min = FfxBrixelizerUnflattenPOT(bottom_stamp_pack & 0x7fff, 5);
|
||||
FfxUInt32x3 bottom_iaabb_max = FfxBrixelizerUnflattenPOT((bottom_stamp_pack >> 16) & 0x7fff, 5);
|
||||
FfxFloat32x3 bottom_stamp_world_coord = FfxFloat32x3(stamp_coord) * CINFO.voxel_size * FfxFloat32(4.0) + CINFO.grid_min;
|
||||
stamp_aabb_min = bottom_stamp_world_coord + FfxFloat32x3(bottom_iaabb_min) * CINFO.voxel_size / FfxFloat32(8.0);
|
||||
stamp_aabb_max = bottom_stamp_world_coord + FfxFloat32x3(bottom_iaabb_max + FFX_BROADCAST_UINT32X3(1)) * CINFO.voxel_size / FfxFloat32(8.0);
|
||||
}
|
||||
}
|
||||
|
||||
FfxFloat32 stamp_aabb_hit_max;
|
||||
FfxFloat32 stamp_aabb_hit_min;
|
||||
if (ffxAsUInt32(stamp_aabb_min.x) == ffxAsUInt32(stamp_aabb_max.x) || !FfxBrixelizerIntersectAABB(ray_origin, ray_idirection, stamp_aabb_min, stamp_aabb_max,
|
||||
/* out */ stamp_aabb_hit_min,
|
||||
/* out */ stamp_aabb_hit_max)) { // empty node
|
||||
ray_t = stamp_hit_max; // Advance the ray
|
||||
if (level == 0) {
|
||||
continue;
|
||||
} else {
|
||||
if (ray_t > top_level_max) {
|
||||
level = 0;
|
||||
stamp_size = FfxFloat32(16.0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (level == 0) {
|
||||
level = 1;
|
||||
stamp_size = FfxFloat32(4.0);
|
||||
continue;
|
||||
} else {
|
||||
stamp_aabb_hit_max = min(stamp_aabb_hit_max, ray_desc.t_max);
|
||||
|
||||
while (ray_t < stamp_aabb_hit_max) {
|
||||
hit.iter_count++;
|
||||
local_iter_cnt++;
|
||||
if (local_iter_cnt > ITER_LIMIT)
|
||||
break;
|
||||
|
||||
ray_cursor = ray_origin + ray_direction * ray_t;
|
||||
|
||||
FfxUInt32x3 voxel;
|
||||
FfxFloat32 voxel_hit_max = FfxBrixelizerGetIntersectCorner(CINFO, corner_sign, ray_cursor, ray_idirection, EPS, /* inout */ voxel, FfxFloat32(1.0));
|
||||
if (voxel_hit_max < EPS) {
|
||||
ray_t = ray_t + voxel_hit_max;
|
||||
break;
|
||||
}
|
||||
voxel_hit_max += ray_t;
|
||||
FfxUInt32 brick_id = FfxBrixelizerLoadBrickIDUniform(FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(CINFO, voxel), 6), cascade_id);
|
||||
if (brick_id == FFX_BRIXELIZER_UNINITIALIZED_ID) {
|
||||
hit.iter_count = ITER_LIMIT + 1;
|
||||
local_iter_cnt = ITER_LIMIT + 1;
|
||||
break;
|
||||
}
|
||||
if (FfxBrixelizerIsValidID(brick_id)) {
|
||||
FfxFloat32x3 voxel_min = FfxFloat32x3(voxel.x, voxel.y, voxel.z) * CINFO.voxel_size + CINFO.grid_min;
|
||||
FfxUInt32 brick_aabb_pack = LoadBricksAABB(FfxBrixelizerBrickGetIndex(brick_id));
|
||||
FfxUInt32x3 brick_aabb_umin = FfxBrixelizerUnflattenPOT(brick_aabb_pack & ((1 << 9) - 1), 3);
|
||||
FfxUInt32x3 brick_aabb_umax = FfxBrixelizerUnflattenPOT((brick_aabb_pack >> 9) & ((1 << 9) - 1), 3) + FFX_BROADCAST_UINT32X3(1);
|
||||
FfxFloat32x3 brick_aabb_min = voxel_min - FFX_BROADCAST_FLOAT32X3(CINFO.voxel_size / FfxFloat32(2.0 * 7.0)) + FfxFloat32x3(brick_aabb_umin) * (CINFO.voxel_size / FfxFloat32(7.0));
|
||||
FfxFloat32x3 brick_aabb_max = voxel_min - FFX_BROADCAST_FLOAT32X3(CINFO.voxel_size / FfxFloat32(2.0 * 7.0)) + FfxFloat32x3(brick_aabb_umax) * (CINFO.voxel_size / FfxFloat32(7.0));
|
||||
FfxFloat32 brick_hit_min;
|
||||
FfxFloat32 brick_hit_max;
|
||||
if (FfxBrixelizerIntersectAABB(ray_cursor, ray_idirection, brick_aabb_min, brick_aabb_max,
|
||||
/* out */ brick_hit_min,
|
||||
/* out */ brick_hit_max)) {
|
||||
|
||||
FfxFloat32x3 uvw = (ray_cursor + brick_hit_min * ray_direction - voxel_min) * CINFO.ivoxel_size;
|
||||
FfxFloat32 dist = FfxFloat32(1.0);
|
||||
FfxFloat32 total_dist = 0.0f;
|
||||
FfxFloat32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
|
||||
FfxFloat32x3 uvw_min = (brick_offset + FFX_BROADCAST_FLOAT32X3(FfxFloat32(0.5))) / FfxFloat32(FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE);
|
||||
FfxFloat32x3 uvw_max = uvw_min + FFX_BROADCAST_FLOAT32X3(FfxFloat32(7.0)) / FfxFloat32(FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE);
|
||||
for (FfxUInt32 i = 0; i < 8; i++) {
|
||||
hit.iter_count++;
|
||||
dist = FfxBrixelizerSampleBrixelDistance(uvw_min, uvw_max, uvw) - FFX_BRIXELIZER_TRAVERSAL_EPS;
|
||||
if (dist < FFX_BRIXELIZER_TRAVERSAL_EPS) {
|
||||
hit.t = ray_t + brick_hit_min + total_dist * voxel_size;
|
||||
if (hit.t > ray_desc.t_max) {
|
||||
return false;
|
||||
}
|
||||
|
||||
hit.brick_id = brick_id;
|
||||
hit.uvwc = PackUVWC(FfxFloat32x4(uvw, 0.0));
|
||||
return true;
|
||||
}
|
||||
uvw += ray_direction * dist;
|
||||
total_dist += dist;
|
||||
if (any(FFX_GREATER_THAN(abs(uvw - FFX_BROADCAST_FLOAT32X3(0.5)), FFX_BROADCAST_FLOAT32X3(0.501))))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ray_t = voxel_hit_max;
|
||||
}
|
||||
if (ray_t > top_level_max) {
|
||||
level = 0;
|
||||
stamp_size = FfxFloat32(16.0);
|
||||
}
|
||||
if (local_iter_cnt > ITER_LIMIT)
|
||||
break;
|
||||
ray_t = stamp_hit_max;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (local_iter_cnt > ITER_LIMIT) {
|
||||
ray_t = max(orig_ray_t, ray_t - CINFO.voxel_size);
|
||||
continue;
|
||||
}
|
||||
|
||||
// advance ray to end of current cascade
|
||||
FfxBrixelizerIntersectAABB(ray_origin, ray_idirection, CINFO.grid_min, CINFO.grid_max, /* out */ cascade_hit_min, /* out */ cascade_hit_max);
|
||||
ray_t = max(orig_ray_t, cascade_hit_max - CINFO.voxel_size);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Calculate a normal from a hit described by an <c><i>FfxBrixelizerHitRaw</i></c> structure.
|
||||
///
|
||||
/// @param [in] hit A ray hit with the SDF returned by <c><i>FfxBrixelizerTraverseRaw</i></c>.
|
||||
///
|
||||
/// @retval A normal to the hit described by the <c><i>hit</i></c> paramter.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FfxFloat32x3 FfxBrixelizerGetHitNormal(FfxBrixelizerHitRaw hit)
|
||||
{
|
||||
FfxFloat32x3 uvw = FfxFloat32x3(
|
||||
FfxBrixelizerUnpackUnsigned8Bits((hit.uvwc >> 0) & 0xff),
|
||||
FfxBrixelizerUnpackUnsigned8Bits((hit.uvwc >> 8) & 0xff),
|
||||
FfxBrixelizerUnpackUnsigned8Bits((hit.uvwc >> 16) & 0xff)
|
||||
);
|
||||
uvw += FFX_BROADCAST_FLOAT32X3(1.0 / 512.0);
|
||||
FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(hit.brick_id);
|
||||
FfxFloat32x3 uvw_min = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(0.5)) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
FfxFloat32x3 uvw_max = (FfxFloat32x3(brick_offset) + FFX_BROADCAST_FLOAT32X3(float(8.0 - 0.5))) / FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE;
|
||||
return FfxBrixelizerGetBrixelGrad(uvw_min, uvw_max, uvw);
|
||||
}
|
||||
|
||||
/// This function is used for running a ray query against the Brixelizer SDF acceleration structure.
|
||||
/// This version simply returns the distance to a hit if a hit is encountered.
|
||||
///
|
||||
/// @param [in] ray_desc A structure encapsulating the parameters of the ray for ray traversal. See <c><i>FfxBrixelizerRayDesc</i></c>.
|
||||
/// @param [out] hit A structure of values to be filled in with details of any hit.
|
||||
///
|
||||
/// @retval
|
||||
/// true The ray hit the SDF and hit data has been written to the <c><i>hit</i></c> parameter.
|
||||
/// @retval
|
||||
/// false The ray did not intersect the SDF and no hit data has been written.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FfxBoolean FfxBrixelizerTraverse(FfxBrixelizerRayDesc ray_desc, out FfxBrixelizerHit hit)
|
||||
{
|
||||
FfxBrixelizerHitRaw raw_payload;
|
||||
FfxBoolean result = FfxBrixelizerTraverseRaw(ray_desc, raw_payload);
|
||||
hit.t = raw_payload.t;
|
||||
return result;
|
||||
}
|
||||
|
||||
/// This function is used for running a ray query against the Brixelizer SDF acceleration structure.
|
||||
/// This version returns the distance to a hit and a normal to the SDF geometry at a hit location when a hit
|
||||
/// is encountered.
|
||||
///
|
||||
///
|
||||
/// @param [in] ray_desc A structure encapsulating the parameters of the ray for ray traversal. See <c><i>FfxBrixelizerRayDesc</i></c>.
|
||||
/// @param [out] hit A structure of values to be filled in with details of any hit.
|
||||
///
|
||||
/// @retval
|
||||
/// true The ray hit the SDF and hit data has been written to the <c><i>hit</i></c> parameter.
|
||||
/// @retval
|
||||
/// false The ray did not intersect the SDF and no hit data has been written.
|
||||
///
|
||||
/// @ingroup Brixelizer
|
||||
FfxBoolean FfxBrixelizerTraverseWithNormal(FfxBrixelizerRayDesc ray_desc, out FfxBrixelizerHitWithNormal hit)
|
||||
{
|
||||
FfxBrixelizerHitRaw raw_payload;
|
||||
FfxBoolean result = FfxBrixelizerTraverseRaw(ray_desc, raw_payload);
|
||||
if (!result) {
|
||||
return false;
|
||||
}
|
||||
hit.t = raw_payload.t;
|
||||
hit.normal = FfxBrixelizerGetHitNormal(raw_payload);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_TRACE_OPS_H
|
||||
68
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/CMakeCompileBrixelizerGIShaders.txt
vendored
Normal file
68
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/CMakeCompileBrixelizerGIShaders.txt
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# 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(BRIXELIZER_GI_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(BRIXELIZER_GI_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/brixelizer"
|
||||
"${FFX_GPU_PATH}/brixelizergi")
|
||||
|
||||
set(BRIXELIZER_GI_PERMUTATION_ARGS
|
||||
-DFFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED={0,1}
|
||||
-DFFX_BRIXELIZER_GI_OPTION_DISABLE_SPECULAR={0,1}
|
||||
-DFFX_BRIXELIZER_GI_OPTION_DISABLE_DENOISER={0,1})
|
||||
|
||||
if (NOT BRIXELIZER_GI_SHADER_EXT)
|
||||
set(BRIXELIZER_GI_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB BRIXELIZER_GI_SHADERS
|
||||
"shaders/brixelizergi/ffx_brixelizergi_blur_x.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_blur_y.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_clear_cache.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_debug_visualization.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_downsample.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_emit_irradiance_cache.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_emit_primary_ray_radiance.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_fill_screen_probes.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_generate_disocclusion_mask.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_interpolate_screen_probes.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_prepare_clear_cache.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_project_screen_probes.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_propagate_sh.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_reproject_gi.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_reproject_screen_probes.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_spawn_screen_probes.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_specular_pre_trace.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_specular_trace.${BRIXELIZER_GI_SHADER_EXT}"
|
||||
"shaders/brixelizergi/ffx_brixelizergi_upsample.${BRIXELIZER_GI_SHADER_EXT}")
|
||||
|
||||
# compile all the shaders
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${BRIXELIZER_GI_BASE_ARGS}" "${BRIXELIZER_GI_API_BASE_ARGS}" "${BRIXELIZER_GI_PERMUTATION_ARGS}" "${BRIXELIZER_GI_INCLUDE_ARGS}"
|
||||
"${BRIXELIZER_GI_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" BRIXELIZER_GI_PERMUTATION_OUTPUTS)
|
||||
|
||||
# add the header files they generate to the main list of dependencies
|
||||
add_shader_output("${BRIXELIZER_GI_PERMUTATION_OUTPUTS}")
|
||||
1269
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_callbacks_glsl.h
vendored
Normal file
1269
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_callbacks_glsl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1246
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_callbacks_hlsl.h
vendored
Normal file
1246
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_callbacks_hlsl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
143
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_common.h
vendored
Normal file
143
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_common.h
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// 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_BRIXELIZER_GI_COMMON_H
|
||||
#define FFX_BRIXELIZER_GI_COMMON_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
|
||||
struct FfxRay
|
||||
{
|
||||
FfxBoolean valid;
|
||||
FfxFloat32 roughness;
|
||||
FfxFloat32x3 camera_pos;
|
||||
FfxFloat32x3 normal;
|
||||
FfxFloat32x3 origin;
|
||||
FfxFloat32x3 direction;
|
||||
FfxFloat32x3 major_direction;
|
||||
};
|
||||
|
||||
FfxBoolean ffxIsBackground(FfxFloat32 depth)
|
||||
{
|
||||
#if FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED == 1
|
||||
return depth < 1.e-12f;
|
||||
# else // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
return depth >= (1.0f - 1.e-12f);
|
||||
# endif // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxViewSpaceToWorldSpace(FfxFloat32x4 view_space_coord)
|
||||
{
|
||||
return FFX_MATRIX_MULTIPLY(GetInverseViewMatrix(), view_space_coord).xyz;
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxPreviousViewSpaceToWorldSpace(FfxFloat32x4 view_space_coord)
|
||||
{
|
||||
return FFX_MATRIX_MULTIPLY(GetPreviousInverseViewMatrix(), view_space_coord).xyz;
|
||||
}
|
||||
|
||||
// Transforms origin to uv space
|
||||
// Mat must be able to transform origin from its current space into clip space.
|
||||
FfxFloat32x3 ffxProjectPosition(FfxFloat32x3 origin, FfxFloat32x4x4 mat)
|
||||
{
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(mat, FfxFloat32x4(origin, FfxFloat32(1.0)));
|
||||
projected.xyz /= projected.w;
|
||||
projected.xy = FfxFloat32(0.5) * projected.xy + FfxFloat32(0.5);
|
||||
projected.y = (FfxFloat32(1.0) - projected.y);
|
||||
return projected.xyz;
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxInvProjectPosition(FfxFloat32x3 coord, FfxFloat32x4x4 mat)
|
||||
{
|
||||
coord.y = (FfxFloat32(1.0) - coord.y);
|
||||
coord.xy = FfxFloat32(2.0) * coord.xy - FfxFloat32(1.0);
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(mat, FfxFloat32x4(coord, FfxFloat32(1.0)));
|
||||
projected.xyz /= projected.w;
|
||||
return projected.xyz;
|
||||
}
|
||||
|
||||
FfxFloat32 ffxGetLinearDepth(FfxFloat32x2 uv, FfxFloat32 depth)
|
||||
{
|
||||
const FfxFloat32x3 view_space_pos = ffxInvProjectPosition(FfxFloat32x3(uv, depth), GetInverseProjectionMatrix());
|
||||
return abs(view_space_pos.z);
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxScreenSpaceToViewSpace(FfxFloat32x3 screen_uv_coord)
|
||||
{
|
||||
return ffxInvProjectPosition(screen_uv_coord, GetInverseProjectionMatrix());
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxPreviousScreenSpaceToViewSpace(FfxFloat32x3 screen_uv_coord)
|
||||
{
|
||||
return ffxInvProjectPosition(screen_uv_coord, GetPreviousInverseProjectionMatrix());
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxGetWorldPosition(FfxFloat32x2 uv, FfxFloat32 depth)
|
||||
{
|
||||
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, depth);
|
||||
FfxFloat32x3 view_space_position = ffxScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
||||
FfxFloat32x3 world_space_origin = ffxViewSpaceToWorldSpace(FfxFloat32x4(view_space_position, 1.0)).xyz;
|
||||
return world_space_origin;
|
||||
}
|
||||
|
||||
FfxFloat32x3 ffxGetPreviousWorldPosition(FfxFloat32x2 uv, FfxFloat32 depth)
|
||||
{
|
||||
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, depth);
|
||||
FfxFloat32x3 view_space_position = ffxPreviousScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
||||
FfxFloat32x3 world_space_origin = ffxPreviousViewSpaceToWorldSpace(FfxFloat32x4(view_space_position, 1.0)).xyz;
|
||||
return world_space_origin;
|
||||
}
|
||||
|
||||
#if FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED == 1
|
||||
FFX_STATIC const FfxFloat32 FfxBrixelizerGIFrontendConstants_BackgroundDepth = FfxFloat32(0.0);
|
||||
#else // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
FFX_STATIC const FfxFloat32 FfxBrixelizerGIFrontendConstants_BackgroundDepth = FfxFloat32(1.0);
|
||||
#endif // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
|
||||
FfxBoolean FfxBrixelizerGIIsDepthACloserThanB(FfxFloat32 a, FfxFloat32 b)
|
||||
{
|
||||
#if FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED == 1
|
||||
return a > b;
|
||||
#else // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
return a < b;
|
||||
#endif // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerGIDepthCloserOp(FfxFloat32 a, FfxFloat32 b)
|
||||
{
|
||||
#ifdef FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
return max(a, b);
|
||||
#else // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
return min(a, b);
|
||||
#endif // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
}
|
||||
|
||||
FfxFloat32 FfxBrixelizerGIDepthFarthestOp(FfxFloat32 a, FfxFloat32 b)
|
||||
{
|
||||
#if FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED == 1
|
||||
return min(a, b);
|
||||
#else // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
return max(a, b);
|
||||
#endif // !FFX_BRIXELIZER_GI_OPTION_DEPTH_INVERTED
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_GI_COMMON_H
|
||||
109
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_host_interface.h
vendored
Normal file
109
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_host_interface.h
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
// 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_BRIXELIZER_GI_HOST_INTERFACE_H
|
||||
#define FFX_BRIXELIZER_GI_HOST_INTERFACE_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
|
||||
#define FFX_BRIXELIZER_GI_INVALID_ID 0x00FFFFFFu
|
||||
|
||||
struct FfxBrixelizerGITracingConstants
|
||||
{
|
||||
FfxUInt32 start_cascade;
|
||||
FfxUInt32 end_cascade;
|
||||
FfxUInt32 debug_state;
|
||||
FfxUInt32 debug_traversal_state;
|
||||
|
||||
FfxFloat32 ray_pushoff;
|
||||
FfxFloat32 sdf_solve_eps;
|
||||
FfxFloat32 specular_ray_pushoff;
|
||||
FfxFloat32 specular_sdf_solve_eps;
|
||||
|
||||
FfxFloat32 preview_ray_pushoff;
|
||||
FfxFloat32 preview_sdf_solve_eps;
|
||||
FfxFloat32 t_min;
|
||||
FfxFloat32 t_max;
|
||||
};
|
||||
|
||||
struct FfxBrixelizerGIConstants
|
||||
{
|
||||
FfxFloat32x4x4 view;
|
||||
FfxFloat32x4x4 view_proj;
|
||||
FfxFloat32x4x4 inv_view;
|
||||
FfxFloat32x4x4 inv_proj;
|
||||
FfxFloat32x4x4 inv_view_proj;
|
||||
FfxFloat32x4x4 prev_view_proj;
|
||||
FfxFloat32x4x4 prev_inv_view;
|
||||
FfxFloat32x4x4 prev_inv_proj;
|
||||
|
||||
FfxUInt32 target_height;
|
||||
FfxUInt32 target_width;
|
||||
FfxFloat32 environmentMapIntensity;
|
||||
FfxUInt32 roughnessChannel;
|
||||
|
||||
FfxUInt32 isRoughnessPerceptual;
|
||||
FfxFloat32 roughnessThreshold;
|
||||
FfxFloat32 normalsUnpackMul;
|
||||
FfxFloat32 normalsUnpackAdd;
|
||||
|
||||
FfxFloat32x2 motionVectorScale;
|
||||
FfxUInt32 debug_type;
|
||||
FfxFloat32 _padding;
|
||||
|
||||
FfxUInt32x2 buffer_dimensions;
|
||||
FfxUInt32x2 probe_buffer_dimensions;
|
||||
|
||||
FfxFloat32x2 buffer_dimensions_f32;
|
||||
FfxFloat32x2 ibuffer_dimensions;
|
||||
|
||||
FfxFloat32x2 probe_buffer_dimensions_f32;
|
||||
FfxFloat32x2 iprobe_buffer_dimensions;
|
||||
|
||||
FfxUInt32x2 tile_buffer_dimensions;
|
||||
FfxFloat32x2 tile_buffer_dimensions_f32;
|
||||
|
||||
FfxUInt32x2 brick_tile_buffer_dimensions;
|
||||
FfxFloat32x2 brick_tile_buffer_dimensions_f32;
|
||||
|
||||
FfxFloat32x3 camera_position;
|
||||
FfxUInt32 frame_index;
|
||||
|
||||
FfxBrixelizerGITracingConstants tracing_constants;
|
||||
};
|
||||
|
||||
struct FfxBrixelizerGIPassConstants
|
||||
{
|
||||
FfxUInt32 cascade_idx;
|
||||
FfxFloat32 energy_decay_k;
|
||||
FfxUInt32x2 _padding;
|
||||
};
|
||||
|
||||
struct FfxBrixelizerGIScalingConstants
|
||||
{
|
||||
FfxUInt32x2 sourceSize;
|
||||
FfxUInt32x2 downsampledSize;
|
||||
FfxUInt32 roughnessChannel;
|
||||
FfxUInt32x3 _padding;
|
||||
};
|
||||
|
||||
#endif // FFX_BRIXELIZER_GI_HOST_INTERFACE_H
|
||||
2029
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_main.h
vendored
Normal file
2029
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_main.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
604
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_probe_shading.h
vendored
Normal file
604
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_probe_shading.h
vendored
Normal file
@@ -0,0 +1,604 @@
|
||||
// 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_BRIXELIZER_GI_PROBE_SHADING_H
|
||||
#define FFX_BRIXELIZER_GI_PROBE_SHADING_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
|
||||
FfxFloat32 FfxBrixelizerGIGetLuminance(FfxFloat32x3 color)
|
||||
{
|
||||
return dot(color, FfxFloat32x3(FfxFloat32(0.299), FfxFloat32(0.587), FfxFloat32(0.114)));
|
||||
}
|
||||
|
||||
#define FFX_BRIXELIZER_GI_LUMINANCE_WEIGHT FfxFloat32(0.2)
|
||||
FfxFloat32 FfxBrixelizerGIGetLuminanceWeight(FfxFloat32x3 radiance, FfxFloat32 weight_k)
|
||||
{
|
||||
return exp(-weight_k * FfxBrixelizerGIGetLuminance(radiance));
|
||||
}
|
||||
|
||||
#define FFX_BRIXELIZER_GI_PI FfxFloat32(3.141592653589793238463)
|
||||
// Reference:
|
||||
// https://en.wikipedia.org/wiki/Table_of_spherical_harmonics#Real_spherical_harmonics with |r| == 1
|
||||
// https://cseweb.ucsd.edu/~ravir/papers/envmap/envmap.pdf
|
||||
#define FFX_BRIXELIZER_GI_SH_C0 FfxFloat32(0.2820947917738781) // 0.5 * math.sqrt(1.0 / math.pi)
|
||||
#define FFX_BRIXELIZER_GI_SH_C1 FfxFloat32(0.4886025119029199) // 0.5 * math.sqrt(3.0 / math.pi)
|
||||
#define FFX_BRIXELIZER_GI_SH_2_PI_3 ((FfxFloat32(2.0) * FFX_BRIXELIZER_GI_PI) / FfxFloat32(3.0))
|
||||
#define FFX_BRIXELIZER_GI_SH_PI_4 (FFX_BRIXELIZER_GI_PI / FfxFloat32(4.0))
|
||||
#define FFX_BRIXELIZER_GI_SH_C4 FfxFloat32(1.0925484305920792) // 0.5 * math.sqrt(15.0 / math.pi)
|
||||
#define FFX_BRIXELIZER_GI_SH_C5 FfxFloat32(0.31539156525252005) // 0.25 * math.sqrt(5.0 / math.pi))
|
||||
#define FFX_BRIXELIZER_GI_SH_C6 FfxFloat32(0.5462742152960396) // 0.25 * math.sqrt(15.0 / math.pi)
|
||||
#define FFX_BRIXELIZER_GI_SH_C7 FfxFloat32(0.24770795610037571) // math.pi / 4.0 * 0.25 * math.sqrt(5.0 / (math.pi))
|
||||
#define FFX_BRIXELIZER_GI_SH_C8 FfxFloat32(1.023326707946489) // math.sqrt(math.pi / 3)
|
||||
#define FFX_BRIXELIZER_GI_SH_C9 FfxFloat32(0.8862269254527579) // math.sqrt(math.pi / 3)
|
||||
#define FFX_BRIXELIZER_GI_SH_C10 FfxFloat32(0.8580855308097834) // math.sqrt(math.pi * 15.0 / (16.0 * 4.0))
|
||||
#define FFX_BRIXELIZER_GI_SH_C11 FfxFloat32(0.4290427654048917) // math.sqrt(3.0 * 2.0 * math.pi) / math.sqrt(64.0 * 8.0 / 5.0)
|
||||
|
||||
// We use 3 bands(9 coefficients)
|
||||
void FfxBrixelizerGISHGetCoefficients(FfxFloat32x3 direction, out FfxFloat32 coefficients[9])
|
||||
{
|
||||
coefficients[0] = FfxFloat32(1.0);
|
||||
|
||||
coefficients[1] = direction.y;
|
||||
coefficients[2] = direction.z;
|
||||
coefficients[3] = direction.x;
|
||||
|
||||
coefficients[4] = direction.x * direction.y;
|
||||
coefficients[5] = direction.y * direction.z;
|
||||
coefficients[6] = FfxFloat32(3.0) * direction.z * direction.z - FfxFloat32(1.0);
|
||||
coefficients[7] = direction.x * direction.z;
|
||||
coefficients[8] = direction.x * direction.x - direction.y * direction.y;
|
||||
|
||||
//
|
||||
|
||||
coefficients[0] = coefficients[0] * FFX_BRIXELIZER_GI_SH_C0;
|
||||
|
||||
coefficients[1] = coefficients[1] * FFX_BRIXELIZER_GI_SH_C1;
|
||||
coefficients[2] = coefficients[2] * FFX_BRIXELIZER_GI_SH_C1;
|
||||
coefficients[3] = coefficients[3] * FFX_BRIXELIZER_GI_SH_C1;
|
||||
|
||||
coefficients[4] = coefficients[4] * FFX_BRIXELIZER_GI_SH_C4;
|
||||
coefficients[5] = coefficients[5] * FFX_BRIXELIZER_GI_SH_C4;
|
||||
coefficients[6] = coefficients[6] * FFX_BRIXELIZER_GI_SH_C5;
|
||||
coefficients[7] = coefficients[7] * FFX_BRIXELIZER_GI_SH_C4;
|
||||
coefficients[8] = coefficients[8] * FFX_BRIXELIZER_GI_SH_C6;
|
||||
}
|
||||
|
||||
void FfxBrixelizerGISHGetCoefficients16(FfxFloat32x3 direction, out FFX_MIN16_F coefficients[9])
|
||||
{
|
||||
coefficients[0] = FFX_MIN16_F(1.0);
|
||||
|
||||
coefficients[1] = FFX_MIN16_F(direction.y);
|
||||
coefficients[2] = FFX_MIN16_F(direction.z);
|
||||
coefficients[3] = FFX_MIN16_F(direction.x);
|
||||
|
||||
coefficients[4] = FFX_MIN16_F(direction.x * direction.y);
|
||||
coefficients[5] = FFX_MIN16_F(direction.y * direction.z);
|
||||
coefficients[6] = FFX_MIN16_F(3.0) * FFX_MIN16_F(direction.z * direction.z) - FFX_MIN16_F(1.0);
|
||||
coefficients[7] = FFX_MIN16_F(direction.x * direction.z);
|
||||
coefficients[8] = FFX_MIN16_F(direction.x * direction.x - direction.y * direction.y);
|
||||
|
||||
//
|
||||
|
||||
coefficients[0] = coefficients[0] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C0);
|
||||
|
||||
coefficients[1] = coefficients[1] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C1);
|
||||
coefficients[2] = coefficients[2] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C1);
|
||||
coefficients[3] = coefficients[3] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C1);
|
||||
|
||||
coefficients[4] = coefficients[4] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C4);
|
||||
coefficients[5] = coefficients[5] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C4);
|
||||
coefficients[6] = coefficients[6] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C5);
|
||||
coefficients[7] = coefficients[7] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C4);
|
||||
coefficients[8] = coefficients[8] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_C6);
|
||||
}
|
||||
|
||||
void FfxBrixelizerGISHGetCoefficients_ClampedCosine(FfxFloat32x3 cosine_lobe_dir, out FfxFloat32 coefficients[9])
|
||||
{
|
||||
FfxBrixelizerGISHGetCoefficients(cosine_lobe_dir, /* out */ coefficients);
|
||||
coefficients[0] = coefficients[0] * FFX_BRIXELIZER_GI_PI;
|
||||
|
||||
coefficients[1] = coefficients[1] * FFX_BRIXELIZER_GI_SH_2_PI_3;
|
||||
coefficients[2] = coefficients[2] * FFX_BRIXELIZER_GI_SH_2_PI_3;
|
||||
coefficients[3] = coefficients[3] * FFX_BRIXELIZER_GI_SH_2_PI_3;
|
||||
|
||||
coefficients[4] = coefficients[4] * FFX_BRIXELIZER_GI_SH_PI_4;
|
||||
coefficients[5] = coefficients[5] * FFX_BRIXELIZER_GI_SH_PI_4;
|
||||
coefficients[6] = coefficients[6] * FFX_BRIXELIZER_GI_SH_PI_4;
|
||||
coefficients[7] = coefficients[7] * FFX_BRIXELIZER_GI_SH_PI_4;
|
||||
coefficients[8] = coefficients[8] * FFX_BRIXELIZER_GI_SH_PI_4;
|
||||
}
|
||||
|
||||
void FfxBrixelizerGISHGetCoefficients_ClampedCosine16(FfxFloat32x3 cosine_lobe_dir, out FFX_MIN16_F coefficients[9])
|
||||
{
|
||||
FfxBrixelizerGISHGetCoefficients16(cosine_lobe_dir, /* out */ coefficients);
|
||||
coefficients[0] = coefficients[0] * FFX_MIN16_F(FFX_BRIXELIZER_GI_PI);
|
||||
|
||||
coefficients[1] = coefficients[1] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_2_PI_3);
|
||||
coefficients[2] = coefficients[2] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_2_PI_3);
|
||||
coefficients[3] = coefficients[3] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_2_PI_3);
|
||||
|
||||
coefficients[4] = coefficients[4] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_PI_4);
|
||||
coefficients[5] = coefficients[5] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_PI_4);
|
||||
coefficients[6] = coefficients[6] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_PI_4);
|
||||
coefficients[7] = coefficients[7] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_PI_4);
|
||||
coefficients[8] = coefficients[8] * FFX_MIN16_F(FFX_BRIXELIZER_GI_SH_PI_4);
|
||||
}
|
||||
|
||||
void FfxBrixelizerGILoadBrickSH(FfxUInt32 brick_id, inout FfxFloat32x4 input_sh[9])
|
||||
{
|
||||
for (FfxInt32 i = 0; i < 9; i++) {
|
||||
input_sh[i] = ffxUnpackF32x2(LoadBricksSH(FfxBrixelizerBrickGetIndex(brick_id) * 9 + i));
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerGILoadBrickSH16(FfxUInt32 brick_id, inout FFX_MIN16_F4 input_sh[9])
|
||||
{
|
||||
for (FfxInt32 i = 0; i < 9; i++) {
|
||||
input_sh[i] = FFX_MIN16_F4(ffxUnpackF32x2(LoadBricksSH(FfxBrixelizerBrickGetIndex(brick_id) * 9 + i)));
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIStoreBrickSH(FfxUInt32 brick_id, FfxFloat32x4 input_sh[9])
|
||||
{
|
||||
for (FfxInt32 i = 0; i < 9; i++) {
|
||||
StoreBricksSH(FfxBrixelizerBrickGetIndex(brick_id) * 9 + i, ffxFloat16x4ToUint32x2(FFX_MIN16_F4(input_sh[i])));
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerGILoadBrickDirectSH(FfxUInt32 brick_id, inout FfxFloat32x4 input_sh[9])
|
||||
{
|
||||
for (FfxInt32 i = 0; i < 9; i++) {
|
||||
input_sh[i] = ffxUnpackF32x2(LoadBricksDirectSH(FfxBrixelizerBrickGetIndex(brick_id) * 9 + i));
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerGILoadBrickDirectSH16(FfxUInt32 brick_id, inout FFX_MIN16_F4 input_sh[9])
|
||||
{
|
||||
for (FfxInt32 i = 0; i < 9; i++) {
|
||||
input_sh[i] = FFX_MIN16_F4(ffxUnpackF32x2(LoadBricksDirectSH(FfxBrixelizerBrickGetIndex(brick_id) * 9 + i)));
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIStoreBrickDirectSH(FfxUInt32 brick_id, FfxFloat32x4 input_sh[9])
|
||||
{
|
||||
for (FfxInt32 i = 0; i < 9; i++) {
|
||||
StoreBricksDirectSH(FfxBrixelizerBrickGetIndex(brick_id) * 9 + i, ffxFloat16x4ToUint32x2(FFX_MIN16_F4(input_sh[i])));
|
||||
}
|
||||
}
|
||||
|
||||
// Pick the current voxel size for pushoff
|
||||
FfxFloat32 FfxBrixelizerGIGetVoxelSize(FfxFloat32x3 world_pos, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade, FfxFloat32 xi)
|
||||
{
|
||||
FfxBrixelizerCascadeInfo CINFO = GetCascadeInfo(g_starting_cascade);
|
||||
FfxFloat32 size = CINFO.grid_max.x - CINFO.grid_min.x;
|
||||
FfxFloat32 r = length(world_pos - CINFO.grid_mid) / (size * FfxFloat32(0.25)); // FfxFloat32(0.288675134594812));
|
||||
FfxFloat32 x = log2(ffxMax(r, FfxFloat32(1.0)));
|
||||
return CINFO.voxel_size * ffxMax(FfxFloat32(1.0), r);
|
||||
}
|
||||
|
||||
FfxFloat32x3 FfxBrixelizerGISampleRadianceCache(FfxUInt32 brick_id, FfxFloat32x3 uvw)
|
||||
{
|
||||
FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
|
||||
FfxFloat32x3 uvw_min = (FfxFloat32x3(brick_offset / 2) + FFX_BROADCAST_FLOAT32X3(FfxFloat32(0.5))) / FfxFloat32(FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2);
|
||||
FfxFloat32x3 uvw_max = (FfxFloat32x3(brick_offset / 2) + FFX_BROADCAST_FLOAT32X3(FfxFloat32(3.5))) / FfxFloat32(FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2);
|
||||
FfxFloat32x3 sample_uvw = ffxLerp(uvw_min, uvw_max, ffxSaturate(uvw));
|
||||
FfxFloat32x3 radiance = SampleRadianceCacheSRV(sample_uvw);
|
||||
|
||||
if (any(isnan(radiance)))
|
||||
radiance = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
|
||||
return radiance;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FfxBrixelizerGISampleRadianceCacheSH(FfxUInt32 brick_id, FfxFloat32x3 ray_direction)
|
||||
{
|
||||
FFX_MIN16_F cosine_sh[9];
|
||||
FfxBrixelizerGISHGetCoefficients_ClampedCosine16(-ray_direction, cosine_sh);
|
||||
|
||||
FFX_MIN16_F4 shs[9];
|
||||
FfxBrixelizerGILoadBrickDirectSH16(brick_id, shs);
|
||||
|
||||
FfxFloat32x3 radiance = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
|
||||
for (FfxUInt32 i = 0; i < 9; i++)
|
||||
radiance += cosine_sh[i] * shs[i].xyz;
|
||||
|
||||
if (any(isnan(radiance)))
|
||||
radiance = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
|
||||
return radiance;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FfxBrixelizerGISampleRadianceCache(FfxUInt32 cascade_id, FfxFloat32x3 dir, FfxBrixelizerCascadeInfo sdfCINFO, FfxFloat32x3 world_pos)
|
||||
{
|
||||
FfxFloat32x3 rel_pos = world_pos - sdfCINFO.grid_min;
|
||||
FfxInt32x3 voxel_offset = FfxInt32x3(rel_pos / sdfCINFO.voxel_size);
|
||||
FfxFloat32x3 uvw = (rel_pos - FfxFloat32x3(voxel_offset) * sdfCINFO.voxel_size) / sdfCINFO.voxel_size;
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(FfxInt32x3(sdfCINFO.clipmap_offset), FFX_BRIXELIZER_CASCADE_WRAP_MASK, FfxUInt32x3(voxel_offset)), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
FfxUInt32 brick_id = LoadCascadeBrickMapArrayUniform(cascade_id, voxel_idx);
|
||||
|
||||
if (FfxBrixelizerIsValidID(brick_id))
|
||||
{
|
||||
FfxUInt32x4 sample_sh_state = LoadBricksSHState(FfxBrixelizerBrickGetIndex(brick_id));
|
||||
FFX_MIN16_F4 sample_dir_w = FFX_MIN16_F4(ffxUnpackF32x2(sample_sh_state.xy));
|
||||
|
||||
FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id);
|
||||
FfxFloat32x3 uvw_min = (FfxFloat32x3(brick_offset / 2) + FFX_BROADCAST_FLOAT32X3(FfxFloat32(0.5))) / FfxFloat32(FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2);
|
||||
FfxFloat32x3 uvw_max = (FfxFloat32x3(brick_offset / 2) + FFX_BROADCAST_FLOAT32X3(FfxFloat32(3.5))) / FfxFloat32(FFX_BRIXELIZER_STATIC_CONFIG_SDF_ATLAS_SIZE / 2);
|
||||
uvw = ffxLerp(uvw_min, uvw_max, ffxSaturate(uvw));
|
||||
FfxFloat32x3 radiance = SampleRadianceCacheSRV(uvw);
|
||||
|
||||
if (any(isnan(radiance)))
|
||||
radiance = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
|
||||
return radiance;
|
||||
}
|
||||
|
||||
return FFX_BROADCAST_FLOAT32X3(0.0);
|
||||
}
|
||||
FfxFloat32x3 FfxBrixelizerGISampleRadianceCacheSH(FfxUInt32 cascade_id, FfxFloat32x3 world_normal, FfxBrixelizerCascadeInfo sdfCINFO, FfxFloat32x3 world_pos)
|
||||
{
|
||||
FfxFloat32x3 rel_pos = world_pos - sdfCINFO.grid_min;
|
||||
FfxInt32x3 voxel_offset = FfxInt32x3(rel_pos / sdfCINFO.voxel_size);
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(FfxInt32x3(sdfCINFO.clipmap_offset), FFX_BRIXELIZER_CASCADE_WRAP_MASK, FfxUInt32x3(voxel_offset)), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
FfxUInt32 brick_id = LoadCascadeBrickMapArrayUniform(cascade_id, voxel_idx);
|
||||
|
||||
if (FfxBrixelizerIsValidID(brick_id))
|
||||
{
|
||||
FFX_MIN16_F cosine_sh[9];
|
||||
FfxBrixelizerGISHGetCoefficients_ClampedCosine16(world_normal, cosine_sh);
|
||||
|
||||
FFX_MIN16_F4 shs[9];
|
||||
FfxBrixelizerGILoadBrickDirectSH16(brick_id, shs);
|
||||
|
||||
FfxFloat32x3 radiance = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
|
||||
for (uint i = 0; i < 9; i++)
|
||||
radiance += cosine_sh[i] * shs[i].xyz;
|
||||
|
||||
if (any(isnan(radiance)))
|
||||
radiance = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
|
||||
return radiance;
|
||||
}
|
||||
|
||||
return FFX_BROADCAST_FLOAT32X3(0.0);
|
||||
}
|
||||
|
||||
FfxBoolean FfxBrixelizerGISampleRadianceCache(FfxFloat32x3 world_offset, FfxFloat32x3 dir, FfxFloat32x3 grad, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade, inout FfxFloat32x3 cache, FfxFloat32 depth_eps)
|
||||
{
|
||||
FfxFloat32x3 world_pos = world_offset;
|
||||
for (FfxUInt32 cascade_id = g_starting_cascade; cascade_id <= g_end_cascade; cascade_id++)
|
||||
{
|
||||
FfxBrixelizerCascadeInfo sdfCINFO = GetCascadeInfo(cascade_id);
|
||||
|
||||
if (sdfCINFO.is_enabled == 1 && all(FFX_GREATER_THAN(world_pos, sdfCINFO.grid_min)) && all(FFX_LESS_THAN(world_pos, sdfCINFO.grid_max)))
|
||||
{
|
||||
FfxFloat32x3 brick_sample = FfxBrixelizerGISampleRadianceCache(cascade_id, dir, sdfCINFO, world_pos);
|
||||
const FfxFloat32 EPS = FfxFloat32(1.0e-3);
|
||||
// Causes light leaks if the brick_sample is fully unlit.
|
||||
//if (dot(brick_sample, brick_sample) > EPS * EPS)
|
||||
{
|
||||
cache = brick_sample;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
cache = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
return false;
|
||||
}
|
||||
FfxBoolean FfxBrixelizerGISampleRadianceCache(FfxFloat32x3 world_offset, FfxFloat32x3 dir, FfxFloat32x3 grad, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade, inout FfxFloat32x3 cache)
|
||||
{
|
||||
return FfxBrixelizerGISampleRadianceCache(world_offset, dir, grad, g_starting_cascade, g_end_cascade, cache, FfxFloat32(1.0 / 8.0));
|
||||
}
|
||||
FfxBoolean FfxBrixelizerGISampleRadianceCacheSH(FfxFloat32x3 world_pos, FfxFloat32x3 world_normal, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade, inout FfxFloat32x3 cache)
|
||||
{
|
||||
|
||||
for (FfxUInt32 cascade_id = g_starting_cascade; cascade_id <= g_end_cascade; cascade_id++)
|
||||
{
|
||||
FfxBrixelizerCascadeInfo sdfCINFO = GetCascadeInfo(cascade_id);
|
||||
|
||||
if (sdfCINFO.is_enabled == 1 && all(FFX_GREATER_THAN(world_pos, sdfCINFO.grid_min)) && all(FFX_LESS_THAN(world_pos, sdfCINFO.grid_max)))
|
||||
{
|
||||
FfxFloat32x3 brick_sample = FfxBrixelizerGISampleRadianceCacheSH(cascade_id, world_normal, sdfCINFO, world_pos);
|
||||
|
||||
cache = brick_sample;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
cache = FFX_BROADCAST_FLOAT32X3(0.0f);
|
||||
return false;
|
||||
}
|
||||
FfxBoolean FfxBrixelizerGILoadBrickSH(FfxFloat32x3 world_pos, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade, inout FfxFloat32x4 input_sh[9])
|
||||
{
|
||||
for (FfxUInt32 cascade_id = g_starting_cascade; cascade_id <= g_end_cascade; cascade_id++)
|
||||
{
|
||||
FfxBrixelizerCascadeInfo CINFO = GetCascadeInfo(cascade_id);
|
||||
FfxFloat32x3 rel_pos = world_pos - CINFO.grid_min;
|
||||
FfxFloat32 size = CINFO.grid_max.x - CINFO.grid_min.x;
|
||||
|
||||
if (CINFO.is_enabled == 1 && all(FFX_GREATER_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(0.0))) && all(FFX_LESS_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(size))))
|
||||
{
|
||||
FfxInt32x3 voxel_offset = FfxInt32x3(rel_pos * CINFO.ivoxel_size);
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(FfxInt32x3(CINFO.clipmap_offset), FFX_BRIXELIZER_CASCADE_WRAP_MASK, FfxUInt32x3(voxel_offset)), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
FfxUInt32 brick_id = LoadCascadeBrickMapArrayUniform(cascade_id, voxel_idx);
|
||||
|
||||
if (FfxBrixelizerIsValidID(brick_id))
|
||||
{
|
||||
FfxBrixelizerGILoadBrickSH(brick_id, /* inout */ input_sh);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#define FfxBrixelizerGIGOLDEN_RATIO FfxFloat32(1.61803398875)
|
||||
FfxBoolean FfxBrixelizerGIInterpolateBrickSH(FfxFloat32x3 world_pos, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade, FfxFloat32 xi, inout FFX_MIN16_F4 input_sh[9])
|
||||
{
|
||||
FfxUInt32 bricks[8] = {
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
FFX_BRIXELIZER_UNINITIALIZED_ID, //
|
||||
};
|
||||
|
||||
FFX_MIN16_F3 uvw;
|
||||
|
||||
for (FfxUInt32 cascade_id = g_starting_cascade; cascade_id <= g_end_cascade; cascade_id++)
|
||||
{
|
||||
FfxBrixelizerCascadeInfo CINFO = GetCascadeInfo(cascade_id);
|
||||
FfxFloat32x3 rel_pos = world_pos - CINFO.grid_min;
|
||||
FfxFloat32 size = CINFO.grid_max.x - CINFO.grid_min.x;
|
||||
FfxFloat32 falloff = length(world_pos - CINFO.grid_mid) / (size / FfxFloat32(2.0));
|
||||
FfxBoolean skip = falloff > (FfxFloat32(1.0) - (xi * FfxFloat32(8.0) + FfxFloat32(0.0)) / FfxFloat32(FFX_BRIXELIZER_CASCADE_RESOLUTION));
|
||||
|
||||
if (CINFO.is_enabled == 1 && !skip && all(FFX_GREATER_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(0.0))) && all(FFX_LESS_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(size))))
|
||||
{
|
||||
FfxFloat32x3 scaled_pos = rel_pos * CINFO.ivoxel_size - FFX_BROADCAST_FLOAT32X3(0.5);
|
||||
uvw = FFX_MIN16_F3(ffxFract(scaled_pos));
|
||||
FfxInt32x3 base_coord = FfxInt32x3(floor(scaled_pos));
|
||||
FfxInt32x3 coords[8] = {
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(0, 0, 0), //
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(1, 0, 0), //
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(0, 1, 0), //
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(1, 1, 0), //
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(0, 0, 1), //
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(1, 0, 1), //
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(0, 1, 1), //
|
||||
FfxInt32x3(scaled_pos) + FfxInt32x3(1, 1, 1), //
|
||||
};
|
||||
|
||||
for (FfxInt32 i = 0; i < 8; i++)
|
||||
{
|
||||
if (any(FFX_LESS_THAN(coords[i], FFX_BROADCAST_INT32X3(0))) && any(FFX_GREATER_THAN_EQUAL(coords[i], FFX_BROADCAST_INT32X3(FFX_BRIXELIZER_CASCADE_RESOLUTION))))
|
||||
continue;
|
||||
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(FfxInt32x3(CINFO.clipmap_offset), FFX_BRIXELIZER_CASCADE_WRAP_MASK, FfxUInt32x3(coords[i])), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
FfxUInt32 brick_id = LoadCascadeBrickMapArrayNonUniform(cascade_id, voxel_idx);
|
||||
|
||||
if (FfxBrixelizerIsValidID(brick_id))
|
||||
bricks[i] = brick_id;
|
||||
}
|
||||
break;
|
||||
}
|
||||
xi = ffxFract(xi + FfxFloat32(cascade_id) * FfxBrixelizerGIGOLDEN_RATIO);
|
||||
}
|
||||
|
||||
FFX_MIN16_F weights[8] = {
|
||||
(FFX_MIN16_F(1.0) - uvw.x) * (FFX_MIN16_F(1.0) - uvw.y) * (FFX_MIN16_F(1.0) - uvw.z), //
|
||||
uvw.x * (FFX_MIN16_F(1.0) - uvw.y) * (FFX_MIN16_F(1.0) - uvw.z), //
|
||||
(FFX_MIN16_F(1.0) - uvw.x) * uvw.y * (FFX_MIN16_F(1.0) - uvw.z), //
|
||||
uvw.x * uvw.y * (FFX_MIN16_F(1.0) - uvw.z), //
|
||||
(FFX_MIN16_F(1.0) - uvw.x) * (FFX_MIN16_F(1.0) - uvw.y) * uvw.z, //
|
||||
uvw.x * (FFX_MIN16_F(1.0) - uvw.y) * uvw.z, //
|
||||
(FFX_MIN16_F(1.0) - uvw.x) * uvw.y * uvw.z, //
|
||||
uvw.x * uvw.y * uvw.z, //
|
||||
};
|
||||
|
||||
FFX_MIN16_F weight_sum = FFX_MIN16_F(0.0);
|
||||
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
input_sh[j] = FFX_BROADCAST_MIN_FLOAT16X4(FFX_MIN16_F(0.0));
|
||||
|
||||
for (FfxInt32 i = 0; i < 8; i++)
|
||||
{
|
||||
if (bricks[i] == FFX_BRIXELIZER_UNINITIALIZED_ID)
|
||||
continue;
|
||||
|
||||
FFX_MIN16_F4 shs[9];
|
||||
FfxBrixelizerGILoadBrickSH16(bricks[i], /* inout */ shs);
|
||||
|
||||
if (shs[0].w < FfxFloat32(1.0))
|
||||
continue; // skip if less than 16 samples of data as too noisy
|
||||
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
input_sh[j] += shs[j] * weights[i];
|
||||
|
||||
weight_sum += weights[i];
|
||||
}
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
input_sh[j] /= ffxMax(weight_sum, FFX_MIN16_F(1.0e-6));
|
||||
|
||||
return ffxAsUInt32(FfxFloat32(weight_sum)) != 0;
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIEmitIrradiance(FfxFloat32x3 world_pos, FfxFloat32x3 probe_direction, FfxFloat32x3 ray_direction, FfxFloat32x4 input_sh[9], FfxFloat32 xi, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade)
|
||||
{
|
||||
FfxFloat32 DoV = ffxSaturate(dot(-ray_direction, probe_direction));
|
||||
FfxFloat32 jk = ffxLerp(FfxFloat32(1.0), FfxFloat32(1.0 / 8.0), DoV);
|
||||
xi = ffxLerp(-jk, jk, xi); // voxel jitter
|
||||
|
||||
for (FfxUInt32 cascade_id = g_starting_cascade; cascade_id <= g_end_cascade; cascade_id++)
|
||||
{
|
||||
FfxFloat32 max_num_samples = FfxFloat32(64.0) * ffxPow(FfxFloat32(1.3), FfxFloat32(cascade_id - g_starting_cascade));
|
||||
FfxBrixelizerCascadeInfo CINFO = GetCascadeInfo(cascade_id);
|
||||
FfxFloat32x3 rel_pos = world_pos - (CINFO.voxel_size) * ray_direction * xi - CINFO.grid_min;
|
||||
FfxFloat32 size = CINFO.grid_max.x - CINFO.grid_min.x;
|
||||
|
||||
if (CINFO.is_enabled == 1 && all(FFX_GREATER_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(0.0))) && all(FFX_LESS_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(size))))
|
||||
{
|
||||
FfxInt32x3 voxel_offset = FfxInt32x3(rel_pos * CINFO.ivoxel_size);
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(FfxInt32x3(CINFO.clipmap_offset), FFX_BRIXELIZER_CASCADE_WRAP_MASK, FfxUInt32x3(voxel_offset)), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
FfxUInt32 brick_id = LoadCascadeBrickMapArrayUniform(cascade_id, voxel_idx);
|
||||
|
||||
if (FfxBrixelizerIsValidID(brick_id))
|
||||
{
|
||||
FfxFloat32x4 src_sh[9];
|
||||
FfxBrixelizerGILoadBrickSH(brick_id, /* inout */ src_sh);
|
||||
FfxFloat32 num_samples = ffxMin(max_num_samples, src_sh[0].w);
|
||||
|
||||
FfxUInt32x4 sh_state = LoadBricksSHState(FfxBrixelizerBrickGetIndex(brick_id));
|
||||
FFX_MIN16_F4 dir_w = FFX_MIN16_F4(ffxUnpackF32x2(sh_state.xy));
|
||||
if (any(isinf(dir_w)) || any(isnan(dir_w)))
|
||||
dir_w = FFX_BROADCAST_MIN_FLOAT16X4(FFX_MIN16_F(0.0));
|
||||
|
||||
FfxFloat32 weight = FfxFloat32(1.0) - FfxFloat32(1.0) / (FfxFloat32(1.0) + num_samples);
|
||||
|
||||
FfxFloat32x4 shs[9];
|
||||
for (FfxInt32 i = 0; i < 9; i++)
|
||||
{
|
||||
FfxFloat32x4 src = src_sh[i];
|
||||
const FfxFloat32 EPS = FfxFloat32(1.0e-4);
|
||||
FfxFloat32x4 new_value = ffxLerp(input_sh[i], src, weight);
|
||||
new_value.w = num_samples + FfxFloat32(1.0);
|
||||
|
||||
if (any(isnan(new_value)))
|
||||
new_value = FFX_BROADCAST_FLOAT32X4(0.0);
|
||||
|
||||
shs[i] = new_value;
|
||||
}
|
||||
|
||||
dir_w.xyz = normalize(ffxLerp(FFX_MIN16_F3(probe_direction), dir_w.xyz, FFX_MIN16_F(weight)));
|
||||
|
||||
sh_state.xy = ffxFloat16x4ToUint32x2(dir_w);
|
||||
StoreBricksSHState(FfxBrixelizerBrickGetIndex(brick_id), sh_state);
|
||||
|
||||
FfxBrixelizerGIStoreBrickSH(brick_id, shs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FfxInt32x3 FfxBrixelizerGIPickMajorDir(FfxFloat32x3 r)
|
||||
{
|
||||
if (abs(r.x) > abs(r.y))
|
||||
{
|
||||
if (abs(r.x) > abs(r.z))
|
||||
return FfxInt32x3(r.x > FfxFloat32(0.0) ? 1 : -1, 0, 0);
|
||||
else
|
||||
return FfxInt32x3(0, 0, r.z > FfxFloat32(0.0) ? 1 : -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (abs(r.y) > abs(r.z))
|
||||
return FfxInt32x3(0, r.y > FfxFloat32(0.0) ? 1 : -1, 0);
|
||||
else
|
||||
return FfxInt32x3(0, 0, r.z > FfxFloat32(0.0) ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIEmitRadiance(FfxUInt32 brick_id, FfxFloat32x3 uvw, FfxFloat32x3 direction, FfxFloat32x3 radiance, FfxFloat32 weight)
|
||||
{
|
||||
FfxUInt32x3 brick_offset = FfxBrixelizerGetSDFAtlasOffset(brick_id) / 2;
|
||||
FfxInt32x3 coord = FfxInt32x3(ffxSaturate(uvw) * FfxFloat32(4.0));
|
||||
FfxFloat32x3 src = LoadRadianceCache(brick_offset + coord);
|
||||
const FfxFloat32 EPS = FfxFloat32(1.0e-6);
|
||||
|
||||
if (dot(src, src) < EPS * EPS)
|
||||
weight = FfxFloat32(0.0);
|
||||
|
||||
FfxFloat32x3 new_value = ffxLerp(radiance, src, weight);
|
||||
|
||||
if (any(isnan(new_value)))
|
||||
new_value = FFX_BROADCAST_FLOAT32X3(0.0);
|
||||
|
||||
StoreRadianceCache(brick_offset + coord, new_value);
|
||||
|
||||
{
|
||||
FfxFloat32x4 src_sh[9];
|
||||
FfxBrixelizerGILoadBrickDirectSH(brick_id, /* inout */ src_sh);
|
||||
|
||||
FfxFloat32 direction_sh[9];
|
||||
FfxBrixelizerGISHGetCoefficients(direction, direction_sh);
|
||||
|
||||
for (FfxUInt32 j = 0; j < 9; j++)
|
||||
{
|
||||
src_sh[j].xyz = ffxLerp(direction_sh[j] * radiance.xyz, src_sh[j].xyz, weight);
|
||||
src_sh[j].w += FfxFloat32(1.0);
|
||||
}
|
||||
|
||||
FfxBrixelizerGIStoreBrickDirectSH(brick_id, src_sh);
|
||||
}
|
||||
|
||||
// g_rw_pctx_volume_cache[brick_offset + coord] = ffxLerp(color, src, FfxFloat32(0.95));
|
||||
// break; // early out and let the rest for Propagate pass
|
||||
}
|
||||
|
||||
// xi - random [0, 1]
|
||||
void FfxBrixelizerGIEmitRadiance(FfxFloat32x3 world_pos, FfxFloat32x3 world_normal, FfxFloat32x3 ray_direction, FfxFloat32x3 radiance, FfxFloat32 xi, FfxUInt32 g_starting_cascade, FfxUInt32 g_end_cascade)
|
||||
{
|
||||
radiance = clamp(radiance, FFX_BROADCAST_FLOAT32X3(0.0), FFX_BROADCAST_FLOAT32X3(8.0)); // Some clamping has to be here for specular highlights
|
||||
FfxFloat32 DoV = ffxSaturate(dot(-ray_direction, world_normal));
|
||||
FfxFloat32 jk = ffxLerp(FfxFloat32(4.0), FfxFloat32(1.0 / 8.0), DoV); // TODO: Make this tunable
|
||||
|
||||
for (FfxUInt32 cascade_id = g_starting_cascade; cascade_id <= g_end_cascade; cascade_id++)
|
||||
{
|
||||
FfxBrixelizerCascadeInfo sdfCINFO = GetCascadeInfoNonUniform(cascade_id);
|
||||
FfxFloat32 random_jitter = ffxLerp(-jk, jk, xi) * GetCascadeInfoNonUniform(g_starting_cascade).voxel_size; // voxel jitter
|
||||
|
||||
// Jitter along the camera primary ray to inject into neighbor voxels
|
||||
FfxFloat32x3 rel_pos = world_pos - ray_direction * random_jitter - sdfCINFO.grid_min;
|
||||
FfxFloat32 size = sdfCINFO.grid_max.x - sdfCINFO.grid_min.x;
|
||||
|
||||
// Check if relative position is within the cascade grid extents
|
||||
if (sdfCINFO.is_enabled == 1 && all(FFX_GREATER_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(0.0))) && all(FFX_LESS_THAN(rel_pos, FFX_BROADCAST_FLOAT32X3(size))))
|
||||
{
|
||||
|
||||
// Convert the relative voxel position into a voxel grid coordinate
|
||||
FfxInt32x3 voxel_offset = FfxInt32x3(rel_pos / sdfCINFO.voxel_size);
|
||||
|
||||
// Generate a 3D texture coordinate from
|
||||
FfxFloat32x3 uvw = (rel_pos - FfxFloat32x3(voxel_offset) * sdfCINFO.voxel_size) / sdfCINFO.voxel_size;
|
||||
uvw = ffxSaturate(uvw);
|
||||
FfxFloat32x3 uvw_c = uvw - FFX_BROADCAST_FLOAT32X3(0.5);
|
||||
FfxInt32x3 md = FfxBrixelizerGIPickMajorDir(uvw_c);
|
||||
|
||||
FfxUInt32 voxel_idx = FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(FfxInt32x3(sdfCINFO.clipmap_offset), FFX_BRIXELIZER_CASCADE_WRAP_MASK, FfxUInt32x3(voxel_offset)), FFX_BRIXELIZER_CASCADE_DEGREE);
|
||||
FfxUInt32 brick_id = LoadCascadeBrickMapArrayNonUniform(cascade_id, voxel_idx);
|
||||
|
||||
if (FfxBrixelizerIsValidID(brick_id))
|
||||
{
|
||||
FfxFloat32 weight = FfxFloat32(1.0) - FfxFloat32(1.0 / (FfxFloat32(8.0) * ffxPow(FfxFloat32(2.0), FfxFloat32(cascade_id - g_starting_cascade))));
|
||||
FfxBrixelizerGIEmitRadiance(brick_id, uvw, world_normal, radiance, weight);
|
||||
}
|
||||
}
|
||||
xi = ffxFract(xi + FfxBrixelizerGIGOLDEN_RATIO);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_GI_PROBE_SHADING_H
|
||||
176
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_radiance_cache_update.h
vendored
Normal file
176
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_radiance_cache_update.h
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
// 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_BRIXELIZER_GI_RADIANCE_CACHE_H
|
||||
#define FFX_BRIXELIZER_GI_RADIANCE_CACHE_H
|
||||
|
||||
#include "../ffx_core.h"
|
||||
|
||||
#include "ffx_brixelizer_brick_common_private.h"
|
||||
#include "ffx_brixelizergi_common.h"
|
||||
#include "ffx_brixelizergi_probe_shading.h"
|
||||
|
||||
FfxFloat32x3 GetWorldPosition(FfxUInt32x2 pixel_coordinate)
|
||||
{
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(pixel_coordinate.xy) + (0.5).xx) / FfxFloat32x2(GetGIConstants().target_width, GetGIConstants().target_height);
|
||||
FfxFloat32 z = LoadDepth(pixel_coordinate);
|
||||
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, z);
|
||||
FfxFloat32x3 view_space_position = ffxScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
||||
FfxFloat32x3 world_space_origin = ffxViewSpaceToWorldSpace(FfxFloat32x4(view_space_position, FfxFloat32(1.0))).xyz;
|
||||
return world_space_origin;
|
||||
}
|
||||
|
||||
// https://www.pcg-random.org/
|
||||
FfxUInt32 FFX_pcg(FfxUInt32 v)
|
||||
{
|
||||
FfxUInt32 state = v * 747796405u + 2891336453u;
|
||||
FfxUInt32 word = ((state >> ((state >> 28u) + 4u)) ^ state) * 277803737u;
|
||||
return (word >> 22u) ^ word;
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIEmitPrimaryRayRadiance(FfxUInt32x2 _tid)
|
||||
{
|
||||
FfxUInt32x2 qid = FfxUInt32x2(GetGIConstants().frame_index & 3, (GetGIConstants().frame_index >> 2) & 3);
|
||||
FfxUInt32x2 tid = _tid * 4 + qid;
|
||||
|
||||
if (any(FFX_GREATER_THAN_EQUAL(tid, FfxUInt32x2(GetGIConstants().target_width, GetGIConstants().target_height))))
|
||||
return;
|
||||
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(tid.xy) + FFX_BROADCAST_FLOAT32X2(0.5).xx) / FfxFloat32x2(GetGIConstants().target_width, GetGIConstants().target_height);
|
||||
FfxFloat32 z = LoadDepth(tid.xy);
|
||||
|
||||
if (ffxIsBackground(z))
|
||||
return;
|
||||
|
||||
FfxFloat32x2 prev_uv = uv + SampleMotionVector(uv);
|
||||
|
||||
if (any(FFX_GREATER_THAN(prev_uv, FFX_BROADCAST_FLOAT32X2(1.0))) || any(FFX_LESS_THAN(prev_uv, FFX_BROADCAST_FLOAT32X2(0.0))))
|
||||
return;
|
||||
|
||||
FfxFloat32x3 ray_origin = GetWorldPosition(tid.xy);
|
||||
FfxFloat32x3 primary_radiance = SamplePrevLitOutput(prev_uv);
|
||||
FfxFloat32 xi = FfxFloat32(FFX_pcg(tid.x + FFX_pcg(tid.y + FFX_pcg(GetGIConstants().frame_index))) & 0xffffu) / FfxFloat32(256 * 256 - 1);
|
||||
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, FfxFloat32(0.5));
|
||||
FfxFloat32x3 view_space_ray = ffxScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
||||
FfxFloat32x3 view_space_ray_direction = normalize(view_space_ray);
|
||||
FfxFloat32x3 ray_direction = -normalize(ffxViewSpaceToWorldSpace(FfxFloat32x4(view_space_ray_direction, FfxFloat32(0.0))));
|
||||
FfxBoolean disoccluded = LoadDisocclusionMask(tid.xy) > 0;
|
||||
|
||||
if (disoccluded)
|
||||
return;
|
||||
|
||||
FfxUInt32 g_starting_cascade = GetGIConstants().tracing_constants.start_cascade;
|
||||
FfxUInt32 g_end_cascade = GetGIConstants().tracing_constants.end_cascade;
|
||||
FfxFloat32x3 world_normal = LoadWorldNormal(tid);
|
||||
FfxBrixelizerGIEmitRadiance(ray_origin, world_normal, ray_direction, primary_radiance, xi, g_starting_cascade, g_end_cascade);
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIPrepareClearCache(FfxUInt32x3 tid)
|
||||
{
|
||||
FfxUInt32 cnt = LoadContextCounter(FFX_BRIXELIZER_CONTEXT_COUNTER_CLEAR_BRICKS);
|
||||
StoreRaySwapIndirectArgs(0, cnt);
|
||||
StoreRaySwapIndirectArgs(1, 1);
|
||||
StoreRaySwapIndirectArgs(2, 1);
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIClearCache(FfxUInt32x3 tid)
|
||||
{
|
||||
FfxUInt32 brick_offset = tid.x / 64;
|
||||
FfxUInt32 brick_id = LoadBricksClearList(brick_offset);
|
||||
FfxUInt32x3 local_coord = FfxBrixelizerUnflattenPOT(tid.x % 64, 2);
|
||||
|
||||
if ((tid.x % 64) == 0) { // clear SH
|
||||
FfxFloat32x4 shs[9];
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
shs[j] = FFX_BROADCAST_FLOAT32X4(0.0);
|
||||
FfxBrixelizerGIStoreBrickSH(brick_id, shs);
|
||||
FfxBrixelizerGIStoreBrickDirectSH(brick_id, shs);
|
||||
StoreBricksSHState(FfxBrixelizerBrickGetIndex(brick_id), FFX_BROADCAST_UINT32X4(0));
|
||||
}
|
||||
StoreRadianceCache(FfxBrixelizerGetSDFAtlasOffset(brick_id) / 2 + local_coord, FfxFloat32x3(0.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
void FfxBrixelizerGIPropagateSH(FfxUInt32x3 tid)
|
||||
{
|
||||
if (tid.x >= FFX_BRIXELIZER_CASCADE_RESOLUTION * FFX_BRIXELIZER_CASCADE_RESOLUTION * FFX_BRIXELIZER_CASCADE_RESOLUTION)
|
||||
return;
|
||||
|
||||
FfxInt32x3 voxel = FfxInt32x3(FfxBrixelizerUnflattenPOT(tid.x, FFX_BRIXELIZER_CASCADE_DEGREE));
|
||||
FfxBrixelizerCascadeInfo CINFO = GetCascadeInfo(GetPassConstantsCascadeIndex());
|
||||
FfxUInt32 base_brick_id = LoadCascadeBrickMapArrayUniform(GetPassConstantsCascadeIndex(), WrapFlatCoords(CINFO, tid.x));
|
||||
if (!FfxBrixelizerIsValidID(base_brick_id))
|
||||
return;
|
||||
FfxFloat32x4 base_sh[9];
|
||||
FfxBrixelizerGILoadBrickSH(base_brick_id, /* inout */ base_sh);
|
||||
FfxFloat32 weight_acc = FfxFloat32(base_sh[0].w * base_sh[0].w);
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
base_sh[j] *= weight_acc;
|
||||
FfxInt32 next_cascade_idx = -1;
|
||||
|
||||
FfxUInt32x4 sh_state = LoadBricksSHState(FfxBrixelizerBrickGetIndex(base_brick_id));
|
||||
FFX_MIN16_F4 dir_w = FFX_MIN16_F4(ffxUnpackF32x2(sh_state.xy));
|
||||
|
||||
if (next_cascade_idx == -1)
|
||||
{
|
||||
for (FfxInt32 z = -1; z <= 1; z++)
|
||||
{
|
||||
for (FfxInt32 y = -1; y <= 1; y++)
|
||||
{
|
||||
for (FfxInt32 x = -1; x <= 1; x++)
|
||||
{
|
||||
if (x == 0 && y == 0 && z == 0)
|
||||
continue;
|
||||
|
||||
FfxInt32x3 sample_voxel = voxel + FfxInt32x3(x, y, z);
|
||||
|
||||
if (any(FFX_LESS_THAN(sample_voxel, FFX_BROADCAST_INT32X3(0))) || any(FFX_GREATER_THAN_EQUAL(sample_voxel, FFX_BROADCAST_INT32X3(FFX_BRIXELIZER_CASCADE_RESOLUTION))))
|
||||
continue;
|
||||
|
||||
FfxUInt32 sample_brick_id = LoadCascadeBrickMapArrayUniform(GetPassConstantsCascadeIndex(), FfxBrixelizerFlattenPOT(FfxBrixelizerWrapCoords(CINFO, sample_voxel), FFX_BRIXELIZER_CASCADE_DEGREE));
|
||||
|
||||
if (FfxBrixelizerIsInvalidID(sample_brick_id))
|
||||
continue;
|
||||
|
||||
FfxUInt32x4 sample_sh_state = LoadBricksSHState(FfxBrixelizerBrickGetIndex(sample_brick_id));
|
||||
FFX_MIN16_F4 sample_dir_w = FFX_MIN16_F4(ffxUnpackF32x2(sample_sh_state.xy));
|
||||
|
||||
if (dot(sample_dir_w.xyz, dir_w.xyz) < FFX_MIN16_F(0.0))
|
||||
continue;
|
||||
|
||||
FfxFloat32x4 shs[9];
|
||||
FfxBrixelizerGILoadBrickSH(sample_brick_id, /* inout */ shs);
|
||||
FfxFloat32 weight = FfxFloat32(1.0) / FfxFloat32(x * x + y * y + z * z);
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
base_sh[j] += shs[j] * weight;
|
||||
weight_acc += weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
base_sh[j] *= FfxFloat32(1.0) / ffxMax(weight_acc, FfxFloat32(1.0e-6));
|
||||
for (FfxInt32 j = 0; j < 9; j++)
|
||||
base_sh[j].w *= GetPassConstantsEnergyDecayK();
|
||||
FfxBrixelizerGIStoreBrickSH(base_brick_id, base_sh);
|
||||
}
|
||||
|
||||
#endif // FFX_BRIXELIZER_GI_RADIANCE_CACHE_H
|
||||
117
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_resources.h
vendored
Normal file
117
manul/thirdparty/fsr2/include/FidelityFX/gpu/brixelizergi/ffx_brixelizergi_resources.h
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
// 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_BRIXELIZER_GI_RESOURCES_H
|
||||
#define FFX_BRIXELIZER_GI_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_GI_TARGET_0 1
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_GI_TARGET_1 2
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_SCREEN_PROBES_0 3
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_SCREEN_PROBES_1 4
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SPECULAR_TARGET_0 5
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SPECULAR_TARGET_1 6
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_RADIANCE_CACHE 7
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_PUSHOFF_MAP 8
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DEBUG_TARGET 9
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_SCREEN_PROBES_STAT 10
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_PROBE_INFO 11
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_STATIC_PROBE_SH 12
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_RAY_SWAP_INDIRECT_ARGS 13
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_BRICKS_DIRECT_SH 14
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_BRICKS_SH 15
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_BRICKS_SH_STATE 16
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DISOCCLUSION_MASK 17
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_TEMP_SPAWN_MASK 18
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_TEMP_RAND_SEED 19
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_TEMP_SPECULAR_PRETRACE_TARGET 20
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_TEMP_BLUR_MASK 21
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_TEMP_PROBE_INFO 22
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_TEMP_PROBE_SH 23
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_TEMP_SPECULAR_RAY_SWAP 24
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH 25
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_HISTORY_DEPTH 26
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_NORMAL 27
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_HISTORY_NORMAL 28
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_ROUGHNESS 29
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_MOTION_VECTORS 30
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_LIT_OUTPUT 31
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_DIFFUSE_GI 32
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_DOWNSAMPLED_SPECULAR_GI 33
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_COUNT_INTERNAL 34
|
||||
|
||||
// Resource IDs for aliasing purposes
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SOURCE_DEPTH 34
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SOURCE_HISTORY_DEPTH 35
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SOURCE_NORMAL 36
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SOURCE_HISTORY_NORMAL 37
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SOURCE_ROUGHNESS 38
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SOURCE_MOTION_VECTORS 39
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_SOURCE_LIT_OUTPUT 40
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_UPSAMPLED_DIFFUSE_GI 41
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_UPSAMPLED_SPECULAR_GI 42
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_OUTPUT_DIFFUSE_GI 43
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_OUTPUT_SPECULAR_GI 44
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_OUTPUT_DEBUG_VISUALIZATION 45
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_ENVIRONMENT_MAP 46
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_PREV_LIT_OUTPUT 47
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_DEPTH 48
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_HISTORY_DEPTH 49
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_NORMAL 50
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_HISTORY_NORMAL 51
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_ROUGHNESS 52
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_MOTION_VECTORS 53
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_BLUE_NOISE 54
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_SDF_ATLAS 55
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_CONTEXT_BRICKS_AABB 56
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_CONTEXT_BRICKS_VOXEL_MAP 57
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_CONTEXT_COUNTERS 58
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_BRICKS_CLEAR_LIST 59
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_CASCADE_AABB_TREES 60 // 24 elements
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_INPUT_CASCADE_BRICK_MAPS 84 // 24 elements
|
||||
|
||||
#define FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_STATIC_GI_TARGET_READ 108
|
||||
#define FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_STATIC_SCREEN_PROBES_READ 109
|
||||
#define FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_STATIC_SPECULAR_TARGET_READ 110
|
||||
#define FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_STATIC_SCREEN_PROBES_WRITE 111
|
||||
#define FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_STATIC_GI_TARGET_WRITE 112
|
||||
#define FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_STATIC_SPECULAR_TARGET_WRITE 113
|
||||
#define FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_COUNT (113 - FFX_BRIXELIZER_GI_PING_PONG_RESOURCE_STATIC_GI_TARGET_READ)
|
||||
|
||||
#define FFX_BRIXELIZER_GI_RESOURCE_IDENTIFIER_COUNT 114
|
||||
|
||||
#define FFX_BRIXELIZER_GI_CONSTANTBUFFER_IDENTIFIER_GI_CONSTANTS 0
|
||||
#define FFX_BRIXELIZER_GI_CONSTANTBUFFER_IDENTIFIER_PASS_CONSTANTS 1
|
||||
#define FFX_BRIXELIZER_GI_CONSTANTBUFFER_IDENTIFIER_SCALING_CONSTANTS 2
|
||||
#define FFX_BRIXELIZER_GI_CONSTANTBUFFER_IDENTIFIER_CONTEXT_INFO 3
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif //FFX_BRIXELIZER_GI_RESOURCES_H
|
||||
77
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/CMakeCompileCACAOShaders.txt
vendored
Normal file
77
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/CMakeCompileCACAOShaders.txt
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
# 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(CACAO_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(CACAO_PERMUTATION_ARGS
|
||||
-DFFX_CACAO_OPTION_APPLY_SMART={0,1}
|
||||
)
|
||||
|
||||
set(CACAO_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/cacao")
|
||||
|
||||
if (NOT CACAO_SHADER_EXT)
|
||||
set(CACAO_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB CACAO_SHADERS
|
||||
"shaders/cacao/ffx_cacao_apply_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_apply_non_smart_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_apply_non_smart_half_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_clear_load_counter_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_1_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_2_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_3_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_4_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_5_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_6_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_7_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_edge_sensitive_blur_8_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_importance_map_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_importance_map_a_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_importance_map_b_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_q0_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_q1_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_q2_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_q3_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_generate_q3_base_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_downsampled_depths_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_downsampled_depths_and_mips_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_downsampled_depths_half_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_downsampled_normals_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_downsampled_normals_from_input_normals_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_native_depths_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_native_depths_and_mips_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_native_depths_half_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_native_normals_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_prepare_native_normals_from_input_normals_pass.${CACAO_SHADER_EXT}"
|
||||
"shaders/cacao/ffx_cacao_upscale_bilateral_5x5_pass.${CACAO_SHADER_EXT}")
|
||||
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${CACAO_BASE_ARGS}" "${CACAO_API_BASE_ARGS}"
|
||||
"${CACAO_PERMUTATION_ARGS}" "${CACAO_INCLUDE_ARGS}"
|
||||
"${CACAO_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" CACAO_PERMUTATION_OUTPUTS)
|
||||
|
||||
add_shader_output("${CACAO_PERMUTATION_OUTPUTS}")
|
||||
105
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_apply.h
vendored
Normal file
105
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_apply.h
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_cacao_defines.h"
|
||||
#include "ffx_cacao_utils.h"
|
||||
|
||||
void FFX_CACAO_Apply(FfxUInt32x2 coord)
|
||||
{
|
||||
FfxFloat32 ao;
|
||||
FfxFloat32x2 inPos = coord;
|
||||
FfxUInt32x2 pixPos = coord;
|
||||
FfxUInt32x2 pixPosHalf = pixPos / FfxUInt32x2(2, 2);
|
||||
|
||||
// calculate index in the four deinterleaved source array texture
|
||||
FfxInt32 mx = FfxInt32(pixPos.x % 2);
|
||||
FfxInt32 my = FfxInt32(pixPos.y % 2);
|
||||
FfxInt32 ic = mx + my * 2; // center index
|
||||
FfxInt32 ih = (1 - mx) + my * 2; // neighbouring, horizontal
|
||||
FfxInt32 iv = mx + (1 - my) * 2; // neighbouring, vertical
|
||||
FfxInt32 id = (1 - mx) + (1 - my) * 2; // diagonal
|
||||
|
||||
FfxFloat32x2 centerVal = FFX_CACAO_Apply_LoadSSAOPass(FfxInt32x2(pixPosHalf), ic);
|
||||
|
||||
ao = centerVal.x;
|
||||
|
||||
#if 1 // change to 0 if you want to disable last pass high-res blur (for debugging purposes, etc.)
|
||||
FfxFloat32x4 edgesLRTB = FFX_CACAO_UnpackEdges(centerVal.y);
|
||||
|
||||
// return 1.0 - FfxFloat32x4( edgesLRTB.x, edgesLRTB.y * 0.5 + edgesLRTB.w * 0.5, edgesLRTB.z, 0.0 ); // debug show edges
|
||||
|
||||
// convert index shifts to sampling offsets
|
||||
FfxFloat32 fmx = FfxFloat32(mx);
|
||||
FfxFloat32 fmy = FfxFloat32(my);
|
||||
|
||||
// in case of an edge, push sampling offsets away from the edge (towards pixel center)
|
||||
FfxFloat32 fmxe = (edgesLRTB.y - edgesLRTB.x);
|
||||
FfxFloat32 fmye = (edgesLRTB.w - edgesLRTB.z);
|
||||
|
||||
// calculate final sampling offsets and sample using bilinear filter
|
||||
FfxFloat32x2 uvH = (inPos.xy + FfxFloat32x2(fmx + fmxe - 0.5, 0.5 - fmy)) * 0.5 * SSAOBufferInverseDimensions();
|
||||
FfxFloat32 aoH = FFX_CACAO_Apply_SampleSSAOUVPass(uvH, ih);
|
||||
FfxFloat32x2 uvV = (inPos.xy + FfxFloat32x2(0.5 - fmx, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions();
|
||||
FfxFloat32 aoV = FFX_CACAO_Apply_SampleSSAOUVPass(uvV, iv);
|
||||
FfxFloat32x2 uvD = (inPos.xy + FfxFloat32x2(fmx - 0.5 + fmxe, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions();
|
||||
FfxFloat32 aoD = FFX_CACAO_Apply_SampleSSAOUVPass(uvD, id);
|
||||
|
||||
// reduce weight for samples near edge - if the edge is on both sides, weight goes to 0
|
||||
FfxFloat32x4 blendWeights;
|
||||
blendWeights.x = 1.0;
|
||||
blendWeights.y = (edgesLRTB.x + edgesLRTB.y) * 0.5;
|
||||
blendWeights.z = (edgesLRTB.z + edgesLRTB.w) * 0.5;
|
||||
blendWeights.w = (blendWeights.y + blendWeights.z) * 0.5;
|
||||
|
||||
// calculate weighted average
|
||||
FfxFloat32 blendWeightsSum = dot(blendWeights, FfxFloat32x4(1.0, 1.0, 1.0, 1.0));
|
||||
ao = dot(FfxFloat32x4(ao, aoH, aoV, aoD), blendWeights) / blendWeightsSum;
|
||||
#endif
|
||||
ao.x = pow(ao.x, 2.2);
|
||||
FFX_CACAO_Apply_StoreOutput(FfxInt32x2(coord), ao.x);
|
||||
}
|
||||
|
||||
|
||||
// edge-ignorant blur & apply (for the lowest quality level 0)
|
||||
void FFX_CACAO_NonSmartApply(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxFloat32x2 inUV = FfxFloat32x2(tid) * OutputBufferInverseDimensions();
|
||||
FfxFloat32 a = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 0);
|
||||
FfxFloat32 b = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 1);
|
||||
FfxFloat32 c = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 2);
|
||||
FfxFloat32 d = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 3);
|
||||
FfxFloat32 avg = (a + b + c + d) * 0.25f;
|
||||
|
||||
FFX_CACAO_Apply_StoreOutput(FfxInt32x2(tid), avg);
|
||||
}
|
||||
|
||||
// edge-ignorant blur & apply, skipping half pixels in checkerboard pattern (for the Lowest quality level 0 and Settings::SkipHalfPixelsOnLowQualityLevel == true )
|
||||
void FFX_CACAO_NonSmartHalfApply(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxFloat32x2 inUV = FfxFloat32x2(tid) * OutputBufferInverseDimensions();
|
||||
FfxFloat32 a = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 0);
|
||||
FfxFloat32 d = FFX_CACAO_Apply_SampleSSAOUVPass(inUV.xy, 3);
|
||||
FfxFloat32 avg = (a + d) * 0.5f;
|
||||
|
||||
FFX_CACAO_Apply_StoreOutput(FfxInt32x2(tid), avg);
|
||||
}
|
||||
774
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_callbacks_glsl.h
vendored
Normal file
774
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,774 @@
|
||||
// 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_cacao_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core.h"
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
struct FFX_CACAO_Constants
|
||||
{
|
||||
FfxFloat32x2 DepthUnpackConsts;
|
||||
FfxFloat32x2 CameraTanHalfFOV;
|
||||
|
||||
FfxFloat32x2 NDCToViewMul;
|
||||
FfxFloat32x2 NDCToViewAdd;
|
||||
|
||||
FfxFloat32x2 DepthBufferUVToViewMul;
|
||||
FfxFloat32x2 DepthBufferUVToViewAdd;
|
||||
|
||||
FfxFloat32 EffectRadius; // world (viewspace) maximum size of the shadow
|
||||
FfxFloat32 EffectShadowStrength; // global strength of the effect (0 - 5)
|
||||
FfxFloat32 EffectShadowPow;
|
||||
FfxFloat32 EffectShadowClamp;
|
||||
|
||||
FfxFloat32 EffectFadeOutMul; // effect fade out from distance (ex. 25)
|
||||
FfxFloat32 EffectFadeOutAdd; // effect fade out to distance (ex. 100)
|
||||
FfxFloat32 EffectHorizonAngleThreshold; // limit errors on slopes and caused by insufficient geometry tessellation (0.05 to 0.5)
|
||||
FfxFloat32 EffectSamplingRadiusNearLimitRec; // if viewspace pixel closer than this, don't enlarge shadow sampling radius anymore (makes no sense to grow beyond some distance, not enough samples to cover everything, so just limit the shadow growth; could be SSAOSettingsFadeOutFrom * 0.1 or less)
|
||||
|
||||
FfxFloat32 DepthPrecisionOffsetMod;
|
||||
FfxFloat32 NegRecEffectRadius; // -1.0 / EffectRadius
|
||||
FfxFloat32 LoadCounterAvgDiv; // 1.0 / ( halfDepthMip[SSAO_DEPTH_MIP_LEVELS-1].sizeX * halfDepthMip[SSAO_DEPTH_MIP_LEVELS-1].sizeY )
|
||||
FfxFloat32 AdaptiveSampleCountLimit;
|
||||
|
||||
FfxFloat32 InvSharpness;
|
||||
FfxInt32 BlurNumPasses;
|
||||
FfxFloat32 BilateralSigmaSquared;
|
||||
FfxFloat32 BilateralSimilarityDistanceSigma;
|
||||
|
||||
FfxFloat32x4 PatternRotScaleMatrices[4][5];
|
||||
|
||||
FfxFloat32 NormalsUnpackMul;
|
||||
FfxFloat32 NormalsUnpackAdd;
|
||||
FfxFloat32 DetailAOStrength;
|
||||
FfxFloat32 Dummy0;
|
||||
|
||||
FfxFloat32x2 SSAOBufferDimensions;
|
||||
FfxFloat32x2 SSAOBufferInverseDimensions;
|
||||
|
||||
FfxFloat32x2 DepthBufferDimensions;
|
||||
FfxFloat32x2 DepthBufferInverseDimensions;
|
||||
|
||||
FfxInt32x2 DepthBufferOffset;
|
||||
FfxFloat32x4 PerPassFullResUVOffset[4];
|
||||
|
||||
FfxFloat32x2 OutputBufferDimensions;
|
||||
FfxFloat32x2 OutputBufferInverseDimensions;
|
||||
|
||||
FfxFloat32x2 ImportanceMapDimensions;
|
||||
FfxFloat32x2 ImportanceMapInverseDimensions;
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferDimensions;
|
||||
FfxFloat32x2 DeinterleavedDepthBufferInverseDimensions;
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferOffset;
|
||||
FfxFloat32x2 DeinterleavedDepthBufferNormalisedOffset;
|
||||
|
||||
mat4 NormalsWorldToViewspaceMatrix;
|
||||
};
|
||||
|
||||
layout (set=0, binding = CACAO_BIND_CB_CACAO) uniform SSAOConstantsBuffer_t
|
||||
{
|
||||
FFX_CACAO_Constants g_FFX_CACAO_Consts;
|
||||
};
|
||||
|
||||
#define FFX_CACAO_CONSTANT_BUFFER_1_SIZE 172 // Number of 32-bit values. This must be kept in sync with max( cbRCAS , cbSPD) size.
|
||||
#endif
|
||||
|
||||
FfxFloat32x2 DepthUnpackConsts(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthUnpackConsts;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 CameraTanHalfFOV(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.CameraTanHalfFOV;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 NDCToViewMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NDCToViewMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 NDCToViewAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NDCToViewAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DepthBufferUVToViewMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferUVToViewMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DepthBufferUVToViewAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferUVToViewAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 EffectRadius(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectRadius;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectShadowStrength(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectShadowStrength;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectShadowPow(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectShadowPow;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectShadowClamp(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectShadowClamp;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 EffectFadeOutMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectFadeOutMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectFadeOutAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectFadeOutAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectHorizonAngleThreshold(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectHorizonAngleThreshold;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectSamplingRadiusNearLimitRec(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectSamplingRadiusNearLimitRec;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 DepthPrecisionOffsetMod(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthPrecisionOffsetMod;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 NegRecEffectRadius(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NegRecEffectRadius;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 LoadCounterAvgDiv(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.LoadCounterAvgDiv;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 AdaptiveSampleCountLimit(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.AdaptiveSampleCountLimit;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 InvSharpness(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.InvSharpness;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxInt32 BlurNumPasses(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.BlurNumPasses;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 BilateralSigmaSquared(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.BilateralSigmaSquared;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 BilateralSimilarityDistanceSigma(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.BilateralSimilarityDistanceSigma;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 PatternRotScaleMatrices(uint i, uint j){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.PatternRotScaleMatrices[i][j];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NormalsUnpackMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 NormalsUnpackAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NormalsUnpackAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 DetailAOStrength(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DetailAOStrength;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 Dummy0(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.Dummy0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 SSAOBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.SSAOBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 SSAOBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.SSAOBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DepthBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DepthBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxInt32x2 DepthBufferOffset(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferOffset;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x4 PerPassFullResUVOffset(uint i){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.PerPassFullResUVOffset[i];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 OutputBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.OutputBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 OutputBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.OutputBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 ImportanceMapDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.ImportanceMapDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 ImportanceMapInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.ImportanceMapInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DeinterleavedDepthBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferOffset(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferOffset;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DeinterleavedDepthBufferNormalisedOffset(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferNormalisedOffset;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
mat4 NormalsWorldToViewspaceMatrix(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NormalsWorldToViewspaceMatrix;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
layout (set=0, binding = 1000) uniform sampler g_PointClampSampler;
|
||||
layout (set=0, binding = 1001) uniform sampler g_PointMirrorSampler;
|
||||
layout (set=0, binding = 1002) uniform sampler g_LinearClampSampler;
|
||||
layout (set=0, binding = 1003) uniform sampler g_ViewspaceDepthTapSampler;
|
||||
layout (set=0, binding = 1004) uniform sampler g_RealPointClampSampler;
|
||||
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
layout (set=0, binding = CACAO_BIND_SRV_DEPTH_IN) uniform texture2D g_DepthIn;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_NORMAL_IN
|
||||
layout (set=0, binding = CACAO_BIND_SRV_NORMAL_IN) uniform texture2D g_NormalIn;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_LOAD_COUNTER
|
||||
layout (set=0, binding = CACAO_BIND_SRV_LOAD_COUNTER) uniform utexture1D g_LoadCounter;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
layout (set=0, binding = CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS) uniform texture2DArray g_DeinterleavedDepth;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS
|
||||
layout (set=0, binding = CACAO_BIND_SRV_DEINTERLEAVED_NORMALS) uniform texture2DArray g_DeinterleavedNormals;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
layout (set=0, binding = CACAO_BIND_SRV_SSAO_BUFFER_PING) uniform texture2DArray g_SsaoBufferPing;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
layout (set=0, binding = CACAO_BIND_SRV_SSAO_BUFFER_PONG) uniform texture2DArray g_SsaoBufferPong;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
layout (set=0, binding = CACAO_BIND_SRV_IMPORTANCE_MAP) uniform texture2D g_ImportanceMap;
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG
|
||||
layout (set=0, binding = CACAO_BIND_SRV_IMPORTANCE_MAP_PONG) uniform texture2D g_ImportanceMapPong;
|
||||
#endif
|
||||
|
||||
#if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
layout (set=0, binding = CACAO_BIND_UAV_LOAD_COUNTER, r32ui) uniform uimage1D g_RwLoadCounter;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
layout (set=0, binding = CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS, r32f) uniform image2DArray g_RwDeinterleavedDepth;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_NORMALS
|
||||
layout (set=0, binding = CACAO_BIND_UAV_DEINTERLEAVED_NORMALS, rgba32f) uniform image2DArray g_RwDeinterleavedNormals;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PING
|
||||
layout (set=0, binding = CACAO_BIND_UAV_SSAO_BUFFER_PING, rg32f) uniform image2DArray g_RwSsaoBufferPing;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG
|
||||
layout (set=0, binding = CACAO_BIND_UAV_SSAO_BUFFER_PONG, rg32f) uniform image2DArray g_RwSsaoBufferPong;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
layout (set = 0, binding = CACAO_BIND_UAV_IMPORTANCE_MAP, r32f) uniform image2D g_RwImportanceMap;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG
|
||||
layout (set = 0, binding = CACAO_BIND_UAV_IMPORTANCE_MAP_PONG, r32f) uniform image2D g_RwImportanceMapPong;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_OUTPUT
|
||||
layout (set = 0, binding = CACAO_BIND_UAV_OUTPUT, rgba16f) uniform image2D g_RwOutput;
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
layout (set = 0, binding = CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS, r32f) uniform image2DArray g_RwDepthMips[4];
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
// Clear Load Counter
|
||||
#if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
void FFX_CACAO_ClearLoadCounter_SetLoadCounter(FfxUInt32 val)
|
||||
{
|
||||
imageStore(g_RwLoadCounter, 0, FfxUInt32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
|
||||
// =============================================================================
|
||||
// Edge Sensitive Blur
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32x2 FFX_CACAO_EdgeSensitiveBlur_SampleInput(FfxFloat32x2 uv, FfxUInt32 layerId)
|
||||
{
|
||||
return textureLod(sampler2DArray(g_SsaoBufferPing, g_PointMirrorSampler), FfxFloat32x3(uv, FfxFloat32(layerId)), 0.0f).xy;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG
|
||||
void FFX_CACAO_EdgeSensitiveBlur_StoreOutput(FfxUInt32x2 coord, FfxFloat32x2 value, FfxUInt32 layerId)
|
||||
{
|
||||
imageStore(g_RwSsaoBufferPong, FfxInt32x3(coord, layerId), FfxFloat32x4(value, 0, 0));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG
|
||||
|
||||
// =============================================================================
|
||||
// SSAO Generation
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
FfxFloat32 FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(FfxFloat32x2 uv, FfxFloat32 mip, FfxUInt32 layerId)
|
||||
{
|
||||
return textureLod(sampler2DArray(g_DeinterleavedDepth, g_ViewspaceDepthTapSampler), FfxFloat32x3(uv, FfxFloat32(layerId)), mip).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
FfxFloat32x4 FFX_CACAO_SSAOGeneration_GatherViewspaceDepthOffset(FfxFloat32x2 uv, FfxInt32x2 offset, FfxUInt32 layerId)
|
||||
{
|
||||
return textureGatherOffset(sampler2DArray(g_DeinterleavedDepth, g_PointMirrorSampler), FfxFloat32x3(uv, FfxFloat32(layerId)), offset, 0);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#if defined CACAO_BIND_SRV_LOAD_COUNTER
|
||||
FfxUInt32 FFX_CACAO_SSAOGeneration_GetLoadCounter()
|
||||
{
|
||||
return FfxUInt32(texelFetch(g_LoadCounter, 0, 0).x);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_LOAD_COUNTER
|
||||
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
FfxFloat32 FFX_CACAO_SSAOGeneration_SampleImportance(FfxFloat32x2 uv)
|
||||
{
|
||||
return textureLod(sampler2D(g_ImportanceMap, g_LinearClampSampler), uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
FfxFloat32x2 FFX_CACAO_SSAOGeneration_LoadBasePassSSAOPass(FfxUInt32x2 coord, FfxUInt32 pass)
|
||||
{
|
||||
return texelFetch(g_SsaoBufferPong, FfxInt32x3(coord, pass), 0).xy;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS
|
||||
FfxFloat32x3 FFX_CACAO_SSAOGeneration_GetNormalPass(FfxUInt32x2 coord, FfxUInt32 pass)
|
||||
{
|
||||
return texelFetch(g_DeinterleavedNormals, FfxInt32x3(coord, pass), 0).xyz;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS
|
||||
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PING
|
||||
void FFX_CACAO_SSAOGeneration_StoreOutput(FfxUInt32x2 coord, FfxFloat32x2 val, FfxUInt32 layerId)
|
||||
{
|
||||
imageStore(g_RwSsaoBufferPing, FfxInt32x3(coord, layerId), FfxFloat32x4(val, 0, 0));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_SSAO_BUFFER_PING
|
||||
|
||||
// ============================================================================
|
||||
// Apply
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32 FFX_CACAO_Apply_SampleSSAOUVPass(FfxFloat32x2 uv, FfxUInt32 pass)
|
||||
{
|
||||
return textureLod(sampler2DArray(g_SsaoBufferPing, g_LinearClampSampler), FfxFloat32x3(uv, pass), 0.0f).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32x2 FFX_CACAO_Apply_LoadSSAOPass(FfxUInt32x2 coord, FfxUInt32 pass)
|
||||
{
|
||||
return texelFetch(g_SsaoBufferPing, FfxInt32x3(coord, pass), 0).xy;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_UAV_OUTPUT
|
||||
void FFX_CACAO_Apply_StoreOutput(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
FfxFloat32x4 prev = imageLoad(g_RwOutput, FfxInt32x2(coord));
|
||||
imageStore(g_RwOutput, FfxInt32x2(coord), FfxFloat32x4(val, prev.g, prev.b, prev.a));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_OUTPUT
|
||||
|
||||
// =============================================================================
|
||||
// Prepare
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_Prepare_SampleDepthOffsets(FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat32x4 samples;
|
||||
samples.x = textureLodOffset(sampler2D(g_DepthIn, g_PointClampSampler), uv, 0.0f, FfxInt32x2(0, 2)).x;
|
||||
samples.y = textureLodOffset(sampler2D(g_DepthIn, g_PointClampSampler), uv, 0.0f, FfxInt32x2(2, 2)).x;
|
||||
samples.z = textureLodOffset(sampler2D(g_DepthIn, g_PointClampSampler), uv, 0.0f, FfxInt32x2(2, 0)).x;
|
||||
samples.w = textureLodOffset(sampler2D(g_DepthIn, g_PointClampSampler), uv, 0.0f, FfxInt32x2(0, 0)).x;
|
||||
return samples;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_Prepare_GatherDepth(FfxFloat32x2 uv)
|
||||
{
|
||||
return textureGather(sampler2D(g_DepthIn, g_PointClampSampler), uv, 0);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32 FFX_CACAO_Prepare_LoadDepth(FfxUInt32x2 coord)
|
||||
{
|
||||
return texelFetch(g_DepthIn, FfxInt32x2(coord), 0).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32 FFX_CACAO_Prepare_LoadDepthOffset(FfxUInt32x2 coord, FfxInt32x2 offset)
|
||||
{
|
||||
return texelFetch(g_DepthIn, FfxInt32x2(coord) + offset, 0).x; //CACAO_TODO
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_Prepare_GatherDepthOffset(FfxFloat32x2 uv, FfxInt32x2 offset)
|
||||
{
|
||||
return textureGatherOffset(sampler2D(g_DepthIn, g_PointClampSampler), uv, offset, 0);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_NORMAL_IN
|
||||
FfxFloat32x3 FFX_CACAO_Prepare_LoadNormal(FfxUInt32x2 coord)
|
||||
{
|
||||
FfxFloat32x3 normal = texelFetch(g_NormalIn, FfxInt32x2(coord), 0).xyz;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
normal = FFX_TRANSFORM_VECTOR(normal, FfxFloat32x3x3(NormalsWorldToViewspaceMatrix())).xyz;
|
||||
return normal;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_NORMAL_IN
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip0(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwDepthMips[0], FfxInt32x3(coord, index), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip1(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwDepthMips[1], FfxInt32x3(coord, index), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip2(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwDepthMips[2], FfxInt32x3(coord, index), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip3(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwDepthMips[3], FfxInt32x3(coord, index), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
void FFX_CACAO_Prepare_StoreDepth(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwDeinterleavedDepth, FfxInt32x3(coord, index), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
void FFX_CACAO_Prepare_StoreNormal(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32x3 normal)
|
||||
{
|
||||
imageStore(g_RwDeinterleavedNormals, FfxInt32x3(coord, index), FfxFloat32x4(normal, 1.0f));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
// =============================================================================
|
||||
// Importance Map
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
FfxFloat32x4 FFX_CACAO_Importance_GatherSSAO(FfxFloat32x2 uv, FfxUInt32 index)
|
||||
{
|
||||
return textureGather(sampler2DArray(g_SsaoBufferPong, g_PointClampSampler), FfxFloat32x3(uv, index), 0);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
void FFX_CACAO_Importance_StoreImportance(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwImportanceMap, FfxInt32x2(coord), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
FfxFloat32 FFX_CACAO_Importance_SampleImportanceA(FfxFloat32x2 uv)
|
||||
{
|
||||
return textureLod(sampler2D(g_ImportanceMap, g_LinearClampSampler), uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG
|
||||
void FFX_CACAO_Importance_StoreImportanceA(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwImportanceMapPong, FfxInt32x2(coord), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG
|
||||
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG
|
||||
FfxFloat32 FFX_CACAO_Importance_SampleImportanceB(FfxFloat32x2 uv)
|
||||
{
|
||||
return textureLod(sampler2D(g_ImportanceMapPong, g_LinearClampSampler), uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG
|
||||
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
void FFX_CACAO_Importance_StoreImportanceB(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
imageStore(g_RwImportanceMap, FfxInt32x2(coord), FfxFloat32x4(val, val, val, val));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
void FFX_CACAO_Importance_LoadCounterInterlockedAdd(FfxUInt32 val)
|
||||
{
|
||||
imageAtomicAdd(g_RwLoadCounter, 0, val);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
|
||||
// =============================================================================
|
||||
// Bilateral Upscale
|
||||
|
||||
// These resources ping/pong which is handled by schedule dispatch
|
||||
#if defined CACAO_BIND_UAV_OUTPUT
|
||||
void FFX_CACAO_BilateralUpscale_StoreOutput(FfxUInt32x2 coord, FfxInt32x2 offset, FfxFloat32 val)
|
||||
{
|
||||
FfxFloat32x4 prev = imageLoad(g_RwOutput, FfxInt32x2(coord) + offset);
|
||||
imageStore(g_RwOutput, FfxInt32x2(coord) + offset, FfxFloat32x4(val, prev.g, prev.b, prev.a));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_OUTPUT
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32 FFX_CACAO_BilateralUpscale_SampleSSAOLinear(FfxFloat32x2 uv, FfxUInt32 index)
|
||||
{
|
||||
return textureLod(sampler2DArray(g_SsaoBufferPing, g_LinearClampSampler), FfxFloat32x3(uv, index), 0).r;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32 FFX_CACAO_BilateralUpscale_SampleSSAOPoint(FfxFloat32x2 uv, FfxUInt32 index)
|
||||
{
|
||||
return textureLod(sampler2DArray(g_SsaoBufferPing, g_PointClampSampler), FfxFloat32x3(uv, index), 0).r;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32x2 FFX_CACAO_BilateralUpscale_LoadSSAO(FfxUInt32x2 coord, FfxUInt32 index)
|
||||
{
|
||||
return texelFetch(g_SsaoBufferPing, FfxInt32x3(coord, index), 0).rg;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_BilateralUpscale_LoadDepths(FfxUInt32x2 coord)
|
||||
{
|
||||
FfxFloat32x4 depths;
|
||||
depths.x = texelFetchOffset(g_DepthIn, FfxInt32x2(coord), 0, FfxInt32x2(0, 0)).x;
|
||||
depths.y = texelFetchOffset(g_DepthIn, FfxInt32x2(coord), 0, FfxInt32x2(1, 0)).x;
|
||||
depths.z = texelFetchOffset(g_DepthIn, FfxInt32x2(coord), 0, FfxInt32x2(0, 1)).x;
|
||||
depths.w = texelFetchOffset(g_DepthIn, FfxInt32x2(coord), 0, FfxInt32x2(1, 1)).x;
|
||||
return depths;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
FfxFloat32 FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(FfxUInt32x2 coord, FfxUInt32 index)
|
||||
{
|
||||
return texelFetch(g_DeinterleavedDepth, FfxInt32x3(coord, index), 0).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
852
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_callbacks_hlsl.h
vendored
Normal file
852
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,852 @@
|
||||
// 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_cacao_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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
|
||||
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
|
||||
#define DECLARE_CB_REGISTER(regIndex) b##regIndex
|
||||
#define FFX_CACAO_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_CACAO_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_CACAO_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
struct FFX_CACAO_Constants
|
||||
{
|
||||
FfxFloat32x2 DepthUnpackConsts;
|
||||
FfxFloat32x2 CameraTanHalfFOV;
|
||||
|
||||
FfxFloat32x2 NDCToViewMul;
|
||||
FfxFloat32x2 NDCToViewAdd;
|
||||
|
||||
FfxFloat32x2 DepthBufferUVToViewMul;
|
||||
FfxFloat32x2 DepthBufferUVToViewAdd;
|
||||
|
||||
FfxFloat32 EffectRadius; // world (viewspace) maximum size of the shadow
|
||||
FfxFloat32 EffectShadowStrength; // global strength of the effect (0 - 5)
|
||||
FfxFloat32 EffectShadowPow;
|
||||
FfxFloat32 EffectShadowClamp;
|
||||
|
||||
FfxFloat32 EffectFadeOutMul; // effect fade out from distance (ex. 25)
|
||||
FfxFloat32 EffectFadeOutAdd; // effect fade out to distance (ex. 100)
|
||||
FfxFloat32 EffectHorizonAngleThreshold; // limit errors on slopes and caused by insufficient geometry tessellation (0.05 to 0.5)
|
||||
FfxFloat32 EffectSamplingRadiusNearLimitRec; // if viewspace pixel closer than this, don't enlarge shadow sampling radius anymore (makes no sense to grow beyond some distance, not enough samples to cover everything, so just limit the shadow growth; could be SSAOSettingsFadeOutFrom * 0.1 or less)
|
||||
|
||||
FfxFloat32 DepthPrecisionOffsetMod;
|
||||
FfxFloat32 NegRecEffectRadius; // -1.0 / EffectRadius
|
||||
FfxFloat32 LoadCounterAvgDiv; // 1.0 / ( halfDepthMip[SSAO_DEPTH_MIP_LEVELS-1].sizeX * halfDepthMip[SSAO_DEPTH_MIP_LEVELS-1].sizeY )
|
||||
FfxFloat32 AdaptiveSampleCountLimit;
|
||||
|
||||
FfxFloat32 InvSharpness;
|
||||
FfxInt32 BlurNumPasses;
|
||||
FfxFloat32 BilateralSigmaSquared;
|
||||
FfxFloat32 BilateralSimilarityDistanceSigma;
|
||||
|
||||
FfxFloat32x4 PatternRotScaleMatrices[4][5];
|
||||
|
||||
FfxFloat32 NormalsUnpackMul;
|
||||
FfxFloat32 NormalsUnpackAdd;
|
||||
FfxFloat32 DetailAOStrength;
|
||||
FfxFloat32 Dummy0;
|
||||
|
||||
FfxFloat32x2 SSAOBufferDimensions;
|
||||
FfxFloat32x2 SSAOBufferInverseDimensions;
|
||||
|
||||
FfxFloat32x2 DepthBufferDimensions;
|
||||
FfxFloat32x2 DepthBufferInverseDimensions;
|
||||
|
||||
FfxInt32x2 DepthBufferOffset;
|
||||
FfxFloat32x4 PerPassFullResUVOffset[4];
|
||||
|
||||
FfxFloat32x2 OutputBufferDimensions;
|
||||
FfxFloat32x2 OutputBufferInverseDimensions;
|
||||
|
||||
FfxFloat32x2 ImportanceMapDimensions;
|
||||
FfxFloat32x2 ImportanceMapInverseDimensions;
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferDimensions;
|
||||
FfxFloat32x2 DeinterleavedDepthBufferInverseDimensions;
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferOffset;
|
||||
FfxFloat32x2 DeinterleavedDepthBufferNormalisedOffset;
|
||||
|
||||
float4x4 NormalsWorldToViewspaceMatrix;
|
||||
};
|
||||
|
||||
cbuffer SSAOConstantsBuffer_t : register(b0)
|
||||
{
|
||||
FFX_CACAO_Constants g_FFX_CACAO_Consts;
|
||||
}
|
||||
|
||||
#define FFX_CACAO_CONSTANT_BUFFER_1_SIZE 172 // Number of 32-bit values. This must be kept in sync with max( cbRCAS , cbSPD) size.
|
||||
#endif
|
||||
|
||||
FfxFloat32x2 DepthUnpackConsts(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthUnpackConsts;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 CameraTanHalfFOV(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.CameraTanHalfFOV;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 NDCToViewMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NDCToViewMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 NDCToViewAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NDCToViewAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DepthBufferUVToViewMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferUVToViewMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DepthBufferUVToViewAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferUVToViewAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 EffectRadius(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectRadius;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectShadowStrength(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectShadowStrength;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectShadowPow(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectShadowPow;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectShadowClamp(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectShadowClamp;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 EffectFadeOutMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectFadeOutMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectFadeOutAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectFadeOutAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectHorizonAngleThreshold(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectHorizonAngleThreshold;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 EffectSamplingRadiusNearLimitRec(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.EffectSamplingRadiusNearLimitRec;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 DepthPrecisionOffsetMod(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthPrecisionOffsetMod;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 NegRecEffectRadius(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NegRecEffectRadius;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 LoadCounterAvgDiv(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.LoadCounterAvgDiv;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 AdaptiveSampleCountLimit(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.AdaptiveSampleCountLimit;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 InvSharpness(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.InvSharpness;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxInt32 BlurNumPasses(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.BlurNumPasses;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 BilateralSigmaSquared(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.BilateralSigmaSquared;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 BilateralSimilarityDistanceSigma(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.BilateralSimilarityDistanceSigma;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 PatternRotScaleMatrices(uint i, uint j){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.PatternRotScaleMatrices[i][j];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NormalsUnpackMul;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 NormalsUnpackAdd(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NormalsUnpackAdd;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 DetailAOStrength(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DetailAOStrength;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32 Dummy0(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.Dummy0;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 SSAOBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.SSAOBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 SSAOBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.SSAOBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DepthBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DepthBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxInt32x2 DepthBufferOffset(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DepthBufferOffset;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x4 PerPassFullResUVOffset(uint i){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.PerPassFullResUVOffset[i];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 OutputBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.OutputBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 OutputBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.OutputBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 ImportanceMapDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.ImportanceMapDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 ImportanceMapInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.ImportanceMapInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DeinterleavedDepthBufferInverseDimensions(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferInverseDimensions;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 DeinterleavedDepthBufferOffset(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferOffset;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
FfxFloat32x2 DeinterleavedDepthBufferNormalisedOffset(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.DeinterleavedDepthBufferNormalisedOffset;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
float4x4 NormalsWorldToViewspaceMatrix(){
|
||||
#if defined(CACAO_BIND_CB_CACAO)
|
||||
return g_FFX_CACAO_Consts.NormalsWorldToViewspaceMatrix;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#define FFX_CACAO_ROOTSIG_STRINGIFY(p) FFX_CACAO_ROOTSIG_STR(p)
|
||||
#define FFX_CACAO_ROOTSIG_STR(p) #p
|
||||
#define FFX_CACAO_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_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_POINT, " \
|
||||
"addressU = TEXTURE_ADDRESS_MIRROR, " \
|
||||
"addressV = TEXTURE_ADDRESS_MIRROR, " \
|
||||
"addressW = TEXTURE_ADDRESS_MIRROR, " \
|
||||
"comparisonFunc = COMPARISON_NEVER, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK), " \
|
||||
"StaticSampler(s2, 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), " \
|
||||
"StaticSampler(s3, 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)" )]
|
||||
|
||||
#define FFX_CACAO_CB2_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0)" )]
|
||||
|
||||
#define FFX_CACAO_CB_GENERATE_REACTIVE_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CACAO_ROOTSIG_STRINGIFY(FFX_CACAO_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0), " \
|
||||
"CBV(b1)")]
|
||||
|
||||
#if defined(FFX_CACAO_EMBED_ROOTSIG)
|
||||
#define FFX_CACAO_EMBED_ROOTSIG_CONTENT FFX_CACAO_ROOTSIG
|
||||
#define FFX_CACAO_EMBED_CB2_ROOTSIG_CONTENT FFX_CACAO_CB2_ROOTSIG
|
||||
#define FFX_CACAO_EMBED_CB_GENERATE_REACTIVE_ROOTSIG_CONTENT FFX_CACAO_CB_GENERATE_REACTIVE_ROOTSIG
|
||||
#else
|
||||
#define FFX_CACAO_EMBED_ROOTSIG_CONTENT
|
||||
#define FFX_CACAO_EMBED_CB2_ROOTSIG_CONTENT
|
||||
#define FFX_CACAO_EMBED_CB_GENERATE_REACTIVE_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_CACAO_EMBED_ROOTSIG
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
SamplerState g_PointClampSampler : register(s0);
|
||||
SamplerState g_PointMirrorSampler : register(s1);
|
||||
SamplerState g_LinearClampSampler : register(s2);
|
||||
SamplerState g_ViewspaceDepthTapSampler : register(s3);
|
||||
SamplerState g_RealPointClampSampler : register(s4);
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
Texture2D<FfxFloat32> g_DepthIn : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_DEPTH_IN);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
Texture2D<FfxFloat32x4> g_NormalIn : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_NORMAL_IN);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_LOAD_COUNTER
|
||||
Texture1D<FfxUInt32> g_LoadCounter : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_LOAD_COUNTER_BUFFER);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
Texture2DArray<FfxFloat32> g_DeinterleavedDepth : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_DEPTHS);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS
|
||||
Texture2DArray<FfxFloat32x4> g_DeinterleavedNormals : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_NORMALS);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
Texture2DArray<FfxFloat32x2> g_SsaoBufferPing : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PONG);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
Texture2DArray<FfxFloat32x2> g_SsaoBufferPong : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PONG);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
Texture2D<FfxFloat32> g_ImportanceMap : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP);
|
||||
#endif
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG
|
||||
Texture2D<FfxFloat32> g_ImportanceMapPong : FFX_CACAO_DECLARE_SRV(FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP_PONG);
|
||||
#endif
|
||||
|
||||
#if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
RWTexture1D<FfxUInt32> g_RwLoadCounter : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_LOAD_COUNTER_BUFFER);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
RWTexture2DArray<FfxFloat32> g_RwDeinterleavedDepth : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_DEPTHS);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_NORMALS
|
||||
RWTexture2DArray<FfxFloat32x4> g_RwDeinterleavedNormals : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_NORMALS);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PING
|
||||
RWTexture2DArray<FfxFloat32x2> g_RwSsaoBufferPing : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PONG);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG
|
||||
RWTexture2DArray<FfxFloat32x2> g_RwSsaoBufferPong : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PONG);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
RWTexture2D<FfxFloat32> g_RwImportanceMap : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG
|
||||
RWTexture2D<FfxFloat32> g_RwImportanceMapPong : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP_PONG);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_OUTPUT
|
||||
RWTexture2D<FfxFloat32x4> g_RwOutput : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_OUTPUT);
|
||||
#endif
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
RWTexture2DArray<FfxFloat32> g_RwDepthMips[4] : FFX_CACAO_DECLARE_UAV(FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_0);
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
// Clear Load Counter
|
||||
|
||||
#if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
void FFX_CACAO_ClearLoadCounter_SetLoadCounter(FfxUInt32 val)
|
||||
{
|
||||
g_RwLoadCounter[0] = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
// =============================================================================
|
||||
// Edge Sensitive Blur
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32x2 FFX_CACAO_EdgeSensitiveBlur_SampleInputOffset(FfxFloat32x2 uv, FfxInt32x2 offset, FfxUInt32 layerId)
|
||||
{
|
||||
return g_SsaoBufferPing.SampleLevel(g_PointMirrorSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), 0.0f, offset);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32x2 FFX_CACAO_EdgeSensitiveBlur_SampleInput(FfxFloat32x2 uv, FfxUInt32 layerId)
|
||||
{
|
||||
return g_SsaoBufferPing.SampleLevel(g_PointMirrorSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), 0.0f);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG
|
||||
void FFX_CACAO_EdgeSensitiveBlur_StoreOutput(FfxUInt32x2 coord, FfxFloat32x2 value, FfxUInt32 layerId)
|
||||
{
|
||||
g_RwSsaoBufferPong[FfxInt32x3(coord, layerId)] = value;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_SSAO_BUFFER_PONG
|
||||
|
||||
// =============================================================================
|
||||
// SSAO Generation
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
FfxFloat32 FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(FfxFloat32x2 uv, FfxFloat32 mip, FfxUInt32 layerId)
|
||||
{
|
||||
return g_DeinterleavedDepth.SampleLevel(g_ViewspaceDepthTapSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), mip);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
FfxFloat32x4 FFX_CACAO_SSAOGeneration_GatherViewspaceDepthOffset(FfxFloat32x2 uv, FfxInt32x2 offset, FfxUInt32 layerId)
|
||||
{
|
||||
return g_DeinterleavedDepth.GatherRed(g_PointMirrorSampler, FfxFloat32x3(uv, FfxFloat32(layerId)), offset);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#if defined CACAO_BIND_SRV_LOAD_COUNTER
|
||||
FfxUInt32 FFX_CACAO_SSAOGeneration_GetLoadCounter()
|
||||
{
|
||||
return g_LoadCounter[0];
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_LOAD_COUNTER
|
||||
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
FfxFloat32 FFX_CACAO_SSAOGeneration_SampleImportance(FfxFloat32x2 uv)
|
||||
{
|
||||
return g_ImportanceMap.SampleLevel(g_LinearClampSampler, uv, 0.0f);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
FfxFloat32x2 FFX_CACAO_SSAOGeneration_LoadBasePassSSAOPass(FfxUInt32x2 coord, FfxUInt32 pass)
|
||||
{
|
||||
return g_SsaoBufferPong.Load(FfxInt32x4(coord, pass, 0)).xy;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS
|
||||
FfxFloat32x3 FFX_CACAO_SSAOGeneration_GetNormalPass(FfxUInt32x2 coord, FfxUInt32 pass)
|
||||
{
|
||||
return g_DeinterleavedNormals[FfxInt32x3(coord, pass)].xyz;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_NORMALS
|
||||
|
||||
#if defined CACAO_BIND_UAV_SSAO_BUFFER_PING
|
||||
void FFX_CACAO_SSAOGeneration_StoreOutput(FfxUInt32x2 coord, FfxFloat32x2 val, FfxUInt32 layerId)
|
||||
{
|
||||
g_RwSsaoBufferPing[FfxInt32x3(coord, layerId)] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_SSAO_BUFFER_PING
|
||||
|
||||
// ============================================================================
|
||||
// Apply
|
||||
|
||||
// This resource can be ssao ping or pong, handled by schedule Dispatch
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32 FFX_CACAO_Apply_SampleSSAOUVPass(FfxFloat32x2 uv, FfxUInt32 pass)
|
||||
{
|
||||
return g_SsaoBufferPing.SampleLevel(g_LinearClampSampler, FfxFloat32x3(uv, pass), 0.0f).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32x2 FFX_CACAO_Apply_LoadSSAOPass(FfxUInt32x2 coord, FfxUInt32 pass)
|
||||
{
|
||||
return g_SsaoBufferPing.Load(FfxInt32x4(coord, pass, 0));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_UAV_OUTPUT
|
||||
void FFX_CACAO_Apply_StoreOutput(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
g_RwOutput[coord].r = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_OUTPUT
|
||||
|
||||
// =============================================================================
|
||||
// Prepare
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_Prepare_SampleDepthOffsets(FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat32x4 samples;
|
||||
samples.x = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(0, 2));
|
||||
samples.y = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(2, 2));
|
||||
samples.z = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(2, 0));
|
||||
samples.w = g_DepthIn.SampleLevel(g_PointClampSampler, uv, 0.0f, FfxInt32x2(0, 0));
|
||||
return samples;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_Prepare_GatherDepth(FfxFloat32x2 uv)
|
||||
{
|
||||
return g_DepthIn.GatherRed(g_PointClampSampler, uv);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32 FFX_CACAO_Prepare_LoadDepth(FfxUInt32x2 coord)
|
||||
{
|
||||
return g_DepthIn.Load(FfxInt32x3(coord, 0));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32 FFX_CACAO_Prepare_LoadDepthOffset(FfxUInt32x2 coord, FfxInt32x2 offset)
|
||||
{
|
||||
return g_DepthIn.Load(FfxInt32x3(coord, 0), offset);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_Prepare_GatherDepthOffset(FfxFloat32x2 uv, FfxInt32x2 offset)
|
||||
{
|
||||
return g_DepthIn.GatherRed(g_PointClampSampler, uv, offset);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_NORMAL_IN
|
||||
FfxFloat32x3 FFX_CACAO_Prepare_LoadNormal(FfxUInt32x2 coord)
|
||||
{
|
||||
FfxFloat32x3 normal = g_NormalIn.Load(FfxInt32x3(coord, 0)).xyz;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
normal = mul(normal, (float3x3)NormalsWorldToViewspaceMatrix()).xyz;
|
||||
// normal = normalize(normal);
|
||||
return normal;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_NORMAL_IN
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip0(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
g_RwDepthMips[0][FfxInt32x3(coord, index)] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip1(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
g_RwDepthMips[1][FfxInt32x3(coord, index)] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip2(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
g_RwDepthMips[2][FfxInt32x3(coord, index)] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
void FFX_CACAO_Prepare_StoreDepthMip3(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
g_RwDepthMips[3][FfxInt32x3(coord, index)] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEPTH_DOWNSAMPLED_MIPS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
void FFX_CACAO_Prepare_StoreDepth(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32 val)
|
||||
{
|
||||
g_RwDeinterleavedDepth[FfxInt32x3(coord, index)] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
void FFX_CACAO_Prepare_StoreNormal(FfxUInt32x2 coord, FfxUInt32 index, FfxFloat32x3 normal)
|
||||
{
|
||||
g_RwDeinterleavedNormals[FfxInt32x3(coord, index)] = FfxFloat32x4(normal, 1.0f);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
// =============================================================================
|
||||
// Importance Map
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
FfxFloat32x4 FFX_CACAO_Importance_GatherSSAO(FfxFloat32x2 uv, FfxUInt32 index)
|
||||
{
|
||||
return g_SsaoBufferPong.GatherRed(g_PointClampSampler, FfxFloat32x3(uv, index));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PONG
|
||||
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
void FFX_CACAO_Importance_StoreImportance(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
g_RwImportanceMap[coord] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
FfxFloat32 FFX_CACAO_Importance_SampleImportanceA(FfxFloat32x2 uv)
|
||||
{
|
||||
return g_ImportanceMap.SampleLevel(g_LinearClampSampler, uv, 0.0f);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG
|
||||
void FFX_CACAO_Importance_StoreImportanceA(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
g_RwImportanceMapPong[coord] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_IMPORTANCE_MAP_PONG
|
||||
|
||||
#if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG
|
||||
FfxFloat32 FFX_CACAO_Importance_SampleImportanceB(FfxFloat32x2 uv)
|
||||
{
|
||||
return g_ImportanceMapPong.SampleLevel(g_LinearClampSampler, uv, 0.0f);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_IMPORTANCE_MAP_PONG
|
||||
|
||||
#if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
void FFX_CACAO_Importance_StoreImportanceB(FfxUInt32x2 coord, FfxFloat32 val)
|
||||
{
|
||||
g_RwImportanceMap[coord] = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_IMPORTANCE_MAP
|
||||
|
||||
#if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
void FFX_CACAO_Importance_LoadCounterInterlockedAdd(FfxUInt32 val)
|
||||
{
|
||||
InterlockedAdd(g_RwLoadCounter[0], val);
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_LOAD_COUNTER
|
||||
|
||||
// =============================================================================
|
||||
// Bilateral Upscale
|
||||
|
||||
// These resources ping/pong which is handled by schedule dispatch
|
||||
#if defined CACAO_BIND_UAV_OUTPUT
|
||||
void FFX_CACAO_BilateralUpscale_StoreOutput(FfxUInt32x2 coord, FfxInt32x2 offset, FfxFloat32 val)
|
||||
{
|
||||
g_RwOutput[coord + offset].r = val;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_UAV_OUTPUT
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32 FFX_CACAO_BilateralUpscale_SampleSSAOLinear(FfxFloat32x2 uv, FfxUInt32 index)
|
||||
{
|
||||
return g_SsaoBufferPing.SampleLevel(g_LinearClampSampler, FfxFloat32x3(uv, index), 0).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32 FFX_CACAO_BilateralUpscale_SampleSSAOPoint(FfxFloat32x2 uv, FfxUInt32 index)
|
||||
{
|
||||
return g_SsaoBufferPing.SampleLevel(g_PointClampSampler, FfxFloat32x3(uv, index), 0).x;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
FfxFloat32x2 FFX_CACAO_BilateralUpscale_LoadSSAO(FfxUInt32x2 coord, FfxUInt32 index)
|
||||
{
|
||||
return g_SsaoBufferPing.Load(FfxInt32x4(coord, index, 0));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_SSAO_BUFFER_PING
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
FfxFloat32x4 FFX_CACAO_BilateralUpscale_LoadDepths(FfxUInt32x2 coord)
|
||||
{
|
||||
FfxFloat32x4 depths;
|
||||
depths.x = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(0, 0));
|
||||
depths.y = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(1, 0));
|
||||
depths.z = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(0, 1));
|
||||
depths.w = g_DepthIn.Load(FfxInt32x3(coord, 0), FfxInt32x2(1, 1));
|
||||
return depths;
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEPTH_IN
|
||||
|
||||
#if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
FfxFloat32 FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(FfxUInt32x2 coord, FfxUInt32 index)
|
||||
{
|
||||
return g_DeinterleavedDepth.Load(FfxInt32x4(coord, index, 0));
|
||||
}
|
||||
#endif // #if defined CACAO_BIND_SRV_DEINTERLEAVED_DEPTHS
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
85
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_defines.h
vendored
Normal file
85
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_defines.h
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// 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.
|
||||
|
||||
// Defines for constants common to both CACAO.cpp and CACAO.hlsl
|
||||
|
||||
#ifndef FFX_CACAO_DEFINES_H
|
||||
#define FFX_CACAO_DEFINES_H
|
||||
|
||||
// ============================================================================
|
||||
// Prepare
|
||||
|
||||
#define FFX_CACAO_PREPARE_DEPTHS_AND_MIPS_WIDTH 8
|
||||
#define FFX_CACAO_PREPARE_DEPTHS_AND_MIPS_HEIGHT 8
|
||||
|
||||
#define FFX_CACAO_PREPARE_DEPTHS_WIDTH 8
|
||||
#define FFX_CACAO_PREPARE_DEPTHS_HEIGHT 8
|
||||
|
||||
#define FFX_CACAO_PREPARE_DEPTHS_HALF_WIDTH 8
|
||||
#define FFX_CACAO_PREPARE_DEPTHS_HALF_HEIGHT 8
|
||||
|
||||
#define FFX_CACAO_PREPARE_NORMALS_WIDTH 8
|
||||
#define FFX_CACAO_PREPARE_NORMALS_HEIGHT 8
|
||||
|
||||
#define PREPARE_NORMALS_FROM_INPUT_NORMALS_WIDTH 8
|
||||
#define PREPARE_NORMALS_FROM_INPUT_NORMALS_HEIGHT 8
|
||||
|
||||
// ============================================================================
|
||||
// SSAO Generation
|
||||
|
||||
#define FFX_CACAO_GENERATE_SPARSE_WIDTH 4
|
||||
#define FFX_CACAO_GENERATE_SPARSE_HEIGHT 16
|
||||
|
||||
#define FFX_CACAO_GENERATE_WIDTH 8
|
||||
#define FFX_CACAO_GENERATE_HEIGHT 8
|
||||
|
||||
// ============================================================================
|
||||
// Importance Map
|
||||
|
||||
#define IMPORTANCE_MAP_WIDTH 8
|
||||
#define IMPORTANCE_MAP_HEIGHT 8
|
||||
|
||||
#define IMPORTANCE_MAP_A_WIDTH 8
|
||||
#define IMPORTANCE_MAP_A_HEIGHT 8
|
||||
|
||||
#define IMPORTANCE_MAP_B_WIDTH 8
|
||||
#define IMPORTANCE_MAP_B_HEIGHT 8
|
||||
|
||||
// ============================================================================
|
||||
// Edge Sensitive Blur
|
||||
|
||||
#define FFX_CACAO_BLUR_WIDTH 16
|
||||
#define FFX_CACAO_BLUR_HEIGHT 16
|
||||
|
||||
// ============================================================================
|
||||
// Apply
|
||||
|
||||
#define FFX_CACAO_APPLY_WIDTH 8
|
||||
#define FFX_CACAO_APPLY_HEIGHT 8
|
||||
|
||||
// ============================================================================
|
||||
// Bilateral Upscale
|
||||
|
||||
#define FFX_CACAO_BILATERAL_UPSCALE_WIDTH 8
|
||||
#define FFX_CACAO_BILATERAL_UPSCALE_HEIGHT 8
|
||||
|
||||
#endif
|
||||
449
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_edge_sensitive_blur.h
vendored
Normal file
449
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_edge_sensitive_blur.h
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_cacao_defines.h"
|
||||
#include "ffx_cacao_utils.h"
|
||||
|
||||
// all in one, SIMD in yo SIMD dawg, shader
|
||||
#define FFX_CACAO_TILE_WIDTH 4
|
||||
#define FFX_CACAO_TILE_HEIGHT 3
|
||||
#define FFX_CACAO_HALF_TILE_WIDTH (FFX_CACAO_TILE_WIDTH / 2)
|
||||
#define FFX_CACAO_QUARTER_TILE_WIDTH (FFX_CACAO_TILE_WIDTH / 4)
|
||||
|
||||
#define FFX_CACAO_ARRAY_WIDTH (FFX_CACAO_HALF_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH + 2)
|
||||
#define FFX_CACAO_ARRAY_HEIGHT (FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT + 2)
|
||||
|
||||
#define FFX_CACAO_ITERS 4
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 s_FFX_CACAO_BlurF16Front_4[FFX_CACAO_ARRAY_WIDTH][FFX_CACAO_ARRAY_HEIGHT];
|
||||
FFX_GROUPSHARED FfxUInt32 s_FFX_CACAO_BlurF16Back_4[FFX_CACAO_ARRAY_WIDTH][FFX_CACAO_ARRAY_HEIGHT];
|
||||
|
||||
#if FFX_HALF
|
||||
struct FFX_CACAO_Edges_4
|
||||
{
|
||||
FfxFloat16x4 left;
|
||||
FfxFloat16x4 right;
|
||||
FfxFloat16x4 top;
|
||||
FfxFloat16x4 bottom;
|
||||
};
|
||||
|
||||
FFX_CACAO_Edges_4 FFX_CACAO_UnpackEdgesFloat16_4(FfxFloat16x4 _packedVal)
|
||||
{
|
||||
FfxUInt32x4 packedVal = FfxUInt32x4(_packedVal * 255.5);
|
||||
FFX_CACAO_Edges_4 result;
|
||||
result.left = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 6) & 0x03) / 3.0 + InvSharpness()));
|
||||
result.right = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 4) & 0x03) / 3.0 + InvSharpness()));
|
||||
result.top = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 2) & 0x03) / 3.0 + InvSharpness()));
|
||||
result.bottom = FfxFloat16x4(ffxSaturate(FfxFloat16x4((packedVal >> 0) & 0x03) / 3.0 + InvSharpness()));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FfxFloat16x4 FFX_CACAO_CalcBlurredSampleF16_4(FfxFloat16x4 packedEdges, FfxFloat16x4 centre, FfxFloat16x4 left, FfxFloat16x4 right, FfxFloat16x4 top, FfxFloat16x4 bottom)
|
||||
{
|
||||
FfxFloat16x4 sum = centre * FfxFloat16(0.5f);
|
||||
FfxFloat16x4 weight = FfxFloat16x4(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
FFX_CACAO_Edges_4 edges = FFX_CACAO_UnpackEdgesFloat16_4(packedEdges);
|
||||
|
||||
sum += left * edges.left;
|
||||
weight += edges.left;
|
||||
sum += right * edges.right;
|
||||
weight += edges.right;
|
||||
sum += top * edges.top;
|
||||
weight += edges.top;
|
||||
sum += bottom * edges.bottom;
|
||||
weight += edges.bottom;
|
||||
|
||||
return sum / weight;
|
||||
}
|
||||
|
||||
void FFX_CACAO_LDSEdgeSensitiveBlur(const FfxUInt32 blurPasses, const FfxUInt32x2 tid, const FfxUInt32x2 gid, const FfxUInt32 layerId)
|
||||
{
|
||||
FfxInt32x2 imageCoord = FfxInt32x2(gid) * (FfxInt32x2(FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH, FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT) - FfxInt32(2*blurPasses)) + FfxInt32x2(FFX_CACAO_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) - FfxInt32(blurPasses);
|
||||
FfxInt32x2 bufferCoord = FfxInt32x2(FFX_CACAO_HALF_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) + 1;
|
||||
|
||||
FfxFloat16x4 packedEdges[FFX_CACAO_QUARTER_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT];
|
||||
{
|
||||
FfxFloat32x2 inputVal[FFX_CACAO_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT];
|
||||
FfxInt32 y;
|
||||
FFX_UNROLL
|
||||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxFloat32x2 sampleUV = (FfxFloat32x2(imageCoord + FfxInt32x2(x, y)) + 0.5f) * SSAOBufferInverseDimensions();
|
||||
inputVal[x][y] = FFX_CACAO_EdgeSensitiveBlur_SampleInput(sampleUV, layerId);
|
||||
}
|
||||
}
|
||||
FFX_UNROLL
|
||||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxFloat16x2 ssaoVals = FfxFloat16x2(inputVal[4 * x + 0][y].x, inputVal[4 * x + 1][y].x);
|
||||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 0][bufferCoord.y + y] = ffxPackF16(ssaoVals);
|
||||
ssaoVals = FfxFloat16x2(inputVal[4 * x + 2][y].x, inputVal[4 * x + 3][y].x);
|
||||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 1][bufferCoord.y + y] = ffxPackF16(ssaoVals);
|
||||
packedEdges[x][y] = FfxFloat16x4(inputVal[4 * x + 0][y].y, inputVal[4 * x + 1][y].y, inputVal[4 * x + 2][y].y, inputVal[4 * x + 3][y].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
FFX_UNROLL
|
||||
for (FfxUInt32 i = 0; i < (blurPasses + 1) / 2; ++i)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2*x, y);
|
||||
FfxFloat16x4 centre = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 0]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 0]));
|
||||
FfxFloat16x4 top = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y - 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y - 1]));
|
||||
FfxFloat16x4 bottom = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 1]));
|
||||
|
||||
FfxFloat16x2 tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x - 1][c.y + 0]);
|
||||
FfxFloat16x4 left = FfxFloat16x4(tmp.y, centre.xyz);
|
||||
tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[c.x + 2][c.y + 0]);
|
||||
FfxFloat16x4 right = FfxFloat16x4(centre.yzw, tmp.x);
|
||||
|
||||
FfxFloat16x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF16_4(packedEdges[x][y], centre, left, right, top, bottom);
|
||||
s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y] = ffxPackF16(tmp_4.xy);
|
||||
s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y] = ffxPackF16(tmp_4.zw);
|
||||
}
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
if (2 * i + 1 < blurPasses)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2 * x, y);
|
||||
FfxFloat16x4 centre = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 0]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 0]));
|
||||
FfxFloat16x4 top = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y - 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y - 1]));
|
||||
FfxFloat16x4 bottom = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 1]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 1]));
|
||||
|
||||
FfxFloat16x2 tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x - 1][c.y + 0]);
|
||||
FfxFloat16x4 left = FfxFloat16x4(tmp.y, centre.xyz);
|
||||
tmp = ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[c.x + 2][c.y + 0]);
|
||||
FfxFloat16x4 right = FfxFloat16x4(centre.yzw, tmp.x);
|
||||
|
||||
FfxFloat16x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF16_4(packedEdges[x][y], centre, left, right, top, bottom);
|
||||
s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y] = ffxPackF16(tmp_4.xy);
|
||||
s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y] = ffxPackF16(tmp_4.zw);
|
||||
}
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
}
|
||||
}
|
||||
|
||||
FFX_UNROLL
|
||||
for (FfxUInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FfxUInt32 outputY = FFX_CACAO_TILE_HEIGHT * tid.y + y;
|
||||
if (blurPasses <= outputY && outputY < FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT - blurPasses)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxUInt32 outputX = FFX_CACAO_TILE_WIDTH * tid.x + 4 * x;
|
||||
|
||||
FfxFloat16x4 ssaoVal;
|
||||
if (blurPasses % 2 == 0)
|
||||
{
|
||||
ssaoVal = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF16(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x + 1][bufferCoord.y + y]));
|
||||
}
|
||||
else
|
||||
{
|
||||
ssaoVal = FfxFloat16x4(ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF16(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x + 1][bufferCoord.y + y]));
|
||||
}
|
||||
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x, y), FfxFloat32x2(ssaoVal.x, packedEdges[x][y].x), layerId);
|
||||
}
|
||||
outputX += 1;
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 1, y), FfxFloat32x2(ssaoVal.y, packedEdges[x][y].y), layerId);
|
||||
}
|
||||
outputX += 1;
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 2, y), FfxFloat32x2(ssaoVal.z, packedEdges[x][y].z), layerId);
|
||||
}
|
||||
outputX += 1;
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 3, y), FfxFloat32x2(ssaoVal.w, packedEdges[x][y].w), layerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct FFX_CACAO_Edges_4
|
||||
{
|
||||
FfxFloat32x4 left;
|
||||
FfxFloat32x4 right;
|
||||
FfxFloat32x4 top;
|
||||
FfxFloat32x4 bottom;
|
||||
};
|
||||
|
||||
FFX_CACAO_Edges_4 FFX_CACAO_UnpackEdgesFloat32_4(FfxFloat32x4 _packedVal)
|
||||
{
|
||||
FfxUInt32x4 packedVal = FfxUInt32x4(_packedVal * 255.5);
|
||||
FFX_CACAO_Edges_4 result;
|
||||
result.left = ffxSaturate(((packedVal >> 6) & 0x03) / 3.0 + InvSharpness());
|
||||
result.right = ffxSaturate(((packedVal >> 4) & 0x03) / 3.0 + InvSharpness());
|
||||
result.top = ffxSaturate(((packedVal >> 2) & 0x03) / 3.0 + InvSharpness());
|
||||
result.bottom = ffxSaturate(((packedVal >> 0) & 0x03) / 3.0 + InvSharpness());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FfxFloat32x4 FFX_CACAO_CalcBlurredSampleF32_4(FfxFloat32x4 packedEdges, FfxFloat32x4 centre, FfxFloat32x4 left, FfxFloat32x4 right, FfxFloat32x4 top, FfxFloat32x4 bottom)
|
||||
{
|
||||
FfxFloat32x4 sum = centre * FfxFloat32(0.5f);
|
||||
FfxFloat32x4 weight = FfxFloat32x4(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
FFX_CACAO_Edges_4 edges = FFX_CACAO_UnpackEdgesFloat32_4(packedEdges);
|
||||
|
||||
sum += left * edges.left;
|
||||
weight += edges.left;
|
||||
sum += right * edges.right;
|
||||
weight += edges.right;
|
||||
sum += top * edges.top;
|
||||
weight += edges.top;
|
||||
sum += bottom * edges.bottom;
|
||||
weight += edges.bottom;
|
||||
|
||||
return sum / weight;
|
||||
}
|
||||
|
||||
void FFX_CACAO_LDSEdgeSensitiveBlur(const FfxUInt32 blurPasses, const FfxUInt32x2 tid, const FfxUInt32x2 gid, const FfxUInt32 layerId)
|
||||
{
|
||||
FfxInt32x2 imageCoord = FfxInt32x2(gid) * (FfxInt32x2(FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH, FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT) - FfxInt32(2*blurPasses)) + FfxInt32x2(FFX_CACAO_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) - FfxInt32(blurPasses);
|
||||
FfxInt32x2 bufferCoord = FfxInt32x2(FFX_CACAO_HALF_TILE_WIDTH, FFX_CACAO_TILE_HEIGHT) * FfxInt32x2(tid) + 1;
|
||||
|
||||
FfxFloat32x4 packedEdges[FFX_CACAO_QUARTER_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT];
|
||||
{
|
||||
FfxFloat32x2 inputVal[FFX_CACAO_TILE_WIDTH][FFX_CACAO_TILE_HEIGHT];
|
||||
FfxInt32 y;
|
||||
FFX_UNROLL
|
||||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxFloat32x2 sampleUV = (FfxFloat32x2(imageCoord + FfxInt32x2(x, y)) + 0.5f) * SSAOBufferInverseDimensions();
|
||||
inputVal[x][y] = FFX_CACAO_EdgeSensitiveBlur_SampleInput(sampleUV, layerId);
|
||||
}
|
||||
}
|
||||
FFX_UNROLL
|
||||
for (y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxFloat32x2 ssaoVals = FfxFloat32x2(inputVal[4 * x + 0][y].x, inputVal[4 * x + 1][y].x);
|
||||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 0][bufferCoord.y + y] = ffxPackF32(ssaoVals);
|
||||
ssaoVals = FfxFloat32x2(inputVal[4 * x + 2][y].x, inputVal[4 * x + 3][y].x);
|
||||
s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + 2*x + 1][bufferCoord.y + y] = ffxPackF32(ssaoVals);
|
||||
packedEdges[x][y] = FfxFloat32x4(inputVal[4 * x + 0][y].y, inputVal[4 * x + 1][y].y, inputVal[4 * x + 2][y].y, inputVal[4 * x + 3][y].y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
FFX_UNROLL
|
||||
for (FfxUInt32 i = 0; i < (blurPasses + 1) / 2; ++i)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2*x, y);
|
||||
FfxFloat32x4 centre = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 0]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 0]));
|
||||
FfxFloat32x4 top = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y - 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y - 1]));
|
||||
FfxFloat32x4 bottom = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y + 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y + 1]));
|
||||
|
||||
FfxFloat32x2 tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x - 1][c.y + 0]);
|
||||
FfxFloat32x4 left = FfxFloat32x4(tmp.y, centre.xyz);
|
||||
tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[c.x + 2][c.y + 0]);
|
||||
FfxFloat32x4 right = FfxFloat32x4(centre.yzw, tmp.x);
|
||||
|
||||
FfxFloat32x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF32_4(packedEdges[x][y], centre, left, right, top, bottom);
|
||||
s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y] = ffxPackF32(tmp_4.xy);
|
||||
s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y] = ffxPackF32(tmp_4.zw);
|
||||
}
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
if (2 * i + 1 < blurPasses)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxInt32x2 c = bufferCoord + FfxInt32x2(2 * x, y);
|
||||
FfxFloat32x4 centre = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 0]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 0]));
|
||||
FfxFloat32x4 top = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y - 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y - 1]));
|
||||
FfxFloat32x4 bottom = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 0][c.y + 1]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 1][c.y + 1]));
|
||||
|
||||
FfxFloat32x2 tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x - 1][c.y + 0]);
|
||||
FfxFloat32x4 left = FfxFloat32x4(tmp.y, centre.xyz);
|
||||
tmp = ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[c.x + 2][c.y + 0]);
|
||||
FfxFloat32x4 right = FfxFloat32x4(centre.yzw, tmp.x);
|
||||
|
||||
FfxFloat32x4 tmp_4 = FFX_CACAO_CalcBlurredSampleF32_4(packedEdges[x][y], centre, left, right, top, bottom);
|
||||
s_FFX_CACAO_BlurF16Front_4[c.x + 0][c.y] = ffxPackF32(tmp_4.xy);
|
||||
s_FFX_CACAO_BlurF16Front_4[c.x + 1][c.y] = ffxPackF32(tmp_4.zw);
|
||||
}
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
}
|
||||
}
|
||||
|
||||
FFX_UNROLL
|
||||
for (FfxUInt32 y = 0; y < FFX_CACAO_TILE_HEIGHT; ++y)
|
||||
{
|
||||
FfxUInt32 outputY = FFX_CACAO_TILE_HEIGHT * tid.y + y;
|
||||
if (blurPasses <= outputY && outputY < FFX_CACAO_TILE_HEIGHT * FFX_CACAO_BLUR_HEIGHT - blurPasses)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 x = 0; x < FFX_CACAO_QUARTER_TILE_WIDTH; ++x)
|
||||
{
|
||||
FfxUInt32 outputX = FFX_CACAO_TILE_WIDTH * tid.x + 4 * x;
|
||||
|
||||
FfxFloat32x4 ssaoVal;
|
||||
if (blurPasses % 2 == 0)
|
||||
{
|
||||
ssaoVal = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF32(s_FFX_CACAO_BlurF16Front_4[bufferCoord.x + x + 1][bufferCoord.y + y]));
|
||||
}
|
||||
else
|
||||
{
|
||||
ssaoVal = FfxFloat32x4(ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x][bufferCoord.y + y]), ffxUnpackF32(s_FFX_CACAO_BlurF16Back_4[bufferCoord.x + x + 1][bufferCoord.y + y]));
|
||||
}
|
||||
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x, y), FfxFloat32x2(ssaoVal.x, packedEdges[x][y].x), layerId);
|
||||
}
|
||||
outputX += 1;
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 1, y), FfxFloat32x2(ssaoVal.y, packedEdges[x][y].y), layerId);
|
||||
}
|
||||
outputX += 1;
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 2, y), FfxFloat32x2(ssaoVal.z, packedEdges[x][y].z), layerId);
|
||||
}
|
||||
outputX += 1;
|
||||
if (blurPasses <= outputX && outputX < FFX_CACAO_TILE_WIDTH * FFX_CACAO_BLUR_WIDTH - blurPasses)
|
||||
{
|
||||
FFX_CACAO_EdgeSensitiveBlur_StoreOutput(imageCoord + FfxInt32x2(4 * x + 3, y), FfxFloat32x2(ssaoVal.w, packedEdges[x][y].w), layerId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif //FFX_HALF
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur1(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(1, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur2(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(2, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur3(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(3, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur4(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(4, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur5(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(5, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur6(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(6, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur7(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(7, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_EdgeSensitiveBlur8(FfxUInt32x2 tid, FfxUInt32x3 gid)
|
||||
{
|
||||
FfxUInt32 layerId = gid.z;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId;
|
||||
FFX_CACAO_LDSEdgeSensitiveBlur(8, tid, gid.xy, layerId);
|
||||
}
|
||||
|
||||
#undef FFX_CACAO_TILE_WIDTH
|
||||
#undef FFX_CACAO_TILE_HEIGHT
|
||||
#undef FFX_CACAO_HALF_TILE_WIDTH
|
||||
#undef FFX_CACAO_QUARTER_TILE_WIDTH
|
||||
#undef FFX_CACAO_ARRAY_WIDTH
|
||||
#undef FFX_CACAO_ARRAY_HEIGHT
|
||||
#undef FFX_CACAO_ITERS
|
||||
111
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_importance_map.h
vendored
Normal file
111
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_importance_map.h
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_cacao_defines.h"
|
||||
#include "ffx_cacao_utils.h"
|
||||
|
||||
void FFX_CACAO_GenerateImportanceMap(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxUInt32x2 basePos = tid * 2;
|
||||
|
||||
FfxFloat32x2 baseUV = (FfxFloat32x2(basePos) + 1.0f) * SSAOBufferInverseDimensions();
|
||||
|
||||
FfxFloat32 avg = 0.0;
|
||||
FfxFloat32 minV = 1.0;
|
||||
FfxFloat32 maxV = 0.0;
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 i = 0; i < 4; i++)
|
||||
{
|
||||
FfxFloat32x4 vals = FFX_CACAO_Importance_GatherSSAO(baseUV, i);
|
||||
|
||||
// apply the same modifications that would have been applied in the main shader
|
||||
vals = EffectShadowStrength() * vals;
|
||||
|
||||
vals = 1 - vals;
|
||||
|
||||
vals = pow(ffxSaturate(vals), FfxFloat32x4(EffectShadowPow(), EffectShadowPow(), EffectShadowPow(), EffectShadowPow()));
|
||||
|
||||
avg += dot(FfxFloat32x4(vals.x, vals.y, vals.z, vals.w), FfxFloat32x4(1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0));
|
||||
|
||||
maxV = max(maxV, max(max(vals.x, vals.y), max(vals.z, vals.w)));
|
||||
minV = min(minV, min(min(vals.x, vals.y), min(vals.z, vals.w)));
|
||||
}
|
||||
|
||||
FfxFloat32 minMaxDiff = maxV - minV;
|
||||
|
||||
FFX_CACAO_Importance_StoreImportance(tid, pow(ffxSaturate(minMaxDiff * 2.0), 0.8f));
|
||||
}
|
||||
|
||||
FFX_STATIC const FfxFloat32 c_FFX_CACAO_SmoothenImportance = 1.0f;
|
||||
|
||||
void FFX_CACAO_PostprocessImportanceMapA(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(tid)+0.5f) * ImportanceMapInverseDimensions();
|
||||
|
||||
FfxFloat32 centre = FFX_CACAO_Importance_SampleImportanceA(uv);
|
||||
|
||||
FfxFloat32x2 halfPixel = 0.5f * ImportanceMapInverseDimensions();
|
||||
|
||||
FfxFloat32x4 vals;
|
||||
vals.x = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(-halfPixel.x * 3, -halfPixel.y));
|
||||
vals.y = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(+halfPixel.x, -halfPixel.y * 3));
|
||||
vals.z = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(+halfPixel.x * 3, +halfPixel.y));
|
||||
vals.w = FFX_CACAO_Importance_SampleImportanceA(uv + FfxFloat32x2(-halfPixel.x, +halfPixel.y * 3));
|
||||
|
||||
FfxFloat32 avgVal = dot(vals, FfxFloat32x4(0.25, 0.25, 0.25, 0.25));
|
||||
vals.xy = max(vals.xy, vals.zw);
|
||||
FfxFloat32 maxVal = max(centre, max(vals.x, vals.y));
|
||||
|
||||
FFX_CACAO_Importance_StoreImportanceA(tid, ffxLerp(maxVal, avgVal, c_FFX_CACAO_SmoothenImportance));
|
||||
}
|
||||
|
||||
void FFX_CACAO_PostprocessImportanceMapB(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(tid)+0.5f) * ImportanceMapInverseDimensions();
|
||||
|
||||
FfxFloat32 centre = FFX_CACAO_Importance_SampleImportanceB(uv);
|
||||
|
||||
FfxFloat32x2 halfPixel = 0.5f * ImportanceMapInverseDimensions();
|
||||
|
||||
FfxFloat32x4 vals;
|
||||
vals.x = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(-halfPixel.x, -halfPixel.y * 3));
|
||||
vals.y = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(+halfPixel.x * 3, -halfPixel.y));
|
||||
vals.z = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(+halfPixel.x, +halfPixel.y * 3));
|
||||
vals.w = FFX_CACAO_Importance_SampleImportanceB(uv + FfxFloat32x2(-halfPixel.x * 3, +halfPixel.y));
|
||||
|
||||
FfxFloat32 avgVal = dot(vals, FfxFloat32x4(0.25, 0.25, 0.25, 0.25));
|
||||
vals.xy = max(vals.xy, vals.zw);
|
||||
FfxFloat32 maxVal = max(centre, max(vals.x, vals.y));
|
||||
|
||||
FfxFloat32 retVal = ffxLerp(maxVal, avgVal, c_FFX_CACAO_SmoothenImportance);
|
||||
FFX_CACAO_Importance_StoreImportanceB(tid, retVal);
|
||||
|
||||
// sum the average; to avoid overflowing we assume max AO resolution is not bigger than 16384x16384; so quarter res (used here) will be 4096x4096, which leaves us with 8 bits per pixel
|
||||
FfxUInt32 sum = FfxUInt32(ffxSaturate(retVal) * 255.0 + 0.5);
|
||||
|
||||
// save every 9th to avoid InterlockedAdd congestion - since we're blurring, this is good enough; compensated by multiplying LoadCounterAvgDiv by 9
|
||||
if (((tid.x % 3) + (tid.y % 3)) == 0)
|
||||
{
|
||||
FFX_CACAO_Importance_LoadCounterInterlockedAdd(sum);
|
||||
}
|
||||
}
|
||||
310
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_prepare.h
vendored
Normal file
310
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_prepare.h
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_cacao_defines.h"
|
||||
#include "ffx_cacao_utils.h"
|
||||
|
||||
FFX_GROUPSHARED FfxFloat32 s_FFX_CACAO_PrepareDepthsAndMipsBuffer[4][8][8];
|
||||
|
||||
FfxFloat32 FFX_CACAO_MipSmartAverage(FfxFloat32x4 depths)
|
||||
{
|
||||
FfxFloat32 closest = min(min(depths.x, depths.y), min(depths.z, depths.w));
|
||||
FfxFloat32 falloffCalcMulSq = -1.0f / EffectRadius() * EffectRadius();
|
||||
FfxFloat32x4 dists = depths - closest.xxxx;
|
||||
FfxFloat32x4 weights = ffxSaturate(dists * dists * falloffCalcMulSq + 1.0);
|
||||
return dot(weights, depths) / dot(weights, FfxFloat32x4(1.0, 1.0, 1.0, 1.0));
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareDepthsAndMips(FfxFloat32x4 samples, FfxUInt32x2 outputCoord, FfxUInt32x2 gtid)
|
||||
{
|
||||
samples = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples);
|
||||
|
||||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[0][gtid.x][gtid.y] = samples.w;
|
||||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[1][gtid.x][gtid.y] = samples.z;
|
||||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[2][gtid.x][gtid.y] = samples.x;
|
||||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[3][gtid.x][gtid.y] = samples.y;
|
||||
|
||||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 0, samples.w);
|
||||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 1, samples.z);
|
||||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 2, samples.x);
|
||||
FFX_CACAO_Prepare_StoreDepthMip0(outputCoord, 3, samples.y);
|
||||
|
||||
FfxUInt32 depthArrayIndex = 2 * (gtid.y % 2) + (gtid.x % 2);
|
||||
FfxUInt32x2 depthArrayOffset = FfxInt32x2(gtid.x % 2, gtid.y % 2);
|
||||
FfxInt32x2 bufferCoord = FfxInt32x2(gtid) - FfxInt32x2(depthArrayOffset);
|
||||
|
||||
outputCoord /= 2;
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// if (stillAlive) <-- all threads alive here
|
||||
{
|
||||
FfxFloat32 sample_00 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 0];
|
||||
FfxFloat32 sample_01 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 1];
|
||||
FfxFloat32 sample_10 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 1][bufferCoord.y + 0];
|
||||
FfxFloat32 sample_11 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 1][bufferCoord.y + 1];
|
||||
|
||||
FfxFloat32 avg = FFX_CACAO_MipSmartAverage(FfxFloat32x4(sample_00, sample_01, sample_10, sample_11));
|
||||
FFX_CACAO_Prepare_StoreDepthMip1(outputCoord, depthArrayIndex, avg);
|
||||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x][bufferCoord.y] = avg;
|
||||
}
|
||||
|
||||
bool stillAlive = gtid.x % 4 == depthArrayOffset.x && gtid.y % 4 == depthArrayOffset.y;
|
||||
|
||||
outputCoord /= 2;
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
if (stillAlive)
|
||||
{
|
||||
FfxFloat32 sample_00 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 0];
|
||||
FfxFloat32 sample_01 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 2];
|
||||
FfxFloat32 sample_10 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 2][bufferCoord.y + 0];
|
||||
FfxFloat32 sample_11 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 2][bufferCoord.y + 2];
|
||||
|
||||
FfxFloat32 avg = FFX_CACAO_MipSmartAverage(FfxFloat32x4(sample_00, sample_01, sample_10, sample_11));
|
||||
FFX_CACAO_Prepare_StoreDepthMip2(outputCoord, depthArrayIndex, avg);
|
||||
s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x][bufferCoord.y] = avg;
|
||||
}
|
||||
|
||||
stillAlive = gtid.x % 8 == depthArrayOffset.x && gtid.y % 8 == depthArrayOffset.y;
|
||||
|
||||
outputCoord /= 2;
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
if (stillAlive)
|
||||
{
|
||||
FfxFloat32 sample_00 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 0];
|
||||
FfxFloat32 sample_01 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 0][bufferCoord.y + 4];
|
||||
FfxFloat32 sample_10 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 4][bufferCoord.y + 0];
|
||||
FfxFloat32 sample_11 = s_FFX_CACAO_PrepareDepthsAndMipsBuffer[depthArrayIndex][bufferCoord.x + 4][bufferCoord.y + 4];
|
||||
|
||||
FfxFloat32 avg = FFX_CACAO_MipSmartAverage(FfxFloat32x4(sample_00, sample_01, sample_10, sample_11));
|
||||
FFX_CACAO_Prepare_StoreDepthMip3(outputCoord, depthArrayIndex, avg);
|
||||
}
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareDownsampledDepthsAndMips(FfxUInt32x2 tid, FfxUInt32x2 gtid)
|
||||
{
|
||||
FfxInt32x2 depthBufferCoord = 4 * FfxInt32x2(tid.xy);
|
||||
FfxInt32x2 outputCoord = FfxInt32x2(tid);
|
||||
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord)+0.5f) * DepthBufferInverseDimensions();
|
||||
FfxFloat32x4 samples = FFX_CACAO_Prepare_SampleDepthOffsets(uv);
|
||||
|
||||
FFX_CACAO_PrepareDepthsAndMips(samples, outputCoord, gtid);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareNativeDepthsAndMips(FfxUInt32x2 tid, FfxUInt32x2 gtid)
|
||||
{
|
||||
FfxInt32x2 depthBufferCoord = 2 * FfxInt32x2(tid.xy);
|
||||
FfxInt32x2 outputCoord = FfxInt32x2(tid);
|
||||
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord)+ 1.0f) * DepthBufferInverseDimensions();
|
||||
FfxFloat32x4 samples = FFX_CACAO_Prepare_GatherDepth(uv);
|
||||
|
||||
FFX_CACAO_PrepareDepthsAndMips(samples, outputCoord, gtid);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareDepths(FfxFloat32x4 samples, FfxUInt32x2 tid)
|
||||
{
|
||||
samples = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 0, samples.w);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 1, samples.z);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 2, samples.x);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 3, samples.y);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareDownsampledDepths(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxInt32x2 depthBufferCoord = 4 * FfxInt32x2(tid.xy);
|
||||
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord)+0.5f) * DepthBufferInverseDimensions();
|
||||
FfxFloat32x4 samples = FFX_CACAO_Prepare_SampleDepthOffsets(uv);
|
||||
|
||||
FFX_CACAO_PrepareDepths(samples, tid);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareNativeDepths(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxInt32x2 depthBufferCoord = 2 * FfxInt32x2(tid.xy);
|
||||
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(depthBufferCoord) + 1.0f) * DepthBufferInverseDimensions();
|
||||
FfxFloat32x4 samples = FFX_CACAO_Prepare_GatherDepth(uv);
|
||||
|
||||
FFX_CACAO_PrepareDepths(samples, tid);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareDownsampledDepthsHalf(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxFloat32 sample_00 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(4 * tid.x + 0, 4 * tid.y + 0));
|
||||
FfxFloat32 sample_11 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(4 * tid.x + 2, 4 * tid.y + 2));
|
||||
sample_00 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_00);
|
||||
sample_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_11);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 0, sample_00);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 3, sample_11);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareNativeDepthsHalf(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxFloat32 sample_00 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(2 * tid.x + 0, 2 * tid.y + 0));
|
||||
FfxFloat32 sample_11 = FFX_CACAO_Prepare_LoadDepth(FfxInt32x2(2 * tid.x + 1, 2 * tid.y + 1));
|
||||
sample_00 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_00);
|
||||
sample_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(sample_11);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 0, sample_00);
|
||||
FFX_CACAO_Prepare_StoreDepth(tid, 3, sample_11);
|
||||
}
|
||||
|
||||
struct FFX_CACAO_PrepareNormalsInputDepths
|
||||
{
|
||||
FfxFloat32 depth_10;
|
||||
FfxFloat32 depth_20;
|
||||
|
||||
FfxFloat32 depth_01;
|
||||
FfxFloat32 depth_11;
|
||||
FfxFloat32 depth_21;
|
||||
FfxFloat32 depth_31;
|
||||
|
||||
FfxFloat32 depth_02;
|
||||
FfxFloat32 depth_12;
|
||||
FfxFloat32 depth_22;
|
||||
FfxFloat32 depth_32;
|
||||
|
||||
FfxFloat32 depth_13;
|
||||
FfxFloat32 depth_23;
|
||||
};
|
||||
|
||||
void FFX_CACAO_PrepareNormals(FFX_CACAO_PrepareNormalsInputDepths depths, FfxFloat32x2 uv, FfxFloat32x2 pixelSize, FfxUInt32x2 normalCoord)
|
||||
{
|
||||
FfxFloat32x3 p_10 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, -1.0f) * pixelSize, depths.depth_10);
|
||||
FfxFloat32x3 p_20 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, -1.0f) * pixelSize, depths.depth_20);
|
||||
|
||||
FfxFloat32x3 p_01 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(-1.0f, +0.0f) * pixelSize, depths.depth_01);
|
||||
FfxFloat32x3 p_11 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, +0.0f) * pixelSize, depths.depth_11);
|
||||
FfxFloat32x3 p_21 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, +0.0f) * pixelSize, depths.depth_21);
|
||||
FfxFloat32x3 p_31 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+2.0f, +0.0f) * pixelSize, depths.depth_31);
|
||||
|
||||
FfxFloat32x3 p_02 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(-1.0f, +1.0f) * pixelSize, depths.depth_02);
|
||||
FfxFloat32x3 p_12 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, +1.0f) * pixelSize, depths.depth_12);
|
||||
FfxFloat32x3 p_22 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, +1.0f) * pixelSize, depths.depth_22);
|
||||
FfxFloat32x3 p_32 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+2.0f, +1.0f) * pixelSize, depths.depth_32);
|
||||
|
||||
FfxFloat32x3 p_13 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+0.0f, +2.0f) * pixelSize, depths.depth_13);
|
||||
FfxFloat32x3 p_23 = FFX_CACAO_NDCToViewSpace(uv + FfxFloat32x2(+1.0f, +2.0f) * pixelSize, depths.depth_23);
|
||||
|
||||
FfxFloat32x4 edges_11 = FFX_CACAO_CalculateEdges(p_11.z, p_01.z, p_21.z, p_10.z, p_12.z);
|
||||
FfxFloat32x4 edges_21 = FFX_CACAO_CalculateEdges(p_21.z, p_11.z, p_31.z, p_20.z, p_22.z);
|
||||
FfxFloat32x4 edges_12 = FFX_CACAO_CalculateEdges(p_12.z, p_02.z, p_22.z, p_11.z, p_13.z);
|
||||
FfxFloat32x4 edges_22 = FFX_CACAO_CalculateEdges(p_22.z, p_12.z, p_32.z, p_21.z, p_23.z);
|
||||
|
||||
FfxFloat32x3 norm_11 = FFX_CACAO_CalculateNormal(edges_11, p_11, p_01, p_21, p_10, p_12);
|
||||
FfxFloat32x3 norm_21 = FFX_CACAO_CalculateNormal(edges_21, p_21, p_11, p_31, p_20, p_22);
|
||||
FfxFloat32x3 norm_12 = FFX_CACAO_CalculateNormal(edges_12, p_12, p_02, p_22, p_11, p_13);
|
||||
FfxFloat32x3 norm_22 = FFX_CACAO_CalculateNormal(edges_22, p_22, p_12, p_32, p_21, p_23);
|
||||
|
||||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 0, norm_11);
|
||||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 1, norm_21);
|
||||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 2, norm_12);
|
||||
FFX_CACAO_Prepare_StoreNormal(normalCoord, 3, norm_22);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareDownsampledNormals(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxInt32x2 depthCoord = 4 * FfxInt32x2(tid) + DepthBufferOffset();
|
||||
|
||||
FFX_CACAO_PrepareNormalsInputDepths depths;
|
||||
|
||||
depths.depth_10 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, -2)));
|
||||
depths.depth_20 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, -2)));
|
||||
|
||||
depths.depth_01 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(-2, +0)));
|
||||
depths.depth_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, +0)));
|
||||
depths.depth_21 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, +0)));
|
||||
depths.depth_31 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+4, +0)));
|
||||
|
||||
depths.depth_02 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(-2, +2)));
|
||||
depths.depth_12 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, +2)));
|
||||
depths.depth_22 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, +2)));
|
||||
depths.depth_32 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+4, +2)));
|
||||
|
||||
depths.depth_13 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+0, +4)));
|
||||
depths.depth_23 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(FFX_CACAO_Prepare_LoadDepthOffset(depthCoord, FfxInt32x2(+2, +4)));
|
||||
|
||||
FfxFloat32x2 pixelSize = 2.0f * OutputBufferInverseDimensions();
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(4 * tid) + 0.5f) * OutputBufferInverseDimensions();
|
||||
|
||||
FFX_CACAO_PrepareNormals(depths, uv, pixelSize, tid);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareNativeNormals(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxInt32x2 depthCoord = 2 * FfxInt32x2(tid) + DepthBufferOffset();
|
||||
FfxFloat32x2 depthBufferUV = FfxFloat32x2(depthCoord) * DepthBufferInverseDimensions();
|
||||
FfxFloat32x4 samples_00 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(0, 0)); //CACAO_TODO fix gather
|
||||
FfxFloat32x4 samples_10 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(2, 0));
|
||||
FfxFloat32x4 samples_01 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(0, 2));
|
||||
FfxFloat32x4 samples_11 = FFX_CACAO_Prepare_GatherDepthOffset(depthBufferUV, FfxInt32x2(2, 2));
|
||||
|
||||
FFX_CACAO_PrepareNormalsInputDepths depths;
|
||||
|
||||
depths.depth_10 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_00.z);
|
||||
depths.depth_20 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_10.w);
|
||||
|
||||
depths.depth_01 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_00.x);
|
||||
depths.depth_11 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_00.y);
|
||||
depths.depth_21 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_10.x);
|
||||
depths.depth_31 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_10.y);
|
||||
|
||||
depths.depth_02 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_01.w);
|
||||
depths.depth_12 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_01.z);
|
||||
depths.depth_22 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_11.w);
|
||||
depths.depth_32 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_11.z);
|
||||
|
||||
depths.depth_13 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_01.y);
|
||||
depths.depth_23 = FFX_CACAO_ScreenSpaceToViewSpaceDepth(samples_11.x);
|
||||
|
||||
// use unused samples to make sure compiler doesn't overlap memory and put a sync
|
||||
// between loads
|
||||
FfxFloat32 epsilon = (samples_00.w + samples_10.z + samples_01.x + samples_11.y) * 1e-20f;
|
||||
|
||||
FfxFloat32x2 pixelSize = OutputBufferInverseDimensions();
|
||||
FfxFloat32x2 uv = (FfxFloat32x2(2 * tid) + 0.5f + epsilon) * OutputBufferInverseDimensions();
|
||||
|
||||
FFX_CACAO_PrepareNormals(depths, uv, pixelSize, tid);
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareDownsampledNormalsFromInputNormals(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxUInt32x2 baseCoord = 4 * tid;
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 0, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 0)));
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 1, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(2, 0)));
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 2, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 2)));
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 3, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(2, 2)));
|
||||
}
|
||||
|
||||
void FFX_CACAO_PrepareNativeNormalsFromInputNormals(FfxUInt32x2 tid)
|
||||
{
|
||||
FfxUInt32x2 baseCoord = 2 * tid;
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 0, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 0)));
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 1, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(1, 0)));
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 2, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(0, 1)));
|
||||
FFX_CACAO_Prepare_StoreNormal(tid, 3, FFX_CACAO_Prepare_LoadNormal(baseCoord + FfxUInt32x2(1, 1)));
|
||||
}
|
||||
50
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_resources.h
vendored
Normal file
50
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_resources.h
vendored
Normal file
@@ -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_CACAO_RESOURCES_H
|
||||
#define FFX_CACAO_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
#define FFX_FSR2_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DEPTH_IN 1
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_NORMAL_IN 2
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_DEPTHS 3
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DEINTERLEAVED_NORMALS 4
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PING 5
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_SSAO_BUFFER_PONG 6
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP 7
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_IMPORTANCE_MAP_PONG 8
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_SSAO_BUFFER 9
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_LOAD_COUNTER_BUFFER 10
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_OUTPUT 11
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_0 12
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_1 13
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_2 14
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_DOWNSAMPLED_DEPTH_MIPMAP_3 15
|
||||
#define FFX_CACAO_RESOURCE_IDENTIFIER_COUNT 16
|
||||
|
||||
#define FFX_CACAO_CONSTANTBUFFER_IDENTIFIER_CACAO 0
|
||||
#define FFX_CACAO_CONSTANTBUFFER_IDENTIFIER_COUNT 1
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif //!defined( FFX_FSR2_RESOURCES_H )
|
||||
616
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_ssao_generation.h
vendored
Normal file
616
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_ssao_generation.h
vendored
Normal file
@@ -0,0 +1,616 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_cacao_defines.h"
|
||||
#include "ffx_cacao_utils.h"
|
||||
|
||||
FFX_STATIC const FfxFloat32x4 g_FFX_CACAO_samplePatternMain[] =
|
||||
{
|
||||
{ 0.78488064, 0.56661671, 1.500000, -0.126083}, { 0.26022232, -0.29575172, 1.500000, -1.064030}, { 0.10459357, 0.08372527, 1.110000, -2.730563}, {-0.68286800, 0.04963045, 1.090000, -0.498827},
|
||||
{-0.13570161, -0.64190155, 1.250000, -0.532765}, {-0.26193795, -0.08205118, 0.670000, -1.783245}, {-0.61177456, 0.66664219, 0.710000, -0.044234}, { 0.43675563, 0.25119025, 0.610000, -1.167283},
|
||||
{ 0.07884444, 0.86618668, 0.640000, -0.459002}, {-0.12790935, -0.29869005, 0.600000, -1.729424}, {-0.04031125, 0.02413622, 0.600000, -4.792042}, { 0.16201244, -0.52851415, 0.790000, -1.067055},
|
||||
{-0.70991218, 0.47301072, 0.640000, -0.335236}, { 0.03277707, -0.22349690, 0.600000, -1.982384}, { 0.68921727, 0.36800742, 0.630000, -0.266718}, { 0.29251814, 0.37775412, 0.610000, -1.422520},
|
||||
{-0.12224089, 0.96582592, 0.600000, -0.426142}, { 0.11071457, -0.16131058, 0.600000, -2.165947}, { 0.46562141, -0.59747696, 0.600000, -0.189760}, {-0.51548797, 0.11804193, 0.600000, -1.246800},
|
||||
{ 0.89141309, -0.42090443, 0.600000, 0.028192}, {-0.32402530, -0.01591529, 0.600000, -1.543018}, { 0.60771245, 0.41635221, 0.600000, -0.605411}, { 0.02379565, -0.08239821, 0.600000, -3.809046},
|
||||
{ 0.48951152, -0.23657045, 0.600000, -1.189011}, {-0.17611565, -0.81696892, 0.600000, -0.513724}, {-0.33930185, -0.20732205, 0.600000, -1.698047}, {-0.91974425, 0.05403209, 0.600000, 0.062246},
|
||||
{-0.15064627, -0.14949332, 0.600000, -1.896062}, { 0.53180975, -0.35210401, 0.600000, -0.758838}, { 0.41487166, 0.81442589, 0.600000, -0.505648}, {-0.24106961, -0.32721516, 0.600000, -1.665244}
|
||||
};
|
||||
|
||||
#define FFX_CACAO_MAX_TAPS (32)
|
||||
#define FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT (5)
|
||||
#define FFX_CACAO_ADAPTIVE_TAP_FLEXIBLE_COUNT (FFX_CACAO_MAX_TAPS - FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT)
|
||||
|
||||
// these values can be changed (up to FFX_CACAO_MAX_TAPS) with no changes required elsewhere; values for 4th and 5th preset are ignored but array needed to avoid compilation errors
|
||||
// the actual number of texture samples is two times this value (each "tap" has two symmetrical depth texture samples)
|
||||
FFX_STATIC const FfxUInt32 g_FFX_CACAO_numTaps[5] = {3, 5, 12, 0, 0};
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Optional parts that can be enabled for a required quality preset level and above (0 == Low, 1 == Medium, 2 == High, 3 == Highest/Adaptive, 4 == reference/unused )
|
||||
// Each has its own cost. To disable just set to 5 or above.
|
||||
//
|
||||
// (experimental) tilts the disk (although only half of the samples!) towards surface normal; this helps with effect uniformity between objects but reduces effect distance and has other side-effects
|
||||
#define FFX_CACAO_TILT_SAMPLES_ENABLE_AT_QUALITY_PRESET (99) // to disable simply set to 99 or similar
|
||||
#define FFX_CACAO_TILT_SAMPLES_AMOUNT (0.4)
|
||||
//
|
||||
#define FFX_CACAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET (1) // to disable simply set to 99 or similar
|
||||
#define FFX_CACAO_HALOING_REDUCTION_AMOUNT (0.6) // values from 0.0 - 1.0, 1.0 means max weighting (will cause artifacts, 0.8 is more reasonable)
|
||||
//
|
||||
#define FFX_CACAO_NORMAL_BASED_EDGES_ENABLE_AT_QUALITY_PRESET (2) //2 // to disable simply set to 99 or similar
|
||||
#define FFX_CACAO_NORMAL_BASED_EDGES_DOT_THRESHOLD (0.5) // use 0-0.1 for super-sharp normal-based edges
|
||||
//
|
||||
#define FFX_CACAO_DETAIL_AO_ENABLE_AT_QUALITY_PRESET (1) //1 // whether to use DetailAOStrength; to disable simply set to 99 or similar
|
||||
//
|
||||
#define FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET (2) // !!warning!! the MIP generation on the C++ side will be enabled on quality preset 2 regardless of this value, so if changing here, change the C++ side too
|
||||
#define FFX_CACAO_DEPTH_MIPS_GLOBAL_OFFSET (-4.3) // best noise/quality/performance tradeoff, found empirically
|
||||
//
|
||||
// !!warning!! the edge handling is hard-coded to 'disabled' on quality level 0, and enabled above, on the C++ side; while toggling it here will work for
|
||||
// testing purposes, it will not yield performance gains (or correct results)
|
||||
#define FFX_CACAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET (1)
|
||||
//
|
||||
#define FFX_CACAO_REDUCE_RADIUS_NEAR_SCREEN_BORDER_ENABLE_AT_QUALITY_PRESET (99) // 99 means disabled; only helpful if artifacts at the edges caused by lack of out of screen depth data are not acceptable with the depth sampler in either clamp or mirror modes
|
||||
|
||||
// =======================================================================================================
|
||||
// SSAO Generation
|
||||
|
||||
// calculate effect radius and fit our screen sampling pattern inside it
|
||||
void FFX_CACAO_CalculateRadiusParameters(const FfxFloat32 pixCenterLength, const FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ, out FfxFloat32 pixLookupRadiusMod, out FfxFloat32 effectRadius, out FfxFloat32 falloffCalcMulSq)
|
||||
{
|
||||
effectRadius = EffectRadius();
|
||||
|
||||
// leaving this out for performance reasons: use something similar if radius needs to scale based on distance
|
||||
//effectRadius *= pow( pixCenterLength, RadiusDistanceScalingFunctionPow());
|
||||
|
||||
// when too close, on-screen sampling disk will grow beyond screen size; limit this to avoid closeup temporal artifacts
|
||||
const FfxFloat32 tooCloseLimitMod = ffxSaturate(pixCenterLength * EffectSamplingRadiusNearLimitRec()) * 0.8 + 0.2;
|
||||
|
||||
effectRadius *= tooCloseLimitMod;
|
||||
|
||||
// 0.85 is to reduce the radius to allow for more samples on a slope to still stay within influence
|
||||
pixLookupRadiusMod = (0.85 * effectRadius) / pixelDirRBViewspaceSizeAtCenterZ.x;
|
||||
|
||||
// used to calculate falloff (both for AO samples and per-sample weights)
|
||||
falloffCalcMulSq = -1.0f / (effectRadius*effectRadius);
|
||||
}
|
||||
|
||||
// all vectors in viewspace
|
||||
FfxFloat32 FFX_CACAO_CalculatePixelObscurance(FfxFloat32x3 pixelNormal, FfxFloat32x3 hitDelta, FfxFloat32 falloffCalcMulSq)
|
||||
{
|
||||
FfxFloat32 lengthSq = dot(hitDelta, hitDelta);
|
||||
FfxFloat32 NdotD = dot(pixelNormal, hitDelta) / sqrt(lengthSq);
|
||||
|
||||
FfxFloat32 falloffMult = max(0.0, lengthSq * falloffCalcMulSq + 1.0);
|
||||
|
||||
return max(0, NdotD - EffectHorizonAngleThreshold()) * falloffMult;
|
||||
}
|
||||
|
||||
void FFX_CACAO_SSAOTapInner(const FfxInt32 qualityLevel,
|
||||
inout FfxFloat32 obscuranceSum,
|
||||
inout FfxFloat32 weightSum,
|
||||
const FfxFloat32x2 samplingUV,
|
||||
const FfxFloat32 mipLevel,
|
||||
const FfxFloat32x3 pixCenterPos,
|
||||
const FfxFloat32x3 negViewspaceDir,
|
||||
FfxFloat32x3 pixelNormal,
|
||||
const FfxFloat32 falloffCalcMulSq,
|
||||
const FfxFloat32 weightMod,
|
||||
const FfxInt32 dbgTapIndex,
|
||||
FfxUInt32 layerId)
|
||||
{
|
||||
// get depth at sample
|
||||
FfxFloat32 viewspaceSampleZ = FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(samplingUV, mipLevel, layerId);
|
||||
|
||||
// convert to viewspace
|
||||
FfxFloat32x3 hitPos = FFX_CACAO_DepthBufferUVToViewSpace(samplingUV.xy, viewspaceSampleZ).xyz;
|
||||
FfxFloat32x3 hitDelta = hitPos - pixCenterPos;
|
||||
|
||||
FfxFloat32 obscurance = FFX_CACAO_CalculatePixelObscurance(pixelNormal, hitDelta, falloffCalcMulSq);
|
||||
FfxFloat32 weight = 1.0;
|
||||
|
||||
if (qualityLevel >= FFX_CACAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET)
|
||||
{
|
||||
//FfxFloat32 reduct = max( 0, dot( hitDelta, negViewspaceDir ) );
|
||||
FfxFloat32 reduct = max(0, -hitDelta.z); // cheaper, less correct version
|
||||
reduct = ffxSaturate(reduct * NegRecEffectRadius() + 2.0); // ffxSaturate( 2.0 - reduct / EffectRadius() );
|
||||
weight = FFX_CACAO_HALOING_REDUCTION_AMOUNT * reduct + (1.0 - FFX_CACAO_HALOING_REDUCTION_AMOUNT);
|
||||
}
|
||||
weight *= weightMod;
|
||||
obscuranceSum += obscurance * weight;
|
||||
weightSum += weight;
|
||||
}
|
||||
|
||||
void FFX_CACAO_SSAOTap(const FfxInt32 qualityLevel,
|
||||
inout FfxFloat32 obscuranceSum,
|
||||
inout FfxFloat32 weightSum,
|
||||
const FfxInt32 tapIndex,
|
||||
const FfxFloat32x2x2 rotScale,
|
||||
const FfxFloat32x3 pixCenterPos,
|
||||
const FfxFloat32x3 negViewspaceDir,
|
||||
FfxFloat32x3 pixelNormal,
|
||||
const FfxFloat32x2 normalizedScreenPos,
|
||||
const FfxFloat32x2 depthBufferUV,
|
||||
const FfxFloat32 mipOffset,
|
||||
const FfxFloat32 falloffCalcMulSq,
|
||||
FfxFloat32 weightMod,
|
||||
FfxFloat32x2 normXY,
|
||||
FfxFloat32 normXYLength,
|
||||
const FfxUInt32 layerId)
|
||||
{
|
||||
FfxFloat32x2 sampleOffset;
|
||||
FfxFloat32 samplePow2Len;
|
||||
|
||||
// patterns
|
||||
{
|
||||
FfxFloat32x4 newSample = g_FFX_CACAO_samplePatternMain[tapIndex];
|
||||
sampleOffset = FFX_TRANSFORM_VECTOR(rotScale, newSample.xy);
|
||||
samplePow2Len = newSample.w; // precalculated, same as: samplePow2Len = log2( length( newSample.xy ) );
|
||||
weightMod *= newSample.z;
|
||||
}
|
||||
|
||||
// snap to pixel center (more correct obscurance math, avoids artifacts)
|
||||
sampleOffset = round(sampleOffset);
|
||||
|
||||
// calculate MIP based on the sample distance from the centre, similar to as described
|
||||
// in http://graphics.cs.williams.edu/papers/SAOHPG12/.
|
||||
FfxFloat32 mipLevel = (qualityLevel < FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (samplePow2Len + mipOffset);
|
||||
|
||||
FfxFloat32x2 samplingUV = sampleOffset * DeinterleavedDepthBufferInverseDimensions() + depthBufferUV;
|
||||
|
||||
FFX_CACAO_SSAOTapInner(qualityLevel, obscuranceSum, weightSum, samplingUV, mipLevel, pixCenterPos, negViewspaceDir, pixelNormal, falloffCalcMulSq, weightMod, tapIndex * 2, layerId);
|
||||
|
||||
// for the second tap, just use the mirrored offset
|
||||
FfxFloat32x2 sampleOffsetMirroredUV = -sampleOffset;
|
||||
|
||||
// tilt the second set of samples so that the disk is effectively rotated by the normal
|
||||
// effective at removing one set of artifacts, but too expensive for lower quality settings
|
||||
if (qualityLevel >= FFX_CACAO_TILT_SAMPLES_ENABLE_AT_QUALITY_PRESET)
|
||||
{
|
||||
FfxFloat32 dotNorm = dot(sampleOffsetMirroredUV, normXY);
|
||||
sampleOffsetMirroredUV -= dotNorm * normXYLength * normXY;
|
||||
sampleOffsetMirroredUV = round(sampleOffsetMirroredUV);
|
||||
}
|
||||
|
||||
// snap to pixel center (more correct obscurance math, avoids artifacts)
|
||||
FfxFloat32x2 samplingMirroredUV = sampleOffsetMirroredUV * DeinterleavedDepthBufferInverseDimensions() + depthBufferUV;
|
||||
|
||||
FFX_CACAO_SSAOTapInner(qualityLevel, obscuranceSum, weightSum, samplingMirroredUV, mipLevel, pixCenterPos, negViewspaceDir, pixelNormal, falloffCalcMulSq, weightMod, tapIndex * 2 + 1, layerId);
|
||||
}
|
||||
|
||||
struct FFX_CACAO_SSAOHits
|
||||
{
|
||||
FfxFloat32x3 hits[2];
|
||||
FfxFloat32 weightMod;
|
||||
};
|
||||
|
||||
struct FFX_CACAO_SSAOSampleData
|
||||
{
|
||||
FfxFloat32x2 uvOffset;
|
||||
FfxFloat32 mipLevel;
|
||||
FfxFloat32 weightMod;
|
||||
};
|
||||
|
||||
FFX_CACAO_SSAOSampleData FFX_CACAO_SSAOGetSampleData(const FfxInt32 qualityLevel,
|
||||
const FfxFloat32x2x2 rotScale,
|
||||
const FfxFloat32x4 newSample,
|
||||
const FfxFloat32 mipOffset)
|
||||
{
|
||||
FfxFloat32x2 sampleOffset = FFX_TRANSFORM_VECTOR(rotScale, newSample.xy);
|
||||
sampleOffset = round(sampleOffset) * DeinterleavedDepthBufferInverseDimensions();
|
||||
|
||||
FfxFloat32 samplePow2Len = newSample.w;
|
||||
FfxFloat32 mipLevel = (qualityLevel < FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (samplePow2Len + mipOffset);
|
||||
|
||||
FFX_CACAO_SSAOSampleData result;
|
||||
|
||||
result.uvOffset = sampleOffset;
|
||||
result.mipLevel = mipLevel;
|
||||
result.weightMod = newSample.z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
FFX_CACAO_SSAOHits FFX_CACAO_SSAOGetHits2(FFX_CACAO_SSAOSampleData data, const FfxFloat32x2 depthBufferUV, const FfxUInt32 layerId)
|
||||
{
|
||||
FFX_CACAO_SSAOHits result;
|
||||
result.weightMod = data.weightMod;
|
||||
FfxFloat32x2 sampleUV = depthBufferUV + data.uvOffset;
|
||||
result.hits[0] = FfxFloat32x3(sampleUV, FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(sampleUV, data.mipLevel, layerId));
|
||||
sampleUV = depthBufferUV - data.uvOffset;
|
||||
result.hits[1] = FfxFloat32x3(sampleUV, FFX_CACAO_SSAOGeneration_SampleViewspaceDepthMip(sampleUV, data.mipLevel, layerId));
|
||||
return result;
|
||||
}
|
||||
|
||||
void FFX_CACAO_SSAOAddHits(const FfxInt32 qualityLevel, const FfxFloat32x3 pixCenterPos, const FfxFloat32x3 pixelNormal, const FfxFloat32 falloffCalcMulSq, inout FfxFloat32 weightSum, inout FfxFloat32 obscuranceSum, FFX_CACAO_SSAOHits hits)
|
||||
{
|
||||
FfxFloat32 weight = hits.weightMod;
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 hitIndex = 0; hitIndex < 2; ++hitIndex)
|
||||
{
|
||||
FfxFloat32x3 hit = hits.hits[hitIndex];
|
||||
FfxFloat32x3 hitPos = FFX_CACAO_DepthBufferUVToViewSpace(hit.xy, hit.z);
|
||||
FfxFloat32x3 hitDelta = hitPos - pixCenterPos;
|
||||
|
||||
FfxFloat32 obscurance = FFX_CACAO_CalculatePixelObscurance(pixelNormal, hitDelta, falloffCalcMulSq);
|
||||
|
||||
if (qualityLevel >= FFX_CACAO_HALOING_REDUCTION_ENABLE_AT_QUALITY_PRESET)
|
||||
{
|
||||
//FfxFloat32 reduct = max( 0, dot( hitDelta, negViewspaceDir ) );
|
||||
FfxFloat32 reduct = max(0, -hitDelta.z); // cheaper, less correct version
|
||||
reduct = ffxSaturate(reduct * NegRecEffectRadius() + 2.0); // ffxSaturate( 2.0 - reduct / EffectRadius() );
|
||||
weight = FFX_CACAO_HALOING_REDUCTION_AMOUNT * reduct + (1.0 - FFX_CACAO_HALOING_REDUCTION_AMOUNT);
|
||||
}
|
||||
obscuranceSum += obscurance * weight;
|
||||
weightSum += weight;
|
||||
}
|
||||
}
|
||||
|
||||
void FFX_CACAO_GenerateSSAOShadowsInternal(out FfxFloat32 outShadowTerm,
|
||||
out FfxFloat32x4 outEdges,
|
||||
out FfxFloat32 outWeight,
|
||||
const FfxFloat32x2 SVPos /*, const FfxFloat32x2 normalizedScreenPos*/,
|
||||
FFX_PARAMETER_UNIFORM FfxInt32 qualityLevel,
|
||||
bool adaptiveBase,
|
||||
const FfxUInt32 layerId)
|
||||
{
|
||||
FfxFloat32x2 SVPosRounded = trunc(SVPos);
|
||||
FfxUInt32x2 SVPosui = FfxUInt32x2(SVPosRounded); //same as FfxUInt32x2( SVPos )
|
||||
|
||||
const FfxInt32 numberOfTaps = (adaptiveBase) ? (FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT) : FfxInt32(g_FFX_CACAO_numTaps[qualityLevel]);
|
||||
FfxFloat32 pixZ, pixLZ, pixTZ, pixRZ, pixBZ;
|
||||
|
||||
FfxFloat32x2 depthBufferUVCorner = (SVPos + 1.0f) * DeinterleavedDepthBufferInverseDimensions() + DeinterleavedDepthBufferNormalisedOffset(); //Need corner to avoid gather fixed point error.
|
||||
FfxFloat32x2 depthBufferUV = (SVPos + 0.5f) * DeinterleavedDepthBufferInverseDimensions() + DeinterleavedDepthBufferNormalisedOffset(); //Need center coord
|
||||
FfxFloat32x4 valuesUL = FFX_CACAO_SSAOGeneration_GatherViewspaceDepthOffset(depthBufferUVCorner, FfxInt32x2(-1, -1), layerId);
|
||||
FfxFloat32x4 valuesBR = FFX_CACAO_SSAOGeneration_GatherViewspaceDepthOffset(depthBufferUVCorner, FfxInt32x2(0, 0), layerId);
|
||||
|
||||
|
||||
// get this pixel's viewspace depth
|
||||
pixZ = valuesUL.y;
|
||||
|
||||
// get left right top bottom neighbouring pixels for edge detection (gets compiled out on qualityLevel == 0)
|
||||
pixLZ = valuesUL.x;
|
||||
pixTZ = valuesUL.z;
|
||||
pixRZ = valuesBR.z;
|
||||
pixBZ = valuesBR.x;
|
||||
|
||||
// FfxFloat32x2 normalizedScreenPos = SVPosRounded * Viewport2xPixelSize() + Viewport2xPixelSize_x_025();
|
||||
FfxFloat32x2 normalizedScreenPos = (SVPosRounded + 0.5f) * SSAOBufferInverseDimensions();
|
||||
FfxFloat32x3 pixCenterPos = FFX_CACAO_NDCToViewSpace(normalizedScreenPos, pixZ); // g
|
||||
|
||||
// Load this pixel's viewspace normal
|
||||
// FfxUInt32x2 fullResCoord = 2 * (SVPosui * 2 + PerPassFullResCoordOffset().xy);
|
||||
FfxFloat32x3 pixelNormal = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui, layerId);
|
||||
|
||||
// optimized approximation of: FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ = FFX_CACAO_NDCToViewSpace( normalizedScreenPos.xy + _ViewportPixelSize().xy, pixCenterPos.z ).xy - pixCenterPos.xy;
|
||||
// const FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ = pixCenterPos.z * NDCToViewMul() * Viewport2xPixelSize();
|
||||
const FfxFloat32x2 pixelDirRBViewspaceSizeAtCenterZ = pixCenterPos.z * NDCToViewMul() * SSAOBufferInverseDimensions();
|
||||
|
||||
FfxFloat32 pixLookupRadiusMod;
|
||||
FfxFloat32 falloffCalcMulSq;
|
||||
|
||||
// calculate effect radius and fit our screen sampling pattern inside it
|
||||
FfxFloat32 effectViewspaceRadius;
|
||||
FFX_CACAO_CalculateRadiusParameters(length(pixCenterPos), pixelDirRBViewspaceSizeAtCenterZ, pixLookupRadiusMod, effectViewspaceRadius, falloffCalcMulSq);
|
||||
|
||||
// calculate samples rotation/scaling
|
||||
FfxFloat32x2x2 rotScale;
|
||||
{
|
||||
// reduce effect radius near the screen edges slightly; ideally, one would render a larger depth buffer (5% on each side) instead
|
||||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_REDUCE_RADIUS_NEAR_SCREEN_BORDER_ENABLE_AT_QUALITY_PRESET))
|
||||
{
|
||||
FfxFloat32 nearScreenBorder = min(min(depthBufferUV.x, 1.0 - depthBufferUV.x), min(depthBufferUV.y, 1.0 - depthBufferUV.y));
|
||||
nearScreenBorder = ffxSaturate(10.0 * nearScreenBorder + 0.6);
|
||||
pixLookupRadiusMod *= nearScreenBorder;
|
||||
}
|
||||
|
||||
// load & update pseudo-random rotation matrix
|
||||
FfxUInt32 pseudoRandomIndex = FfxUInt32(SVPosRounded.y * 2 + SVPosRounded.x) % 5;
|
||||
FfxFloat32x4 rs = PatternRotScaleMatrices(layerId, pseudoRandomIndex);
|
||||
rotScale = FfxFloat32x2x2(rs.x * pixLookupRadiusMod, rs.y * pixLookupRadiusMod, rs.z * pixLookupRadiusMod, rs.w * pixLookupRadiusMod);
|
||||
}
|
||||
|
||||
// the main obscurance & sample weight storage
|
||||
FfxFloat32 obscuranceSum = 0.0;
|
||||
FfxFloat32 weightSum = 0.0;
|
||||
|
||||
// edge mask for between this and left/right/top/bottom neighbour pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge)
|
||||
FfxFloat32x4 edgesLRTB = FfxFloat32x4(1.0, 1.0, 1.0, 1.0);
|
||||
|
||||
// Move center pixel slightly towards camera to avoid imprecision artifacts due to using of 16bit depth buffer; a lot smaller offsets needed when using 32bit floats
|
||||
pixCenterPos *= DepthPrecisionOffsetMod();
|
||||
|
||||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET))
|
||||
{
|
||||
edgesLRTB = FFX_CACAO_CalculateEdges(pixZ, pixLZ, pixRZ, pixTZ, pixBZ);
|
||||
}
|
||||
|
||||
// adds a more high definition sharp effect, which gets blurred out (reuses left/right/top/bottom samples that we used for edge detection)
|
||||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_DETAIL_AO_ENABLE_AT_QUALITY_PRESET))
|
||||
{
|
||||
// disable in case of quality level 4 (reference)
|
||||
if (qualityLevel != 4)
|
||||
{
|
||||
//approximate neighbouring pixels positions (actually just deltas or "positions - pixCenterPos" )
|
||||
FfxFloat32x3 viewspaceDirZNormalized = FfxFloat32x3(pixCenterPos.xy / pixCenterPos.zz, 1.0);
|
||||
|
||||
// very close approximation of: FfxFloat32x3 pixLPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( -HalfViewportPixelSize().x, 0.0 ), pixLZ ).xyz - pixCenterPos.xyz;
|
||||
FfxFloat32x3 pixLDelta = FfxFloat32x3(-pixelDirRBViewspaceSizeAtCenterZ.x, 0.0, 0.0) + viewspaceDirZNormalized * (pixLZ - pixCenterPos.z);
|
||||
// very close approximation of: FfxFloat32x3 pixRPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( +HalfViewportPixelSize().x, 0.0 ), pixRZ ).xyz - pixCenterPos.xyz;
|
||||
FfxFloat32x3 pixRDelta = FfxFloat32x3(+pixelDirRBViewspaceSizeAtCenterZ.x, 0.0, 0.0) + viewspaceDirZNormalized * (pixRZ - pixCenterPos.z);
|
||||
// very close approximation of: FfxFloat32x3 pixTPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( 0.0, -HalfViewportPixelSize().y ), pixTZ ).xyz - pixCenterPos.xyz;
|
||||
FfxFloat32x3 pixTDelta = FfxFloat32x3(0.0, -pixelDirRBViewspaceSizeAtCenterZ.y, 0.0) + viewspaceDirZNormalized * (pixTZ - pixCenterPos.z);
|
||||
// very close approximation of: FfxFloat32x3 pixBPos = FFX_CACAO_NDCToViewSpace( normalizedScreenPos + FfxFloat32x2( 0.0, +HalfViewportPixelSize().y ), pixBZ ).xyz - pixCenterPos.xyz;
|
||||
FfxFloat32x3 pixBDelta = FfxFloat32x3(0.0, +pixelDirRBViewspaceSizeAtCenterZ.y, 0.0) + viewspaceDirZNormalized * (pixBZ - pixCenterPos.z);
|
||||
|
||||
const FfxFloat32 rangeReductionConst = 4.0f; // this is to avoid various artifacts
|
||||
const FfxFloat32 modifiedFalloffCalcMulSq = rangeReductionConst * falloffCalcMulSq;
|
||||
|
||||
FfxFloat32x4 additionalObscurance;
|
||||
additionalObscurance.x = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixLDelta, modifiedFalloffCalcMulSq);
|
||||
additionalObscurance.y = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixRDelta, modifiedFalloffCalcMulSq);
|
||||
additionalObscurance.z = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixTDelta, modifiedFalloffCalcMulSq);
|
||||
additionalObscurance.w = FFX_CACAO_CalculatePixelObscurance(pixelNormal, pixBDelta, modifiedFalloffCalcMulSq);
|
||||
|
||||
obscuranceSum += DetailAOStrength() * dot(additionalObscurance, edgesLRTB);
|
||||
}
|
||||
}
|
||||
|
||||
// Sharp normals also create edges - but this adds to the cost as well
|
||||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_NORMAL_BASED_EDGES_ENABLE_AT_QUALITY_PRESET))
|
||||
{
|
||||
FfxFloat32x3 neighbourNormalL = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(-1, +0), layerId);
|
||||
FfxFloat32x3 neighbourNormalR = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(+1, +0), layerId);
|
||||
FfxFloat32x3 neighbourNormalT = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(+0, -1), layerId);
|
||||
FfxFloat32x3 neighbourNormalB = FFX_CACAO_SSAOGeneration_GetNormalPass(SVPosui + FfxInt32x2(+0, +1), layerId);
|
||||
|
||||
const FfxFloat32 dotThreshold = FFX_CACAO_NORMAL_BASED_EDGES_DOT_THRESHOLD;
|
||||
|
||||
FfxFloat32x4 normalEdgesLRTB;
|
||||
normalEdgesLRTB.x = ffxSaturate((dot(pixelNormal, neighbourNormalL) + dotThreshold));
|
||||
normalEdgesLRTB.y = ffxSaturate((dot(pixelNormal, neighbourNormalR) + dotThreshold));
|
||||
normalEdgesLRTB.z = ffxSaturate((dot(pixelNormal, neighbourNormalT) + dotThreshold));
|
||||
normalEdgesLRTB.w = ffxSaturate((dot(pixelNormal, neighbourNormalB) + dotThreshold));
|
||||
|
||||
//#define FFX_CACAO_SMOOTHEN_NORMALS // fixes some aliasing artifacts but kills a lot of high detail and adds to the cost - not worth it probably but feel free to play with it
|
||||
#ifdef FFX_CACAO_SMOOTHEN_NORMALS
|
||||
//neighbourNormalL = LoadNormal( fullResCoord, FfxInt32x2( -1, 0 ) );
|
||||
//neighbourNormalR = LoadNormal( fullResCoord, FfxInt32x2( 1, 0 ) );
|
||||
//neighbourNormalT = LoadNormal( fullResCoord, FfxInt32x2( 0, -1 ) );
|
||||
//neighbourNormalB = LoadNormal( fullResCoord, FfxInt32x2( 0, 1 ) );
|
||||
pixelNormal += neighbourNormalL * edgesLRTB.x + neighbourNormalR * edgesLRTB.y + neighbourNormalT * edgesLRTB.z + neighbourNormalB * edgesLRTB.w;
|
||||
pixelNormal = normalize(pixelNormal);
|
||||
#endif
|
||||
|
||||
edgesLRTB *= normalEdgesLRTB;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const FfxFloat32 globalMipOffset = FFX_CACAO_DEPTH_MIPS_GLOBAL_OFFSET;
|
||||
FfxFloat32 mipOffset = (qualityLevel < FFX_CACAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (log2(pixLookupRadiusMod) + globalMipOffset);
|
||||
|
||||
// Used to tilt the second set of samples so that the disk is effectively rotated by the normal
|
||||
// effective at removing one set of artifacts, but too expensive for lower quality settings
|
||||
FfxFloat32x2 normXY = FfxFloat32x2(pixelNormal.x, pixelNormal.y);
|
||||
FfxFloat32 normXYLength = length(normXY);
|
||||
normXY /= FfxFloat32x2(normXYLength, -normXYLength);
|
||||
normXYLength *= FFX_CACAO_TILT_SAMPLES_AMOUNT;
|
||||
|
||||
const FfxFloat32x3 negViewspaceDir = -normalize(pixCenterPos);
|
||||
|
||||
// standard, non-adaptive approach
|
||||
if ((qualityLevel != 3) || adaptiveBase)
|
||||
{
|
||||
FFX_UNROLL
|
||||
for (FfxInt32 i = 0; i < numberOfTaps; i++)
|
||||
{
|
||||
FFX_CACAO_SSAOTap(qualityLevel, obscuranceSum, weightSum, i, rotScale, pixCenterPos, negViewspaceDir, pixelNormal, normalizedScreenPos, depthBufferUV, mipOffset, falloffCalcMulSq, 1.0, normXY, normXYLength, layerId);
|
||||
}
|
||||
}
|
||||
else // if( qualityLevel == 3 ) adaptive approach
|
||||
{
|
||||
// add new ones if needed
|
||||
FfxFloat32x2 fullResUV = normalizedScreenPos + PerPassFullResUVOffset(layerId).xy;
|
||||
FfxFloat32 importance = FFX_CACAO_SSAOGeneration_SampleImportance(fullResUV);
|
||||
|
||||
// this is to normalize FFX_CACAO_DETAIL_AO_AMOUNT across all pixel regardless of importance
|
||||
obscuranceSum *= (FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT / FfxFloat32(FFX_CACAO_MAX_TAPS)) + (importance * FFX_CACAO_ADAPTIVE_TAP_FLEXIBLE_COUNT / FfxFloat32(FFX_CACAO_MAX_TAPS));
|
||||
|
||||
// load existing base values
|
||||
FfxFloat32x2 baseValues = FFX_CACAO_SSAOGeneration_LoadBasePassSSAOPass(SVPosui, layerId); //PassIndex());
|
||||
weightSum += baseValues.y * FfxFloat32(FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT * 4.0);
|
||||
obscuranceSum += (baseValues.x) * weightSum;
|
||||
|
||||
// increase importance around edges
|
||||
FfxFloat32 edgeCount = dot(1.0 - edgesLRTB, FfxFloat32x4(1.0, 1.0, 1.0, 1.0));
|
||||
|
||||
FfxFloat32 avgTotalImportance = FfxFloat32(FFX_CACAO_SSAOGeneration_GetLoadCounter()) * LoadCounterAvgDiv();
|
||||
|
||||
FfxFloat32 importanceLimiter = ffxSaturate(AdaptiveSampleCountLimit() / avgTotalImportance);
|
||||
importance *= importanceLimiter;
|
||||
|
||||
FfxFloat32 additionalSampleCountFlt = FFX_CACAO_ADAPTIVE_TAP_FLEXIBLE_COUNT * importance;
|
||||
|
||||
additionalSampleCountFlt += 1.5;
|
||||
FfxUInt32 additionalSamples = FfxUInt32(additionalSampleCountFlt);
|
||||
FfxUInt32 additionalSamplesTo = min(FFX_CACAO_MAX_TAPS - 1, additionalSamples + FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT);
|
||||
|
||||
// sample loop
|
||||
{
|
||||
FfxFloat32x4 newSample = g_FFX_CACAO_samplePatternMain[FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT];
|
||||
FFX_CACAO_SSAOSampleData data = FFX_CACAO_SSAOGetSampleData(qualityLevel, rotScale, newSample, mipOffset);
|
||||
FFX_CACAO_SSAOHits hits = FFX_CACAO_SSAOGetHits2(data, depthBufferUV, layerId);
|
||||
newSample = g_FFX_CACAO_samplePatternMain[FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT + 1];
|
||||
|
||||
for (FfxUInt32 i = FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT; i < additionalSamplesTo - 1; i++)
|
||||
{
|
||||
data = FFX_CACAO_SSAOGetSampleData(qualityLevel, rotScale, newSample, mipOffset);
|
||||
newSample = g_FFX_CACAO_samplePatternMain[i + 2];
|
||||
FFX_CACAO_SSAOHits nextHits = FFX_CACAO_SSAOGetHits2(data, depthBufferUV, layerId);
|
||||
|
||||
FFX_CACAO_SSAOAddHits(qualityLevel, pixCenterPos, pixelNormal, falloffCalcMulSq, weightSum, obscuranceSum, hits);
|
||||
hits = nextHits;
|
||||
}
|
||||
|
||||
// last loop iteration
|
||||
{
|
||||
FFX_CACAO_SSAOAddHits(qualityLevel, pixCenterPos, pixelNormal, falloffCalcMulSq, weightSum, obscuranceSum, hits);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// early out for adaptive base - just output weight (used for the next pass)
|
||||
if (adaptiveBase)
|
||||
{
|
||||
FfxFloat32 obscurance = obscuranceSum / weightSum;
|
||||
|
||||
outShadowTerm = obscurance;
|
||||
outEdges = FfxFloat32x4(0, 0, 0, 0);
|
||||
outWeight = weightSum;
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate weighted average
|
||||
FfxFloat32 obscurance = obscuranceSum / weightSum;
|
||||
|
||||
// calculate fadeout (1 close, gradient, 0 far)
|
||||
FfxFloat32 fadeOut = ffxSaturate(pixCenterPos.z * EffectFadeOutMul() + EffectFadeOutAdd());
|
||||
|
||||
// Reduce the SSAO shadowing if we're on the edge to remove artifacts on edges (we don't care for the lower quality one)
|
||||
if (!adaptiveBase && (qualityLevel >= FFX_CACAO_DEPTH_BASED_EDGES_ENABLE_AT_QUALITY_PRESET))
|
||||
{
|
||||
// FfxFloat32 edgeCount = dot( 1.0-edgesLRTB, FfxFloat32x4( 1.0, 1.0, 1.0, 1.0 ) );
|
||||
|
||||
// when there's more than 2 opposite edges, start fading out the occlusion to reduce aliasing artifacts
|
||||
FfxFloat32 edgeFadeoutFactor = ffxSaturate((1.0 - edgesLRTB.x - edgesLRTB.y) * 0.35) + ffxSaturate((1.0 - edgesLRTB.z - edgesLRTB.w) * 0.35);
|
||||
|
||||
// (experimental) if you want to reduce the effect next to any edge
|
||||
// edgeFadeoutFactor += 0.1 * ffxSaturate( dot( 1 - edgesLRTB, FfxFloat32x4( 1, 1, 1, 1 ) ) );
|
||||
|
||||
fadeOut *= ffxSaturate(1.0 - edgeFadeoutFactor);
|
||||
}
|
||||
|
||||
// same as a bove, but a lot more conservative version
|
||||
// fadeOut *= ffxSaturate( dot( edgesLRTB, FfxFloat32x4( 0.9, 0.9, 0.9, 0.9 ) ) - 2.6 );
|
||||
|
||||
// strength
|
||||
obscurance = EffectShadowStrength() * obscurance;
|
||||
|
||||
// clamp
|
||||
obscurance = min(obscurance, EffectShadowClamp());
|
||||
|
||||
// fadeout
|
||||
obscurance *= fadeOut;
|
||||
|
||||
// conceptually switch to occlusion with the meaning being visibility (grows with visibility, occlusion == 1 implies full visibility),
|
||||
// to be in line with what is more commonly used.
|
||||
FfxFloat32 occlusion = 1.0 - obscurance;
|
||||
|
||||
// modify the gradient
|
||||
// note: this cannot be moved to a later pass because of loss of precision after storing in the render target
|
||||
occlusion = pow(ffxSaturate(occlusion), EffectShadowPow());
|
||||
|
||||
// outputs!
|
||||
outShadowTerm = occlusion; // Our final 'occlusion' term (0 means fully occluded, 1 means fully lit)
|
||||
outEdges = edgesLRTB; // These are used to prevent blurring across edges, 1 means no edge, 0 means edge, 0.5 means half way there, etc.
|
||||
outWeight = weightSum;
|
||||
}
|
||||
|
||||
void FFX_CACAO_GenerateQ0(FfxUInt32x3 tid)
|
||||
{
|
||||
FfxUInt32 tidCorrectedZ = tid.z % 5;
|
||||
FfxUInt32 layerId = tid.z / 5;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; // Choose correct layer in 2 layer case
|
||||
FfxUInt32 xOffset = (tid.y * 3 + tidCorrectedZ) % 5;
|
||||
FfxUInt32x2 coord = FfxUInt32x2(5 * tid.x + xOffset, tid.y);
|
||||
FfxFloat32x2 inPos = FfxFloat32x2(coord);
|
||||
FfxFloat32 outShadowTerm;
|
||||
FfxFloat32 outWeight;
|
||||
FfxFloat32x4 outEdges;
|
||||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 0, false, layerId);
|
||||
FfxFloat32x2 out0;
|
||||
out0.x = outShadowTerm;
|
||||
out0.y = FFX_CACAO_PackEdges(FfxFloat32x4(1, 1, 1, 1)); // no edges in low quality
|
||||
FFX_CACAO_SSAOGeneration_StoreOutput(coord, out0, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_GenerateQ1(FfxUInt32x3 tid)
|
||||
{
|
||||
FfxUInt32 tidCorrectedZ = tid.z % 5;
|
||||
FfxUInt32 layerId = tid.z / 5;
|
||||
layerId = (layerId == 1 && BlurNumPasses() == 2) ? 3 : layerId; // Choose correct layer in 2 layer case
|
||||
FfxUInt32 xOffset = (tid.y * 3 + tidCorrectedZ) % 5;
|
||||
FfxUInt32x2 coord = FfxUInt32x2(5 * tid.x + xOffset, tid.y);
|
||||
FfxFloat32x2 inPos = FfxFloat32x2(coord);
|
||||
FfxFloat32 outShadowTerm;
|
||||
FfxFloat32 outWeight;
|
||||
FfxFloat32x4 outEdges;
|
||||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 1, false, layerId);
|
||||
FfxFloat32x2 out0;
|
||||
out0.x = outShadowTerm;
|
||||
out0.y = FFX_CACAO_PackEdges(outEdges);
|
||||
FFX_CACAO_SSAOGeneration_StoreOutput(coord, out0, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_GenerateQ2(FfxUInt32x3 coord)
|
||||
{
|
||||
FfxFloat32x2 inPos = FfxFloat32x2(coord.xy);
|
||||
FfxUInt32 layerId = coord.z;
|
||||
FfxFloat32 outShadowTerm;
|
||||
FfxFloat32 outWeight;
|
||||
FfxFloat32x4 outEdges;
|
||||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 2, false, layerId);
|
||||
FfxFloat32x2 out0;
|
||||
out0.x = outShadowTerm;
|
||||
out0.y = FFX_CACAO_PackEdges(outEdges);
|
||||
FFX_CACAO_SSAOGeneration_StoreOutput(coord.xy, out0, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_GenerateQ3Base(FfxUInt32x3 coord)
|
||||
{
|
||||
FfxFloat32x2 inPos = FfxFloat32x2(coord.xy);
|
||||
FfxUInt32 layerId = coord.z;
|
||||
FfxFloat32 outShadowTerm;
|
||||
FfxFloat32 outWeight;
|
||||
FfxFloat32x4 outEdges;
|
||||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 3, true, layerId);
|
||||
FfxFloat32x2 out0;
|
||||
out0.x = outShadowTerm;
|
||||
out0.y = outWeight / (FfxFloat32(FFX_CACAO_ADAPTIVE_TAP_BASE_COUNT) * 4.0); //0.0; //frac(outWeight / 6.0);// / (FfxFloat32)(FFX_CACAO_MAX_TAPS * 4.0);
|
||||
FFX_CACAO_SSAOGeneration_StoreOutput(coord.xy, out0, layerId);
|
||||
}
|
||||
|
||||
void FFX_CACAO_GenerateQ3(FfxUInt32x3 coord)
|
||||
{
|
||||
FfxFloat32x2 inPos = FfxFloat32x2(coord.xy);
|
||||
FfxUInt32 layerId = coord.z;
|
||||
FfxFloat32 outShadowTerm;
|
||||
FfxFloat32 outWeight;
|
||||
FfxFloat32x4 outEdges;
|
||||
FFX_CACAO_GenerateSSAOShadowsInternal(outShadowTerm, outEdges, outWeight, inPos.xy, 3, false, layerId);
|
||||
FfxFloat32x2 out0;
|
||||
out0.x = outShadowTerm;
|
||||
out0.y = FFX_CACAO_PackEdges(outEdges);
|
||||
FFX_CACAO_SSAOGeneration_StoreOutput(coord.xy, out0, layerId);
|
||||
}
|
||||
611
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_upscale.h
vendored
Normal file
611
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_upscale.h
vendored
Normal file
@@ -0,0 +1,611 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_cacao_defines.h"
|
||||
#include "ffx_cacao_utils.h"
|
||||
|
||||
#define FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH (FFX_CACAO_BILATERAL_UPSCALE_WIDTH + 4)
|
||||
#define FFX_CACAO_BILATERAL_UPSCALE_BUFFER_HEIGHT (FFX_CACAO_BILATERAL_UPSCALE_HEIGHT + 4 + 4)
|
||||
|
||||
struct FFX_CACAO_BilateralBufferVal
|
||||
{
|
||||
FfxUInt32 packedDepths;
|
||||
FfxUInt32 packedSsaoVals;
|
||||
};
|
||||
|
||||
FFX_GROUPSHARED FFX_CACAO_BilateralBufferVal s_FFX_CACAO_BilateralUpscaleBuffer[FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH][FFX_CACAO_BILATERAL_UPSCALE_BUFFER_HEIGHT];
|
||||
|
||||
void FFX_CACAO_BilateralUpscaleNxN(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid, const FfxInt32 width, const FfxInt32 height, const bool useEdges)
|
||||
{
|
||||
// fill in group shared buffer
|
||||
{
|
||||
FfxUInt32 threadNum = (gtid.y * FFX_CACAO_BILATERAL_UPSCALE_WIDTH + gtid.x) * 3;
|
||||
FfxUInt32x2 bufferCoord = FfxUInt32x2(threadNum % FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH, threadNum / FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH);
|
||||
FfxUInt32x2 imageCoord = (gid * FfxUInt32x2(FFX_CACAO_BILATERAL_UPSCALE_WIDTH, FFX_CACAO_BILATERAL_UPSCALE_HEIGHT)) + bufferCoord - 2;
|
||||
|
||||
if (useEdges)
|
||||
{
|
||||
FfxFloat32x2 inputs[3];
|
||||
for (FfxInt32 j = 0; j < 3; ++j)
|
||||
{
|
||||
FfxInt32x2 p = FfxInt32x2(imageCoord.x + j, imageCoord.y);
|
||||
FfxInt32x2 pos = p / 2;
|
||||
FfxInt32 index = (p.x % 2) + 2 * (p.y % 2);
|
||||
inputs[j] = FFX_CACAO_BilateralUpscale_LoadSSAO(pos, index);
|
||||
}
|
||||
|
||||
for (FfxInt32 i = 0; i < 3; ++i)
|
||||
{
|
||||
FfxInt32 mx = FfxInt32(imageCoord.x % 2);
|
||||
FfxInt32 my = FfxInt32(imageCoord.y % 2);
|
||||
|
||||
FfxInt32 ic = mx + my * 2; // center index
|
||||
FfxInt32 ih = (1 - mx) + my * 2; // neighbouring, horizontal
|
||||
FfxInt32 iv = mx + (1 - my) * 2; // neighbouring, vertical
|
||||
FfxInt32 id = (1 - mx) + (1 - my) * 2; // diagonal
|
||||
|
||||
FfxFloat32x2 centerVal = inputs[i];
|
||||
|
||||
FfxFloat32 ao = centerVal.x;
|
||||
|
||||
FfxFloat32x4 edgesLRTB = FFX_CACAO_UnpackEdges(centerVal.y);
|
||||
|
||||
// convert index shifts to sampling offsets
|
||||
FfxFloat32 fmx = FfxFloat32(mx);
|
||||
FfxFloat32 fmy = FfxFloat32(my);
|
||||
|
||||
// in case of an edge, push sampling offsets away from the edge (towards pixel center)
|
||||
FfxFloat32 fmxe = (edgesLRTB.y - edgesLRTB.x);
|
||||
FfxFloat32 fmye = (edgesLRTB.w - edgesLRTB.z);
|
||||
|
||||
// calculate final sampling offsets and sample using bilinear filter
|
||||
FfxFloat32x2 p = imageCoord;
|
||||
FfxFloat32x2 uvH = (p + FfxFloat32x2(fmx + fmxe - 0.5, 0.5 - fmy)) * 0.5 * SSAOBufferInverseDimensions();
|
||||
FfxFloat32 aoH = FFX_CACAO_BilateralUpscale_SampleSSAOLinear(uvH, ih);
|
||||
FfxFloat32x2 uvV = (p + FfxFloat32x2(0.5 - fmx, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions();
|
||||
FfxFloat32 aoV = FFX_CACAO_BilateralUpscale_SampleSSAOLinear(uvV, iv);
|
||||
FfxFloat32x2 uvD = (p + FfxFloat32x2(fmx - 0.5 + fmxe, fmy - 0.5 + fmye)) * 0.5 * SSAOBufferInverseDimensions();
|
||||
FfxFloat32 aoD = FFX_CACAO_BilateralUpscale_SampleSSAOLinear(uvD, id);
|
||||
|
||||
// reduce weight for samples near edge - if the edge is on both sides, weight goes to 0
|
||||
FfxFloat32x4 blendWeights;
|
||||
blendWeights.x = 1.0;
|
||||
blendWeights.y = (edgesLRTB.x + edgesLRTB.y) * 0.5;
|
||||
blendWeights.z = (edgesLRTB.z + edgesLRTB.w) * 0.5;
|
||||
blendWeights.w = (blendWeights.y + blendWeights.z) * 0.5;
|
||||
|
||||
// calculate weighted average
|
||||
FfxFloat32 blendWeightsSum = dot(blendWeights, FfxFloat32x4(1.0, 1.0, 1.0, 1.0));
|
||||
ao = dot(FfxFloat32x4(ao, aoH, aoV, aoD), blendWeights) / blendWeightsSum;
|
||||
|
||||
++imageCoord.x;
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal;
|
||||
|
||||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2((imageCoord / 2) + DeinterleavedDepthBufferOffset());
|
||||
FfxUInt32 depthArrayBufferIndex = ic;
|
||||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex);
|
||||
|
||||
bufferVal.packedDepths = ffxPackF32(FfxFloat32x2(depth, depth));
|
||||
bufferVal.packedSsaoVals = ffxPackF32(FfxFloat32x2(ao, ao));
|
||||
|
||||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (FfxInt32 i = 0; i < 3; ++i)
|
||||
{
|
||||
FfxFloat32x2 sampleLoc0 = (FfxFloat32x2(imageCoord / 2) + 0.5f) * SSAOBufferInverseDimensions();
|
||||
FfxFloat32x2 sampleLoc1 = sampleLoc0;
|
||||
FfxFloat32x2 sampleLoc2 = sampleLoc0;
|
||||
FfxFloat32x2 sampleLoc3 = sampleLoc0;
|
||||
switch ((imageCoord.y % 2) * 2 + (imageCoord.x % 2)) {
|
||||
case 0:
|
||||
sampleLoc1.x -= 0.5f * SSAOBufferInverseDimensions().x;
|
||||
sampleLoc2.y -= 0.5f * SSAOBufferInverseDimensions().y;
|
||||
sampleLoc3 -= 0.5f * SSAOBufferInverseDimensions();
|
||||
break;
|
||||
case 1:
|
||||
sampleLoc0.x += 0.5f * SSAOBufferInverseDimensions().x;
|
||||
sampleLoc2 += FfxFloat32x2(0.5f, -0.5f) * SSAOBufferInverseDimensions();
|
||||
sampleLoc3.y -= 0.5f * SSAOBufferInverseDimensions().y;
|
||||
break;
|
||||
case 2:
|
||||
sampleLoc0.y += 0.5f * SSAOBufferInverseDimensions().y;
|
||||
sampleLoc1 += FfxFloat32x2(-0.5f, 0.5f) * SSAOBufferInverseDimensions();
|
||||
sampleLoc3.x -= 0.5f * SSAOBufferInverseDimensions().x;
|
||||
break;
|
||||
case 3:
|
||||
sampleLoc0 += 0.5f * SSAOBufferInverseDimensions();
|
||||
sampleLoc1.y += 0.5f * SSAOBufferInverseDimensions().y;
|
||||
sampleLoc2.x += 0.5f * SSAOBufferInverseDimensions().x;
|
||||
break;
|
||||
}
|
||||
|
||||
FfxFloat32 ssaoVal0 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc0, 0);
|
||||
FfxFloat32 ssaoVal1 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc1, 1);
|
||||
FfxFloat32 ssaoVal2 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc2, 2);
|
||||
FfxFloat32 ssaoVal3 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc3, 3);
|
||||
|
||||
FfxUInt32x3 ssaoArrayBufferCoord = FfxUInt32x3(imageCoord / 2, 2 * (imageCoord.y % 2) + imageCoord.x % 2);
|
||||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2(ssaoArrayBufferCoord.xy + DeinterleavedDepthBufferOffset());
|
||||
FfxUInt32 depthArrayBufferIndex = ssaoArrayBufferCoord.z;
|
||||
++imageCoord.x;
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal;
|
||||
|
||||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex);
|
||||
FfxFloat32 ssaoVal = (ssaoVal0 + ssaoVal1 + ssaoVal2 + ssaoVal3) * 0.25f;
|
||||
|
||||
bufferVal.packedDepths = ffxPackF32(FfxFloat32x2(depth, depth));
|
||||
bufferVal.packedSsaoVals = ffxPackF32(FfxFloat32x2(ssaoVal, ssaoVal)); //CACAO_TODO half path?
|
||||
|
||||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
FfxFloat32 depths[4];
|
||||
// load depths
|
||||
{
|
||||
FfxInt32x2 fullBufferCoord = FfxInt32x2(2 * tid);
|
||||
FfxInt32x2 fullDepthBufferCoord = fullBufferCoord + DepthBufferOffset();
|
||||
|
||||
FfxFloat32x4 screenSpaceDepths = FFX_CACAO_BilateralUpscale_LoadDepths(fullDepthBufferCoord);
|
||||
|
||||
depths[0] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.x);
|
||||
depths[1] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.y);
|
||||
depths[2] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.z);
|
||||
depths[3] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.w);
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16x4 packedDepths = FfxFloat16x4(depths[0], depths[1], depths[2], depths[3]);
|
||||
|
||||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height);
|
||||
|
||||
FfxFloat16 epsilonWeight = FfxFloat16(1e-3f);
|
||||
FfxFloat16x2 nearestSsaoVals = ffxUnpackF16(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals);
|
||||
FfxFloat16x4 packedTotals = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
packedTotals.xy *= nearestSsaoVals;
|
||||
packedTotals.zw *= nearestSsaoVals;
|
||||
FfxFloat16x4 packedTotalWeights = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma();
|
||||
FfxFloat16x2 packedDistSigma = FfxFloat16x2(1.0f / distanceSigma, 1.0f / distanceSigma);
|
||||
FfxFloat32 sigma = BilateralSigmaSquared();
|
||||
FfxFloat16x2 packedSigma = FfxFloat16x2(1.0f / sigma, 1.0f / sigma);
|
||||
|
||||
for (FfxInt32 x = -width; x <= width; ++x)
|
||||
{
|
||||
for (FfxInt32 y = -height; y <= height; ++y)
|
||||
{
|
||||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y);
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y];
|
||||
|
||||
FfxFloat16x2 u = FfxFloat16x2(x, x) - FfxFloat16x2(0.0f, 0.5f);
|
||||
FfxFloat16x2 v1 = FfxFloat16x2(y, y) - FfxFloat16x2(0.0f, 0.0f);
|
||||
FfxFloat16x2 v2 = FfxFloat16x2(y, y) - FfxFloat16x2(0.5f, 0.5f);
|
||||
u = u * u;
|
||||
v1 = v1 * v1;
|
||||
v2 = v2 * v2;
|
||||
|
||||
FfxFloat16x2 dist1 = u + v1;
|
||||
FfxFloat16x2 dist2 = u + v2;
|
||||
|
||||
FfxFloat16x2 wx1 = exp(-dist1 * packedSigma);
|
||||
FfxFloat16x2 wx2 = exp(-dist2 * packedSigma);
|
||||
|
||||
FfxFloat16x2 bufferPackedDepths = ffxUnpackF16(bufferVal.packedDepths);
|
||||
|
||||
FfxFloat16x2 diff1 = packedDepths.xy - bufferPackedDepths;
|
||||
FfxFloat16x2 diff2 = packedDepths.zw - bufferPackedDepths;
|
||||
diff1 *= diff1;
|
||||
diff2 *= diff2;
|
||||
|
||||
FfxFloat16x2 wy1 = exp(-diff1 * packedDistSigma);
|
||||
FfxFloat16x2 wy2 = exp(-diff2 * packedDistSigma);
|
||||
|
||||
FfxFloat16x2 weight1 = wx1 * wy1;
|
||||
FfxFloat16x2 weight2 = wx2 * wy2;
|
||||
|
||||
FfxFloat16x2 packedSsaoVals = ffxUnpackF16(bufferVal.packedSsaoVals);
|
||||
packedTotals.xy += packedSsaoVals * weight1;
|
||||
packedTotals.zw += packedSsaoVals * weight2;
|
||||
packedTotalWeights.xy += weight1;
|
||||
packedTotalWeights.zw += weight2;
|
||||
}
|
||||
}
|
||||
|
||||
FfxUInt32x2 outputCoord = 2 * tid;
|
||||
FfxFloat16x4 outputValues = packedTotals / packedTotalWeights;
|
||||
#else
|
||||
FfxFloat32x4 packedDepths = FfxFloat32x4(depths[0], depths[1], depths[2], depths[3]);
|
||||
|
||||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height);
|
||||
|
||||
FfxFloat32 epsilonWeight = FfxFloat32(1e-3f);
|
||||
FfxFloat32x2 nearestSsaoVals = ffxUnpackF32(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals);
|
||||
FfxFloat32x4 packedTotals = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
packedTotals.xy *= nearestSsaoVals;
|
||||
packedTotals.zw *= nearestSsaoVals;
|
||||
FfxFloat32x4 packedTotalWeights = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma();
|
||||
FfxFloat32x2 packedDistSigma = FfxFloat32x2(1.0f / distanceSigma, 1.0f / distanceSigma);
|
||||
FfxFloat32 sigma = BilateralSigmaSquared();
|
||||
FfxFloat32x2 packedSigma = FfxFloat32x2(1.0f / sigma, 1.0f / sigma);
|
||||
|
||||
for (FfxInt32 x = -width; x <= width; ++x)
|
||||
{
|
||||
for (FfxInt32 y = -height; y <= height; ++y)
|
||||
{
|
||||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y);
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y];
|
||||
|
||||
FfxFloat32x2 u = FfxFloat32x2(x, x) - FfxFloat32x2(0.0f, 0.5f);
|
||||
FfxFloat32x2 v1 = FfxFloat32x2(y, y) - FfxFloat32x2(0.0f, 0.0f);
|
||||
FfxFloat32x2 v2 = FfxFloat32x2(y, y) - FfxFloat32x2(0.5f, 0.5f);
|
||||
u = u * u;
|
||||
v1 = v1 * v1;
|
||||
v2 = v2 * v2;
|
||||
|
||||
FfxFloat32x2 dist1 = u + v1;
|
||||
FfxFloat32x2 dist2 = u + v2;
|
||||
|
||||
FfxFloat32x2 wx1 = exp(-dist1 * packedSigma);
|
||||
FfxFloat32x2 wx2 = exp(-dist2 * packedSigma);
|
||||
|
||||
FfxFloat32x2 bufferPackedDepths = ffxUnpackF32(bufferVal.packedDepths);
|
||||
|
||||
FfxFloat32x2 diff1 = packedDepths.xy - bufferPackedDepths;
|
||||
FfxFloat32x2 diff2 = packedDepths.zw - bufferPackedDepths;
|
||||
diff1 *= diff1;
|
||||
diff2 *= diff2;
|
||||
|
||||
FfxFloat32x2 wy1 = exp(-diff1 * packedDistSigma);
|
||||
FfxFloat32x2 wy2 = exp(-diff2 * packedDistSigma);
|
||||
|
||||
FfxFloat32x2 weight1 = wx1 * wy1;
|
||||
FfxFloat32x2 weight2 = wx2 * wy2;
|
||||
|
||||
FfxFloat32x2 packedSsaoVals = ffxUnpackF32(bufferVal.packedSsaoVals);
|
||||
packedTotals.xy += packedSsaoVals * weight1;
|
||||
packedTotals.zw += packedSsaoVals * weight2;
|
||||
packedTotalWeights.xy += weight1;
|
||||
packedTotalWeights.zw += weight2;
|
||||
}
|
||||
}
|
||||
|
||||
FfxUInt32x2 outputCoord = 2 * tid;
|
||||
FfxFloat32x4 outputValues = packedTotals / packedTotalWeights;
|
||||
outputValues = pow(outputValues, FfxFloat32x4(2.2, 2.2, 2.2, 2.2));
|
||||
#endif //FFX_HALF
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 0), outputValues.x); // totals[0] / totalWeights[0];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 0), outputValues.y); // totals[1] / totalWeights[1];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 1), outputValues.z); // totals[2] / totalWeights[2];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 1), outputValues.w); // totals[3] / totalWeights[3];
|
||||
}
|
||||
|
||||
|
||||
void FFX_CACAO_UpscaleBilateral5x5Smart(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
FFX_CACAO_BilateralUpscaleNxN(tid, gtid, gid, 2, 2, true);
|
||||
}
|
||||
|
||||
void FFX_CACAO_UpscaleBilateral5x5NonSmart(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
FFX_CACAO_BilateralUpscaleNxN(tid, gtid, gid, 2, 2, false);
|
||||
}
|
||||
|
||||
void FFX_CACAO_UpscaleBilateral7x7(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
FFX_CACAO_BilateralUpscaleNxN(tid, gtid, gid, 3, 3, true);
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
void FFX_CACAO_UpscaleBilateral5x5Half(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
const FfxInt32 width = 2, height = 2;
|
||||
|
||||
// fill in group shared buffer
|
||||
{
|
||||
FfxUInt32 threadNum = (gtid.y * FFX_CACAO_BILATERAL_UPSCALE_WIDTH + gtid.x) * 3;
|
||||
FfxUInt32x2 bufferCoord = FfxUInt32x2(threadNum % FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH, threadNum / FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH);
|
||||
FfxUInt32x2 imageCoord = (gid * FfxUInt32x2(FFX_CACAO_BILATERAL_UPSCALE_WIDTH, FFX_CACAO_BILATERAL_UPSCALE_HEIGHT)) + bufferCoord - 2;
|
||||
|
||||
for (FfxInt32 i = 0; i < 3; ++i)
|
||||
{
|
||||
FfxFloat32x2 sampleLoc0 = (FfxFloat32x2(imageCoord / 2) + 0.5f) * SSAOBufferInverseDimensions();
|
||||
FfxFloat32x2 sampleLoc1 = sampleLoc0;
|
||||
switch ((imageCoord.y % 2) * 2 + (imageCoord.x % 2)) {
|
||||
case 0:
|
||||
sampleLoc1 -= 0.5f * SSAOBufferInverseDimensions();
|
||||
break;
|
||||
case 1:
|
||||
sampleLoc0.x += 0.5f * SSAOBufferInverseDimensions().x;
|
||||
sampleLoc1.y -= 0.5f * SSAOBufferInverseDimensions().y;
|
||||
break;
|
||||
case 2:
|
||||
sampleLoc0.y += 0.5f * SSAOBufferInverseDimensions().y;
|
||||
sampleLoc1.x -= 0.5f * SSAOBufferInverseDimensions().x;
|
||||
break;
|
||||
case 3:
|
||||
sampleLoc0 += 0.5f * SSAOBufferInverseDimensions();
|
||||
break;
|
||||
}
|
||||
|
||||
FfxFloat32 ssaoVal0 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc0, 0);
|
||||
FfxFloat32 ssaoVal1 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc1, 3);
|
||||
|
||||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2((imageCoord / 2) + DeinterleavedDepthBufferOffset());
|
||||
FfxUInt32 depthArrayBufferIndex = (imageCoord.y % 2) * 3;
|
||||
++imageCoord.x;
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal;
|
||||
|
||||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex);
|
||||
FfxFloat32 ssaoVal = (ssaoVal0 + ssaoVal1) * 0.5f;
|
||||
|
||||
bufferVal.packedDepths = ffxPackF16(FfxFloat16x2(depth, depth));
|
||||
bufferVal.packedSsaoVals = ffxPackF16(FfxFloat16x2(ssaoVal, ssaoVal));
|
||||
|
||||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal;
|
||||
}
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
FfxFloat32 depths[4];
|
||||
// load depths
|
||||
{
|
||||
FfxInt32x2 fullBufferCoord = FfxInt32x2(2 * tid);
|
||||
FfxInt32x2 fullDepthBufferCoord = fullBufferCoord + DepthBufferOffset();
|
||||
|
||||
FfxFloat32x4 screenSpaceDepths = FFX_CACAO_BilateralUpscale_LoadDepths(fullDepthBufferCoord);
|
||||
|
||||
depths[0] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.x);
|
||||
depths[1] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.y);
|
||||
depths[2] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.z);
|
||||
depths[3] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.w);
|
||||
}
|
||||
FfxFloat16x4 packedDepths = FfxFloat16x4(depths[0], depths[1], depths[2], depths[3]);
|
||||
|
||||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height);
|
||||
|
||||
FfxFloat16 epsilonWeight = FfxFloat16(1e-3f);
|
||||
FfxFloat16x2 nearestSsaoVals = ffxUnpackF16(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals);
|
||||
FfxFloat16x4 packedTotals = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
packedTotals.xy *= nearestSsaoVals;
|
||||
packedTotals.zw *= nearestSsaoVals;
|
||||
FfxFloat16x4 packedTotalWeights = epsilonWeight * FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma();
|
||||
FfxFloat16x2 packedDistSigma = FfxFloat16x2(1.0f / distanceSigma, 1.0f / distanceSigma);
|
||||
FfxFloat32 sigma = BilateralSigmaSquared();
|
||||
FfxFloat16x2 packedSigma = FfxFloat16x2(1.0f / sigma, 1.0f / sigma);
|
||||
|
||||
for (FfxInt32 x = -width; x <= width; ++x)
|
||||
{
|
||||
for (FfxInt32 y = -height; y <= height; ++y)
|
||||
{
|
||||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y);
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y];
|
||||
|
||||
FfxFloat16x2 u = FfxFloat16x2(x, x) - FfxFloat16x2(0.0f, 0.5f);
|
||||
FfxFloat16x2 v1 = FfxFloat16x2(y, y) - FfxFloat16x2(0.0f, 0.0f);
|
||||
FfxFloat16x2 v2 = FfxFloat16x2(y, y) - FfxFloat16x2(0.5f, 0.5f);
|
||||
u = u * u;
|
||||
v1 = v1 * v1;
|
||||
v2 = v2 * v2;
|
||||
|
||||
FfxFloat16x2 dist1 = u + v1;
|
||||
FfxFloat16x2 dist2 = u + v2;
|
||||
|
||||
FfxFloat16x2 wx1 = exp(-dist1 * packedSigma);
|
||||
FfxFloat16x2 wx2 = exp(-dist2 * packedSigma);
|
||||
|
||||
FfxFloat16x2 bufferPackedDepths = ffxUnpackF16(bufferVal.packedDepths);
|
||||
|
||||
FfxFloat16x2 diff1 = packedDepths.xy - bufferPackedDepths;
|
||||
FfxFloat16x2 diff2 = packedDepths.zw - bufferPackedDepths;
|
||||
diff1 *= diff1;
|
||||
diff2 *= diff2;
|
||||
|
||||
FfxFloat16x2 wy1 = exp(-diff1 * packedDistSigma);
|
||||
FfxFloat16x2 wy2 = exp(-diff2 * packedDistSigma);
|
||||
|
||||
FfxFloat16x2 weight1 = wx1 * wy1;
|
||||
FfxFloat16x2 weight2 = wx2 * wy2;
|
||||
|
||||
FfxFloat16x2 packedSsaoVals = ffxUnpackF16(bufferVal.packedSsaoVals);
|
||||
packedTotals.xy += packedSsaoVals * weight1;
|
||||
packedTotals.zw += packedSsaoVals * weight2;
|
||||
packedTotalWeights.xy += weight1;
|
||||
packedTotalWeights.zw += weight2;
|
||||
}
|
||||
}
|
||||
|
||||
FfxUInt32x2 outputCoord = 2 * tid;
|
||||
FfxFloat16x4 outputValues = packedTotals / packedTotalWeights;
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 0), outputValues.x); // totals[0] / totalWeights[0];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 0), outputValues.y); // totals[1] / totalWeights[1];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 1), outputValues.z); // totals[2] / totalWeights[2];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 1), outputValues.w); // totals[3] / totalWeights[3];
|
||||
}
|
||||
#else
|
||||
void FFX_CACAO_UpscaleBilateral5x5(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
const FfxInt32 width = 2, height = 2;
|
||||
|
||||
// fill in group shared buffer
|
||||
{
|
||||
FfxUInt32 threadNum = (gtid.y * FFX_CACAO_BILATERAL_UPSCALE_WIDTH + gtid.x) * 3;
|
||||
FfxUInt32x2 bufferCoord = FfxUInt32x2(threadNum % FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH, threadNum / FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH);
|
||||
FfxUInt32x2 imageCoord = (gid * FfxUInt32x2(FFX_CACAO_BILATERAL_UPSCALE_WIDTH, FFX_CACAO_BILATERAL_UPSCALE_HEIGHT)) + bufferCoord - 2;
|
||||
|
||||
for (FfxInt32 i = 0; i < 3; ++i)
|
||||
{
|
||||
FfxFloat32x2 sampleLoc0 = (FfxFloat32x2(imageCoord / 2) + 0.5f) * SSAOBufferInverseDimensions();
|
||||
FfxFloat32x2 sampleLoc1 = sampleLoc0;
|
||||
switch ((imageCoord.y % 2) * 2 + (imageCoord.x % 2)) {
|
||||
case 0:
|
||||
sampleLoc1 -= 0.5f * SSAOBufferInverseDimensions();
|
||||
break;
|
||||
case 1:
|
||||
sampleLoc0.x += 0.5f * SSAOBufferInverseDimensions().x;
|
||||
sampleLoc1.y -= 0.5f * SSAOBufferInverseDimensions().y;
|
||||
break;
|
||||
case 2:
|
||||
sampleLoc0.y += 0.5f * SSAOBufferInverseDimensions().y;
|
||||
sampleLoc1.x -= 0.5f * SSAOBufferInverseDimensions().x;
|
||||
break;
|
||||
case 3:
|
||||
sampleLoc0 += 0.5f * SSAOBufferInverseDimensions();
|
||||
break;
|
||||
}
|
||||
|
||||
FfxFloat32 ssaoVal0 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc0, 0);
|
||||
FfxFloat32 ssaoVal1 = FFX_CACAO_BilateralUpscale_SampleSSAOPoint(sampleLoc1, 3);
|
||||
|
||||
FfxUInt32x2 depthArrayBufferCoord = FfxUInt32x2((imageCoord / 2) + DeinterleavedDepthBufferOffset());
|
||||
FfxUInt32 depthArrayBufferIndex = (imageCoord.y % 2) * 3;
|
||||
++imageCoord.x;
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal;
|
||||
|
||||
FfxFloat32 depth = FFX_CACAO_BilateralUpscale_LoadDownscaledDepth(depthArrayBufferCoord, depthArrayBufferIndex);
|
||||
FfxFloat32 ssaoVal = (ssaoVal0 + ssaoVal1) * 0.5f;
|
||||
|
||||
bufferVal.packedDepths = ffxPackF32(FfxFloat32x2(depth, depth));
|
||||
bufferVal.packedSsaoVals = ffxPackF32(FfxFloat32x2(ssaoVal, ssaoVal));
|
||||
|
||||
s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x + i][bufferCoord.y] = bufferVal;
|
||||
}
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
FfxFloat32 depths[4];
|
||||
// load depths
|
||||
{
|
||||
FfxInt32x2 fullBufferCoord = FfxInt32x2(2 * tid);
|
||||
FfxInt32x2 fullDepthBufferCoord = fullBufferCoord + DepthBufferOffset();
|
||||
|
||||
FfxFloat32x4 screenSpaceDepths = FFX_CACAO_BilateralUpscale_LoadDepths(fullDepthBufferCoord);
|
||||
|
||||
depths[0] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.x);
|
||||
depths[1] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.y);
|
||||
depths[2] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.z);
|
||||
depths[3] = FFX_CACAO_ScreenSpaceToViewSpaceDepth(screenSpaceDepths.w);
|
||||
}
|
||||
FfxFloat32x4 packedDepths = FfxFloat32x4(depths[0], depths[1], depths[2], depths[3]);
|
||||
|
||||
FfxInt32x2 baseBufferCoord = FfxInt32x2(gtid) + FfxInt32x2(width, height);
|
||||
|
||||
FfxFloat32 epsilonWeight = FfxFloat32(1e-3f);
|
||||
FfxFloat32x2 nearestSsaoVals = ffxUnpackF32(s_FFX_CACAO_BilateralUpscaleBuffer[baseBufferCoord.x][baseBufferCoord.y].packedSsaoVals);
|
||||
FfxFloat32x4 packedTotals = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
packedTotals.xy *= nearestSsaoVals;
|
||||
packedTotals.zw *= nearestSsaoVals;
|
||||
FfxFloat32x4 packedTotalWeights = epsilonWeight * FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
FfxFloat32 distanceSigma = BilateralSimilarityDistanceSigma();
|
||||
FfxFloat32x2 packedDistSigma = FfxFloat32x2(1.0f / distanceSigma, 1.0f / distanceSigma);
|
||||
FfxFloat32 sigma = BilateralSigmaSquared();
|
||||
FfxFloat32x2 packedSigma = FfxFloat32x2(1.0f / sigma, 1.0f / sigma);
|
||||
|
||||
for (FfxInt32 x = -width; x <= width; ++x)
|
||||
{
|
||||
for (FfxInt32 y = -height; y <= height; ++y)
|
||||
{
|
||||
FfxInt32x2 bufferCoord = baseBufferCoord + FfxInt32x2(x, y);
|
||||
|
||||
FFX_CACAO_BilateralBufferVal bufferVal = s_FFX_CACAO_BilateralUpscaleBuffer[bufferCoord.x][bufferCoord.y];
|
||||
|
||||
FfxFloat32x2 u = FfxFloat32x2(x, x) - FfxFloat32x2(0.0f, 0.5f);
|
||||
FfxFloat32x2 v1 = FfxFloat32x2(y, y) - FfxFloat32x2(0.0f, 0.0f);
|
||||
FfxFloat32x2 v2 = FfxFloat32x2(y, y) - FfxFloat32x2(0.5f, 0.5f);
|
||||
u = u * u;
|
||||
v1 = v1 * v1;
|
||||
v2 = v2 * v2;
|
||||
|
||||
FfxFloat32x2 dist1 = u + v1;
|
||||
FfxFloat32x2 dist2 = u + v2;
|
||||
|
||||
FfxFloat32x2 wx1 = exp(-dist1 * packedSigma);
|
||||
FfxFloat32x2 wx2 = exp(-dist2 * packedSigma);
|
||||
|
||||
FfxFloat32x2 bufferPackedDepths = ffxUnpackF32(bufferVal.packedDepths);
|
||||
|
||||
FfxFloat32x2 diff1 = packedDepths.xy - bufferPackedDepths;
|
||||
FfxFloat32x2 diff2 = packedDepths.zw - bufferPackedDepths;
|
||||
diff1 *= diff1;
|
||||
diff2 *= diff2;
|
||||
|
||||
FfxFloat32x2 wy1 = exp(-diff1 * packedDistSigma);
|
||||
FfxFloat32x2 wy2 = exp(-diff2 * packedDistSigma);
|
||||
|
||||
FfxFloat32x2 weight1 = wx1 * wy1;
|
||||
FfxFloat32x2 weight2 = wx2 * wy2;
|
||||
|
||||
FfxFloat32x2 packedSsaoVals = ffxUnpackF32(bufferVal.packedSsaoVals);
|
||||
packedTotals.xy += packedSsaoVals * weight1;
|
||||
packedTotals.zw += packedSsaoVals * weight2;
|
||||
packedTotalWeights.xy += weight1;
|
||||
packedTotalWeights.zw += weight2;
|
||||
}
|
||||
}
|
||||
|
||||
FfxUInt32x2 outputCoord = 2 * tid;
|
||||
FfxFloat32x4 outputValues = packedTotals / packedTotalWeights;
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 0), outputValues.x); // totals[0] / totalWeights[0];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 0), outputValues.y); // totals[1] / totalWeights[1];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(0, 1), outputValues.z); // totals[2] / totalWeights[2];
|
||||
FFX_CACAO_BilateralUpscale_StoreOutput(outputCoord, FfxInt32x2(1, 1), outputValues.w); // totals[3] / totalWeights[3];
|
||||
}
|
||||
#endif //FFX_HALF
|
||||
|
||||
void FFX_CACAO_UpscaleBilateral5x5Pass(FfxUInt32x2 tid, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
#if FFX_CACAO_OPTION_APPLY_SMART
|
||||
FFX_CACAO_UpscaleBilateral5x5Smart(tid, gtid, gid);
|
||||
#else
|
||||
|
||||
#if FFX_HALF
|
||||
FFX_CACAO_UpscaleBilateral5x5Half(tid, gtid, gid);
|
||||
#else
|
||||
FFX_CACAO_UpscaleBilateral5x5NonSmart(tid, gtid, gid);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef FFX_CACAO_BILATERAL_UPSCALE_BUFFER_WIDTH
|
||||
#undef FFX_CACAO_BILATERAL_UPSCALE_BUFFER_HEIGHT
|
||||
104
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_utils.h
vendored
Normal file
104
manul/thirdparty/fsr2/include/FidelityFX/gpu/cacao/ffx_cacao_utils.h
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
// 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.
|
||||
|
||||
// packing/unpacking for edges; 2 bits per edge mean 4 gradient values (0, 0.33, 0.66, 1) for smoother transitions!
|
||||
FfxFloat32 FFX_CACAO_PackEdges(FfxFloat32x4 edgesLRTB)
|
||||
{
|
||||
edgesLRTB = round(ffxSaturate(edgesLRTB) * 3.05);
|
||||
return dot(edgesLRTB, FfxFloat32x4(64.0 / 255.0, 16.0 / 255.0, 4.0 / 255.0, 1.0 / 255.0));
|
||||
}
|
||||
|
||||
FfxFloat32x4 FFX_CACAO_UnpackEdges(FfxFloat32 _packedVal)
|
||||
{
|
||||
FfxUInt32 packedVal = FfxUInt32(_packedVal * 255.5);
|
||||
FfxFloat32x4 edgesLRTB;
|
||||
edgesLRTB.x = FfxFloat32((packedVal >> 6) & 0x03) / 3.0; // there's really no need for mask (as it's an 8 bit input) but I'll leave it in so it doesn't cause any trouble in the future
|
||||
edgesLRTB.y = FfxFloat32((packedVal >> 4) & 0x03) / 3.0;
|
||||
edgesLRTB.z = FfxFloat32((packedVal >> 2) & 0x03) / 3.0;
|
||||
edgesLRTB.w = FfxFloat32((packedVal >> 0) & 0x03) / 3.0;
|
||||
|
||||
return ffxSaturate(edgesLRTB + InvSharpness());
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_CACAO_ScreenSpaceToViewSpaceDepth(FfxFloat32 screenDepth)
|
||||
{
|
||||
FfxFloat32 depthLinearizeMul = DepthUnpackConsts().x;
|
||||
FfxFloat32 depthLinearizeAdd = DepthUnpackConsts().y;
|
||||
|
||||
return depthLinearizeMul * ffxInvertSafe(depthLinearizeAdd - screenDepth);
|
||||
}
|
||||
|
||||
FfxFloat32x4 FFX_CACAO_ScreenSpaceToViewSpaceDepth(FfxFloat32x4 screenDepth)
|
||||
{
|
||||
FfxFloat32 depthLinearizeMul = DepthUnpackConsts().x;
|
||||
FfxFloat32 depthLinearizeAdd = DepthUnpackConsts().y;
|
||||
|
||||
return depthLinearizeMul * ffxInvertSafe(depthLinearizeAdd - screenDepth);
|
||||
}
|
||||
|
||||
FfxFloat32x4 FFX_CACAO_CalculateEdges(const FfxFloat32 centerZ, const FfxFloat32 leftZ, const FfxFloat32 rightZ, const FfxFloat32 topZ, const FfxFloat32 bottomZ)
|
||||
{
|
||||
// slope-sensitive depth-based edge detection
|
||||
FfxFloat32x4 edgesLRTB = FfxFloat32x4(leftZ, rightZ, topZ, bottomZ) - centerZ;
|
||||
FfxFloat32x4 edgesLRTBSlopeAdjusted = edgesLRTB + edgesLRTB.yxwz;
|
||||
edgesLRTB = min(abs(edgesLRTB), abs(edgesLRTBSlopeAdjusted));
|
||||
return ffxSaturate((1.3 - edgesLRTB / (centerZ * 0.040)));
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_CACAO_NDCToViewSpace(FfxFloat32x2 pos, FfxFloat32 viewspaceDepth)
|
||||
{
|
||||
FfxFloat32x3 ret;
|
||||
|
||||
ret.xy = (NDCToViewMul() * pos.xy + NDCToViewAdd()) * viewspaceDepth;
|
||||
|
||||
ret.z = viewspaceDepth;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_CACAO_DepthBufferUVToViewSpace(FfxFloat32x2 pos, FfxFloat32 viewspaceDepth)
|
||||
{
|
||||
FfxFloat32x3 ret;
|
||||
ret.xy = (DepthBufferUVToViewMul() * pos.xy + DepthBufferUVToViewAdd()) * viewspaceDepth;
|
||||
ret.z = viewspaceDepth;
|
||||
return ret;
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_CACAO_CalculateNormal(const FfxFloat32x4 edgesLRTB, FfxFloat32x3 pixCenterPos, FfxFloat32x3 pixLPos, FfxFloat32x3 pixRPos, FfxFloat32x3 pixTPos, FfxFloat32x3 pixBPos)
|
||||
{
|
||||
// Get this pixel's viewspace normal
|
||||
FfxFloat32x4 acceptedNormals = FfxFloat32x4(edgesLRTB.x*edgesLRTB.z, edgesLRTB.z*edgesLRTB.y, edgesLRTB.y*edgesLRTB.w, edgesLRTB.w*edgesLRTB.x);
|
||||
|
||||
pixLPos = normalize(pixLPos - pixCenterPos);
|
||||
pixRPos = normalize(pixRPos - pixCenterPos);
|
||||
pixTPos = normalize(pixTPos - pixCenterPos);
|
||||
pixBPos = normalize(pixBPos - pixCenterPos);
|
||||
|
||||
FfxFloat32x3 pixelNormal = FfxFloat32x3(0, 0, -0.0005);
|
||||
pixelNormal += (acceptedNormals.x) * cross(pixLPos, pixTPos);
|
||||
pixelNormal += (acceptedNormals.y) * cross(pixTPos, pixRPos);
|
||||
pixelNormal += (acceptedNormals.z) * cross(pixRPos, pixBPos);
|
||||
pixelNormal += (acceptedNormals.w) * cross(pixBPos, pixLPos);
|
||||
pixelNormal = normalize(pixelNormal);
|
||||
|
||||
return pixelNormal;
|
||||
}
|
||||
47
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/CMakeCompileCASShaders.txt
vendored
Normal file
47
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/CMakeCompileCASShaders.txt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# 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(CAS_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(CAS_PERMUTATION_ARGS
|
||||
-DFFX_CAS_OPTION_SHARPEN_ONLY={0,1}
|
||||
-DFFX_CAS_COLOR_SPACE_CONVERSION={0,1,2,3,4})
|
||||
|
||||
set(CAS_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/cas")
|
||||
|
||||
if (NOT CAS_SHADER_EXT)
|
||||
set(CAS_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB CAS_SHADERS
|
||||
"shaders/cas/ffx_cas_sharpen_pass.${CAS_SHADER_EXT}")
|
||||
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${CAS_BASE_ARGS}" "${CAS_API_BASE_ARGS}" "${CAS_PERMUTATION_ARGS}" "${CAS_INCLUDE_ARGS}"
|
||||
"${CAS_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" CAS_PERMUTATION_OUTPUTS)
|
||||
|
||||
# add the header files they generate to the main list of dependencies
|
||||
add_shader_output("${CAS_PERMUTATION_OUTPUTS}")
|
||||
1271
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas.h
vendored
Normal file
1271
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
184
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_callbacks_glsl.h
vendored
Normal file
184
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// 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_cas_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core.h"
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(CAS_BIND_CB_CAS)
|
||||
layout(set = 0, binding = CAS_BIND_CB_CAS, std140) uniform cbCAS_t
|
||||
{
|
||||
FfxUInt32x4 const0;
|
||||
FfxUInt32x4 const1;
|
||||
}
|
||||
cbCAS;
|
||||
#endif
|
||||
|
||||
FfxUInt32x4 Const0()
|
||||
{
|
||||
#if defined(CAS_BIND_CB_CAS)
|
||||
return cbCAS.const0;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32x4 Const1()
|
||||
{
|
||||
#if defined(CAS_BIND_CB_CAS)
|
||||
return cbCAS.const1;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
layout(set = 0, binding = 1000) uniform sampler s_LinearClamp;
|
||||
|
||||
// SRVs
|
||||
#if defined CAS_BIND_SRV_INPUT_COLOR
|
||||
layout(set = 0, binding = CAS_BIND_SRV_INPUT_COLOR) uniform texture2D r_input_color;
|
||||
#endif
|
||||
|
||||
// UAV declarations
|
||||
#if defined CAS_BIND_UAV_OUTPUT_COLOR
|
||||
layout(set = 0, binding = CAS_BIND_UAV_OUTPUT_COLOR, rgba16) uniform image2D rw_output_color;
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
FfxFloat16x3 casLoadHalf(FFX_PARAMETER_IN FfxInt16x2 position)
|
||||
{
|
||||
#if defined(CAS_BIND_SRV_INPUT_COLOR)
|
||||
return FfxFloat16x3(texelFetch(r_input_color, FfxInt32x2(position), 0).rgb);
|
||||
#else
|
||||
return FfxFloat16x3(0.f);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Transform input from the load into a linear color space between 0 and 1.
|
||||
void casInputHalf(FFX_PARAMETER_INOUT FfxFloat16x2 red, FFX_PARAMETER_INOUT FfxFloat16x2 green, FFX_PARAMETER_INOUT FfxFloat16x2 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red *= red;
|
||||
green *= green;
|
||||
blue *= blue;
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxLinearFromGammaHalf(red, FfxFloat16(2.2f));
|
||||
green = ffxLinearFromGammaHalf(green, FfxFloat16(2.2f));
|
||||
blue = ffxLinearFromGammaHalf(blue, FfxFloat16(2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxLinearFromSrgbHalf(red);
|
||||
green = ffxLinearFromSrgbHalf(green);
|
||||
blue = ffxLinearFromSrgbHalf(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
void casOutputHalf(FFX_PARAMETER_INOUT FfxFloat16x2 red, FFX_PARAMETER_INOUT FfxFloat16x2 green, FFX_PARAMETER_INOUT FfxFloat16x2 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red = ffxSqrt(red);
|
||||
green = ffxSqrt(green);
|
||||
blue = ffxSqrt(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxGammaFromLinearHalf(red, FfxFloat16(1/2.2f));
|
||||
green = ffxGammaFromLinearHalf(green, FfxFloat16(1/2.2f));
|
||||
blue = ffxGammaFromLinearHalf(blue, FfxFloat16(1/2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
red = ffxSrgbFromLinearHalf(red);
|
||||
green = ffxSrgbFromLinearHalf(green);
|
||||
blue = ffxSrgbFromLinearHalf(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxSrgbFromLinearHalf(red);
|
||||
green = ffxSrgbFromLinearHalf(green);
|
||||
blue = ffxSrgbFromLinearHalf(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
FfxFloat32x3 casLoad(FFX_PARAMETER_IN FfxInt32x2 position)
|
||||
{
|
||||
#if defined(CAS_BIND_SRV_INPUT_COLOR)
|
||||
return texelFetch(r_input_color, position, 0).rgb;
|
||||
#else
|
||||
return FfxFloat32x3(0.f);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Transform input from the load into a linear color space between 0 and 1.
|
||||
void casInput(FFX_PARAMETER_INOUT FfxFloat32 red, FFX_PARAMETER_INOUT FfxFloat32 green, FFX_PARAMETER_INOUT FfxFloat32 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red *= red;
|
||||
green *= green;
|
||||
blue *= blue;
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxLinearFromGamma(red, FfxFloat32(2.2f));
|
||||
green = ffxLinearFromGamma(green, FfxFloat32(2.2f));
|
||||
blue = ffxLinearFromGamma(blue, FfxFloat32(2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxLinearFromSrgb(red);
|
||||
green = ffxLinearFromSrgb(green);
|
||||
blue = ffxLinearFromSrgb(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
void casOutput(FFX_PARAMETER_INOUT FfxFloat32 red, FFX_PARAMETER_INOUT FfxFloat32 green, FFX_PARAMETER_INOUT FfxFloat32 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red = ffxSqrt(red);
|
||||
green = ffxSqrt(green);
|
||||
blue = ffxSqrt(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxGammaFromLinear(red, FfxFloat32(1/2.2f));
|
||||
green = ffxGammaFromLinear(green, FfxFloat32(1/2.2f));
|
||||
blue = ffxGammaFromLinear(blue, FfxFloat32(1/2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
red = ffxSrgbFromLinear(red);
|
||||
green = ffxSrgbFromLinear(green);
|
||||
blue = ffxSrgbFromLinear(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxSrgbFromLinear(red);
|
||||
green = ffxSrgbFromLinear(green);
|
||||
blue = ffxSrgbFromLinear(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // FFX_HALF
|
||||
|
||||
void casStoreOutput(FfxInt32x2 iPxPos, FfxFloat32x4 fColor)
|
||||
{
|
||||
#if defined(CAS_BIND_UAV_OUTPUT_COLOR)
|
||||
imageStore(rw_output_color, iPxPos, fColor);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
226
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_callbacks_hlsl.h
vendored
Normal file
226
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
// 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_cas_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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
|
||||
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
|
||||
#define DECLARE_CB_REGISTER(regIndex) b##regIndex
|
||||
#define FFX_CAS_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_CAS_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_CAS_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(CAS_BIND_CB_CAS)
|
||||
cbuffer cbCAS : FFX_CAS_DECLARE_CB(CAS_BIND_CB_CAS)
|
||||
{
|
||||
FfxUInt32x4 const0;
|
||||
FfxUInt32x4 const1;
|
||||
#define FFX_CAS_CONSTANT_BUFFER_1_SIZE 8 // Number of 32-bit values. This must be kept in sync with the cbCAS size.
|
||||
};
|
||||
#else
|
||||
#define const0 0
|
||||
#define const1 0
|
||||
#endif
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#define FFX_CAS_ROOTSIG_STRINGIFY(p) FFX_CAS_ROOTSIG_STR(p)
|
||||
#define FFX_CAS_ROOTSIG_STR(p) #p
|
||||
#define FFX_CAS_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CAS_ROOTSIG_STRINGIFY(FFX_CAS_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CAS_ROOTSIG_STRINGIFY(FFX_CAS_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)" )]
|
||||
|
||||
#if defined(FFX_CAS_EMBED_ROOTSIG)
|
||||
#define FFX_CAS_EMBED_ROOTSIG_CONTENT FFX_CAS_ROOTSIG
|
||||
#else
|
||||
#define FFX_CAS_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_CAS_EMBED_ROOTSIG
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
|
||||
FfxUInt32x4 Const0()
|
||||
{
|
||||
#if defined(CAS_BIND_CB_CAS)
|
||||
return const0;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32x4 Const1()
|
||||
{
|
||||
#if defined(CAS_BIND_CB_CAS)
|
||||
return const1;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
SamplerState s_LinearClamp : register(s0);
|
||||
|
||||
// SRVs
|
||||
#if defined(CAS_BIND_SRV_INPUT_COLOR)
|
||||
Texture2D<FfxFloat32x4> r_input_color : FFX_CAS_DECLARE_SRV(CAS_BIND_SRV_INPUT_COLOR);
|
||||
#endif
|
||||
|
||||
// UAV declarations
|
||||
#if defined(CAS_BIND_UAV_OUTPUT_COLOR)
|
||||
RWTexture2D<FfxFloat32x4> rw_output_color : FFX_CAS_DECLARE_UAV(CAS_BIND_UAV_OUTPUT_COLOR);
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
FfxFloat16x3 casLoadHalf(FFX_PARAMETER_IN FfxInt16x2 position)
|
||||
{
|
||||
#if defined(CAS_BIND_SRV_INPUT_COLOR)
|
||||
return FfxFloat16x3(r_input_color.Load(FfxInt32x3(position, 0)).rgb);
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Transform input from the load into a linear color space between 0 and 1.
|
||||
void casInputHalf(FFX_PARAMETER_INOUT FfxFloat16x2 red, FFX_PARAMETER_INOUT FfxFloat16x2 green, FFX_PARAMETER_INOUT FfxFloat16x2 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red *= red;
|
||||
green *= green;
|
||||
blue *= blue;
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxLinearFromGammaHalf(red, FfxFloat16(2.2f));
|
||||
green = ffxLinearFromGammaHalf(green, FfxFloat16(2.2f));
|
||||
blue = ffxLinearFromGammaHalf(blue, FfxFloat16(2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxLinearFromSrgbHalf(red);
|
||||
green = ffxLinearFromSrgbHalf(green);
|
||||
blue = ffxLinearFromSrgbHalf(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
void casOutputHalf(FFX_PARAMETER_INOUT FfxFloat16x2 red, FFX_PARAMETER_INOUT FfxFloat16x2 green, FFX_PARAMETER_INOUT FfxFloat16x2 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red = ffxSqrt(red);
|
||||
green = ffxSqrt(green);
|
||||
blue = ffxSqrt(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxGammaFromLinearHalf(red, FfxFloat16(1/2.2f));
|
||||
green = ffxGammaFromLinearHalf(green, FfxFloat16(1/2.2f));
|
||||
blue = ffxGammaFromLinearHalf(blue, FfxFloat16(1/2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
red = ffxSrgbFromLinearHalf(red);
|
||||
green = ffxSrgbFromLinearHalf(green);
|
||||
blue = ffxSrgbFromLinearHalf(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxSrgbFromLinearHalf(red);
|
||||
green = ffxSrgbFromLinearHalf(green);
|
||||
blue = ffxSrgbFromLinearHalf(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
FfxFloat32x3 casLoad(FFX_PARAMETER_IN FfxInt32x2 position)
|
||||
{
|
||||
#if defined(CAS_BIND_SRV_INPUT_COLOR)
|
||||
return r_input_color.Load(FfxInt32x3(position, 0)).rgb;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Transform input from the load into a linear color space between 0 and 1.
|
||||
void casInput(FFX_PARAMETER_INOUT FfxFloat32 red, FFX_PARAMETER_INOUT FfxFloat32 green, FFX_PARAMETER_INOUT FfxFloat32 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red *= red;
|
||||
green *= green;
|
||||
blue *= blue;
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxLinearFromGamma(red, FfxFloat32(2.2f));
|
||||
green = ffxLinearFromGamma(green, FfxFloat32(2.2f));
|
||||
blue = ffxLinearFromGamma(blue, FfxFloat32(2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxLinearFromSrgb(red);
|
||||
green = ffxLinearFromSrgb(green);
|
||||
blue = ffxLinearFromSrgb(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
void casOutput(FFX_PARAMETER_INOUT FfxFloat32 red, FFX_PARAMETER_INOUT FfxFloat32 green, FFX_PARAMETER_INOUT FfxFloat32 blue)
|
||||
{
|
||||
#if FFX_CAS_COLOR_SPACE_CONVERSION == 1 // gamma 2.0
|
||||
red = ffxSqrt(red);
|
||||
green = ffxSqrt(green);
|
||||
blue = ffxSqrt(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 2 // gamma 2.2
|
||||
red = ffxGammaFromLinear(red, FfxFloat32(1/2.2f));
|
||||
green = ffxGammaFromLinear(green, FfxFloat32(1/2.2f));
|
||||
blue = ffxGammaFromLinear(blue, FfxFloat32(1/2.2f));
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 3 // sRGB output (auto-degamma'd on sampler read)
|
||||
red = ffxSrgbFromLinear(red);
|
||||
green = ffxSrgbFromLinear(green);
|
||||
blue = ffxSrgbFromLinear(blue);
|
||||
#elif FFX_CAS_COLOR_SPACE_CONVERSION == 4 // sRGB input/output
|
||||
red = ffxSrgbFromLinear(red);
|
||||
green = ffxSrgbFromLinear(green);
|
||||
blue = ffxSrgbFromLinear(blue);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // FFX_HALF
|
||||
|
||||
void casStoreOutput(FfxInt32x2 iPxPos, FfxFloat32x4 fColor)
|
||||
{
|
||||
#if defined(CAS_BIND_UAV_OUTPUT_COLOR)
|
||||
rw_output_color[iPxPos] = fColor;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
41
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_resources.h
vendored
Normal file
41
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_resources.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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_CAS_RESOURCES_H
|
||||
#define FFX_CAS_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#define FFX_CAS_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_CAS_RESOURCE_IDENTIFIER_INPUT_COLOR 1
|
||||
#define FFX_CAS_RESOURCE_IDENTIFIER_OUTPUT_COLOR 2
|
||||
|
||||
#define FFX_CAS_RESOURCE_IDENTIFIER_COUNT 3
|
||||
|
||||
// CBV resource definitions
|
||||
#define FFX_CAS_CONSTANTBUFFER_IDENTIFIER_CAS 0
|
||||
|
||||
#define FFX_CAS_CONSTANTBUFFER_IDENTIFIER_COUNT 1
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif // FFX_CAS_RESOURCES_H
|
||||
89
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_sharpen.h
vendored
Normal file
89
manul/thirdparty/fsr2/include/FidelityFX/gpu/cas/ffx_cas_sharpen.h
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// 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_core.h"
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#define FFX_CAS_PACKED_ONLY 1
|
||||
|
||||
#endif // FFX_HALF
|
||||
|
||||
#include "cas/ffx_cas.h"
|
||||
|
||||
void Sharpen(FfxUInt32x3 LocalThreadId, FfxUInt32x3 WorkGroupId, FfxUInt32x3 Dtid)
|
||||
{
|
||||
// Do remapping of local xy in workgroup for a more PS-like swizzle pattern.
|
||||
FfxUInt32x2 gxy = ffxRemapForQuad(LocalThreadId.x) + FfxUInt32x2(WorkGroupId.x << 4u, WorkGroupId.y << 4u);
|
||||
|
||||
FfxBoolean sharpenOnly;
|
||||
#if FFX_CAS_OPTION_SHARPEN_ONLY
|
||||
sharpenOnly = true;
|
||||
#else
|
||||
sharpenOnly = false;
|
||||
#endif // FFX_CAS_OPTION_SHARPEN_ONLY
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
// Filter.
|
||||
FfxFloat16x4 c0, c1;
|
||||
FfxFloat16x2 cR, cG, cB;
|
||||
|
||||
ffxCasFilterHalf(cR, cG, cB, gxy, Const0(), Const1(), sharpenOnly);
|
||||
casOutputHalf(cR, cG, cB);
|
||||
ffxCasDepackHalf(c0, c1, cR, cG, cB);
|
||||
casStoreOutput(FfxInt32x2(gxy), FfxFloat32x4(c0));
|
||||
casStoreOutput(FfxInt32x2(gxy) + FfxInt32x2(8, 0), FfxFloat32x4(c1));
|
||||
gxy.y += 8u;
|
||||
|
||||
ffxCasFilterHalf(cR, cG, cB, gxy, Const0(), Const1(), sharpenOnly);
|
||||
casOutputHalf(cR, cG, cB);
|
||||
ffxCasDepackHalf(c0, c1, cR, cG, cB);
|
||||
casStoreOutput(FfxInt32x2(gxy), FfxFloat32x4(c0));
|
||||
casStoreOutput(FfxInt32x2(gxy) + FfxInt32x2(8, 0), FfxFloat32x4(c1));
|
||||
|
||||
#else
|
||||
|
||||
// Filter.
|
||||
FfxFloat32x3 c;
|
||||
|
||||
ffxCasFilter(c.r, c.g, c.b, gxy, Const0(), Const1(), sharpenOnly);
|
||||
casOutput(c.r, c.g, c.b);
|
||||
casStoreOutput(FfxInt32x2(gxy), FfxFloat32x4(c, 1));
|
||||
gxy.x += 8u;
|
||||
|
||||
ffxCasFilter(c.r, c.g, c.b, gxy, Const0(), Const1(), sharpenOnly);
|
||||
casOutput(c.r, c.g, c.b);
|
||||
casStoreOutput(FfxInt32x2(gxy), FfxFloat32x4(c, 1));
|
||||
gxy.y += 8u;
|
||||
|
||||
ffxCasFilter(c.r, c.g, c.b, gxy, Const0(), Const1(), sharpenOnly);
|
||||
casOutput(c.r, c.g, c.b);
|
||||
casStoreOutput(FfxInt32x2(gxy), FfxFloat32x4(c, 1));
|
||||
gxy.x -= 8u;
|
||||
|
||||
ffxCasFilter(c.r, c.g, c.b, gxy, Const0(), Const1(), sharpenOnly);
|
||||
casOutput(c.r, c.g, c.b);
|
||||
casStoreOutput(FfxInt32x2(gxy), FfxFloat32x4(c, 1));
|
||||
|
||||
#endif // FFX_HALF
|
||||
}
|
||||
49
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/CMakeCompileClassifierShaders.txt
vendored
Normal file
49
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/CMakeCompileClassifierShaders.txt
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# 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(CLASSIFIER_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(CLASSIFIER_PERMUTATION_ARGS
|
||||
-DFFX_CLASSIFIER_OPTION_INVERTED_DEPTH={0,1}
|
||||
-DFFX_CLASSIFIER_OPTION_CLASSIFIER_MODE={0,1}
|
||||
)
|
||||
|
||||
set(CLASSIFIER_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/classifier")
|
||||
|
||||
if (NOT CLASSIFIER_SHADER_EXT)
|
||||
set(CLASSIFIER_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB CLASSIFIER_SHADERS
|
||||
"shaders/classifier/ffx_classifier_shadows_pass.${CLASSIFIER_SHADER_EXT}"
|
||||
"shaders/classifier/ffx_classifier_reflections_pass.${CLASSIFIER_SHADER_EXT}")
|
||||
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${CLASSIFIER_BASE_ARGS}" "${CLASSIFIER_API_BASE_ARGS}" "${CLASSIFIER_PERMUTATION_ARGS}" "${CLASSIFIER_INCLUDE_ARGS}"
|
||||
"${CLASSIFIER_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" CLASSIFIER_PERMUTATION_OUTPUTS)
|
||||
|
||||
# add the header files they generate to the main list of dependencies
|
||||
add_shader_output("${CLASSIFIER_PERMUTATION_OUTPUTS}")
|
||||
102
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_common.h
vendored
Normal file
102
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_common.h
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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.
|
||||
|
||||
#define TILE_SIZE_X 8
|
||||
#define TILE_SIZE_Y 4
|
||||
#define k_pushOff 4e-2f
|
||||
#define k_tileSize FfxUInt32x2(TILE_SIZE_X, TILE_SIZE_Y)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// I/O Structures
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
struct Tile
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxUInt16x2 location;
|
||||
#else
|
||||
FfxUInt32x2 location; // Dead code, f32 not supported
|
||||
#endif
|
||||
FfxUInt32 mask;
|
||||
|
||||
FfxFloat32 minT;
|
||||
FfxFloat32 maxT;
|
||||
};
|
||||
|
||||
Tile TileCreate(const FfxUInt32x2 id)
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxUInt16x2 f16ID = FfxUInt16x2(FfxUInt16(id.x), FfxUInt16(id.y));
|
||||
Tile t = { f16ID, 0, k_pushOff, FFX_POSITIVE_INFINITY_FLOAT }; // skyHeight
|
||||
#else
|
||||
Tile t = { id, 0, k_pushOff, FFX_POSITIVE_INFINITY_FLOAT }; //skyHeight
|
||||
#endif
|
||||
return t;
|
||||
}
|
||||
|
||||
FfxUInt32x4 TileToUint(const Tile t)
|
||||
{
|
||||
const FfxUInt32x4 ui = FfxUInt32x4((FfxUInt32(t.location.y) << 16) | FfxUInt32(t.location.x), t.mask, ffxAsUInt32(t.minT), ffxAsUInt32(t.maxT));
|
||||
return ui;
|
||||
}
|
||||
|
||||
Tile TileFromUint(const FfxUInt32x4 ui)
|
||||
{
|
||||
#if FFX_HALF
|
||||
FfxUInt16x2 id = FfxUInt16x2(ui.x & 0xffff, (ui.x >> 16) & 0xffff);
|
||||
#else
|
||||
FfxUInt32x2 id;
|
||||
#endif
|
||||
Tile t = { id, ui.y, ffxAsFloat(ui.z), ffxAsFloat(ui.w) };
|
||||
return t;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// helper functions
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
FfxUInt32 LaneIdToBitShift(FfxUInt32x2 localID)
|
||||
{
|
||||
return localID.y * TILE_SIZE_X + localID.x;
|
||||
}
|
||||
|
||||
FfxUInt32 BoolToWaveMask(FfxBoolean b, FfxUInt32x2 localID)
|
||||
{
|
||||
const FfxUInt32 value = FfxUInt32(b) << LaneIdToBitShift(localID);
|
||||
return ffxWaveOr(value);
|
||||
}
|
||||
|
||||
FfxBoolean WaveMaskToBool(FfxUInt32 mask, FfxUInt32x2 localID)
|
||||
{
|
||||
return FfxBoolean((FfxUInt32(1) << LaneIdToBitShift(localID)) & mask);
|
||||
}
|
||||
|
||||
|
||||
#define k_pi 3.1415926535897932384f
|
||||
#define k_2pi 2.0f * k_pi
|
||||
#define k_pi_over_2 0.5f * k_pi
|
||||
|
||||
// made using a modified version of https://www.asawicki.info/news_952_poisson_disc_generator
|
||||
#define k_poissonDiscSampleCountLow 8
|
||||
#define k_poissonDiscSampleCountMid 16
|
||||
#define k_poissonDiscSampleCountHigh 24
|
||||
#define k_poissonDiscSampleCountUltra 32
|
||||
378
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections.h
vendored
Normal file
378
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections.h
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
// 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.
|
||||
|
||||
#define TILE_CLASS_FULL_SW 0
|
||||
#define TILE_CLASS_HALF_SW 1
|
||||
#define TILE_CLASS_FULL_HW 2
|
||||
|
||||
#define FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
#include "ffx_classifier_reflections_common.h"
|
||||
|
||||
FfxFloat32x2 Hash22(FfxFloat32x2 p)
|
||||
{
|
||||
FfxFloat32x3 p3 = ffxFract(FfxFloat32x3(p.xyx) * FfxFloat32x3(.1031, .1030, .0973));
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
return ffxFract((p3.xx + p3.yz) * p3.zy);
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetRandom(FfxUInt32x2 index)
|
||||
{
|
||||
FfxFloat32 v = 0.152f;
|
||||
FfxFloat32x2 pos = (FfxFloat32x2(index) * v + FfxFloat32(FrameIndex()) / 60.0f * 1500.0f + 50.0f);
|
||||
return Hash22(pos);
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetRandomLastFrame(FfxUInt32x2 index)
|
||||
{
|
||||
FfxFloat32 v = 0.152f;
|
||||
FfxFloat32x2 pos = (FfxFloat32x2(index) * v + FfxFloat32(FrameIndex() - 1) / 60.0f * 1500.0f + 50.0f);
|
||||
return Hash22(pos);
|
||||
}
|
||||
|
||||
FfxBoolean IsSW(FfxFloat32 hitcounter, FfxFloat32 misscounter, FfxFloat32 rnd)
|
||||
{
|
||||
// Turn a random tile full hybrid once in a while to get the opportunity for testing HiZ traversal
|
||||
return rnd <= (+HybridSpawnRate() + hitcounter - misscounter * HybridMissWeight());
|
||||
}
|
||||
|
||||
FfxBoolean IsConverged(FfxUInt32x2 pixel_coordinate, FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat32x2 motion_vector = LoadMotionVector(FfxInt32x2(pixel_coordinate));
|
||||
;
|
||||
return SampleVarianceHistory(uv - motion_vector) < VRTVarianceThreshold();
|
||||
}
|
||||
|
||||
// In case no ray is traced we need to clear the buffers
|
||||
void FillEnvironment(FfxUInt32x2 ray_coord, FfxFloat32 factor)
|
||||
{
|
||||
// Fall back to the environment probe
|
||||
FfxUInt32x2 screen_size = FfxUInt32x2(ReflectionWidth(), ReflectionHeight());
|
||||
FfxFloat32x2 uv = (ray_coord + 0.5) * InverseRenderSize();
|
||||
FfxFloat32x3 world_space_normal = LoadWorldSpaceNormal(FfxInt32x2(ray_coord));
|
||||
FfxFloat32 roughness = LoadRoughnessFromMaterialParametersInput(FfxUInt32x3(ray_coord, 0));
|
||||
FfxFloat32 z = GetInputDepth(ray_coord);
|
||||
FfxFloat32x3 screen_uv_space_ray_origin = FfxFloat32x3(uv, z);
|
||||
FfxFloat32x3 view_space_ray = ScreenSpaceToViewSpace(screen_uv_space_ray_origin);
|
||||
FfxFloat32x3 view_space_ray_direction = normalize(view_space_ray);
|
||||
FfxFloat32x3 view_space_surface_normal = FFX_MATRIX_MULTIPLY(ViewMatrix(), FfxFloat32x4(world_space_normal, 0)).xyz;
|
||||
FfxFloat32x3 view_space_reflected_direction = reflect(view_space_ray_direction, view_space_surface_normal);
|
||||
FfxFloat32x3 world_space_reflected_direction = FFX_MATRIX_MULTIPLY(InvView(), FfxFloat32x4(view_space_reflected_direction, 0)).xyz;
|
||||
FfxFloat32x3 world_space_ray_origin = FFX_MATRIX_MULTIPLY(InvView(), FfxFloat32x4(view_space_ray, 1)).xyz;
|
||||
|
||||
FfxFloat32x3 env_sample = SampleEnvironmentMap(world_space_reflected_direction, sqrt(roughness));
|
||||
|
||||
if (!any(isnan(env_sample)))
|
||||
StoreRadiance(ray_coord, env_sample.xyzz * factor);
|
||||
else
|
||||
StoreRadiance(ray_coord, (0.0f).xxxx);
|
||||
}
|
||||
|
||||
void ZeroBuffers(FfxUInt32x2 dispatch_thread_id)
|
||||
{
|
||||
StoreRadiance(dispatch_thread_id, (0.0f).xxxx);
|
||||
}
|
||||
|
||||
FfxFloat32x2 GetSurfaceReprojection(FfxFloat32x2 uv, FfxFloat32x2 motion_vector)
|
||||
{
|
||||
// Reflector position reprojection
|
||||
FfxFloat32x2 history_uv = uv - motion_vector;
|
||||
return history_uv;
|
||||
}
|
||||
|
||||
FfxBoolean IsBaseRay(FfxUInt32x2 dispatch_thread_id, FfxUInt32 samples_per_quad)
|
||||
{
|
||||
switch (samples_per_quad)
|
||||
{
|
||||
case 1:
|
||||
return ((dispatch_thread_id.x & 1) | (dispatch_thread_id.y & 1)) == 0; // Deactivates 3 out of 4 rays
|
||||
case 2:
|
||||
return (dispatch_thread_id.x & 1) == (dispatch_thread_id.y & 1); // Deactivates 2 out of 4 rays. Keeps diagonal.
|
||||
default: // case 4:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 g_TileCount;
|
||||
FFX_GROUPSHARED FfxInt32 g_TileClass;
|
||||
FFX_GROUPSHARED FfxUInt32 g_SWCount;
|
||||
FFX_GROUPSHARED FfxUInt32 g_SWCountTotal;
|
||||
FFX_GROUPSHARED FfxUInt32 g_base_ray_index_sw;
|
||||
|
||||
void ClassifyTiles(FfxUInt32x2 dispatch_thread_id,
|
||||
FfxUInt32x2 group_thread_id,
|
||||
FfxFloat32 roughness,
|
||||
FfxFloat32x3 view_space_surface_normal,
|
||||
FfxFloat32 depth,
|
||||
FfxInt32x2 screen_size,
|
||||
FfxUInt32 samples_per_quad,
|
||||
FfxBoolean enable_temporal_variance_guided_tracing,
|
||||
FfxBoolean enable_hitcounter,
|
||||
FfxBoolean enable_screen_space_tracing,
|
||||
FfxBoolean enable_hw_ray_tracing)
|
||||
{
|
||||
FfxUInt32 flat_group_thread_id = group_thread_id.x + group_thread_id.y * 8;
|
||||
FfxBoolean is_first_lane_of_wave = ffxWaveIsFirstLane();
|
||||
|
||||
if (group_thread_id.x == 0 && group_thread_id.y == 0)
|
||||
{
|
||||
// Initialize group shared variables
|
||||
g_TileCount = 0;
|
||||
g_SWCount = 0;
|
||||
g_SWCountTotal = 0;
|
||||
g_base_ray_index_sw = 0;
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
// Initialize per 8x8 tile hit counter
|
||||
if (enable_hitcounter)
|
||||
{
|
||||
// In case we do hybrid
|
||||
if (enable_screen_space_tracing && enable_hw_ray_tracing)
|
||||
{
|
||||
// Feedback counters
|
||||
// See Intersect.hlsl
|
||||
FfxUInt32 hitcounter = 0;
|
||||
|
||||
// Use surface motion vectors of one of the 8x8 pixels in the tile to reproject statistics from the previous frame
|
||||
// Helps a lot in movement to sustain temoporal coherence
|
||||
#define FFX_CLASSIFIER_CLASSIFICATION_REPROJECT_HITCOUNTER
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_REPROJECT_HITCOUNTER
|
||||
{
|
||||
// Grab motion vector from a random point in the subgroup
|
||||
FfxFloat32x2 xi = GetRandom(dispatch_thread_id.xy / 8);
|
||||
FfxInt32x2 mix = FfxInt32x2(xi * 8.0f);
|
||||
FfxFloat32x2 motion_vector = LoadMotionVector(FfxInt32x2(dispatch_thread_id) + mix);
|
||||
FfxFloat32x2 uv8 = (FfxFloat32x2(dispatch_thread_id.xy + mix)) / FFX_DNSR_Reflections_RoundUp8(screen_size);
|
||||
FfxFloat32x2 surface_reprojection_uv = GetSurfaceReprojection(uv8, motion_vector);
|
||||
hitcounter = LoadHitCounterHistory(FfxUInt32x2(surface_reprojection_uv * (FFX_DNSR_Reflections_RoundUp8(screen_size) / 8)));
|
||||
}
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_REPROJECT_HITCOUNTER
|
||||
|
||||
// Use 3x3 region to grab the biggest success rate and create a safe band of hybrid rays to hide artefacts in movements
|
||||
#define FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
FfxUInt32 same_pixel_hitcounter = 0;
|
||||
// We need a safe band for some geometry not in the BVH to avoid fireflies
|
||||
const FfxInt32 radius = 1;
|
||||
for (FfxInt32 y = -radius; y <= radius; y++)
|
||||
{
|
||||
for (FfxInt32 x = -radius; x <= radius; x++)
|
||||
{
|
||||
FfxUInt32 pt = LoadHitCounterHistory(dispatch_thread_id.xy / 8 + FfxInt32x2(x, y));
|
||||
if (FFX_Hitcounter_GetSWHits(pt) > FFX_Hitcounter_GetSWHits(same_pixel_hitcounter))
|
||||
same_pixel_hitcounter = pt;
|
||||
}
|
||||
}
|
||||
#else // FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
FfxUInt32 same_pixel_hitcounter = LoadHitCounterHistory(dispatch_thread_id.xy / 8);
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_SAFEBAND
|
||||
|
||||
// Again compare with the same pixel and Pick the one with the biggest success rate
|
||||
if (FFX_Hitcounter_GetSWHits(hitcounter) < FFX_Hitcounter_GetSWHits(same_pixel_hitcounter))
|
||||
hitcounter = same_pixel_hitcounter;
|
||||
|
||||
FfxFloat32 rnd = GetRandom(dispatch_thread_id.xy / 8).x;
|
||||
FfxFloat32 rnd_last = GetRandomLastFrame(dispatch_thread_id.xy / 8).x;
|
||||
FfxFloat32 sw_hitcount_new = FfxFloat32(FFX_Hitcounter_GetSWHits(hitcounter));
|
||||
FfxFloat32 sw_hitcount_old = FfxFloat32(FFX_Hitcounter_GetOldSWHits(hitcounter));
|
||||
FfxFloat32 sw_misscount_new = FfxFloat32(FFX_Hitcounter_GetSWMisses(hitcounter));
|
||||
FfxFloat32 sw_misscount_old = FfxFloat32(FFX_Hitcounter_GetOldSWMisses(hitcounter));
|
||||
FfxBoolean new_class = IsSW(sw_hitcount_new, sw_misscount_new, rnd);
|
||||
FfxBoolean old_class = IsSW(sw_hitcount_old, sw_misscount_old, rnd_last);
|
||||
|
||||
// To make transition less obvious we do and extra checkerboard stage
|
||||
if (new_class == old_class)
|
||||
{
|
||||
if (new_class)
|
||||
{
|
||||
g_TileClass = TILE_CLASS_FULL_SW;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_TileClass = TILE_CLASS_FULL_HW;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_TileClass = TILE_CLASS_HALF_SW;
|
||||
}
|
||||
sw_hitcount_old = sw_hitcount_new;
|
||||
sw_misscount_old = sw_misscount_new;
|
||||
StoreHitCounter(dispatch_thread_id.xy / 8,
|
||||
(FfxUInt32(clamp(sw_hitcount_old, 0.0f, 255.0f)) << 8) | (FfxUInt32(clamp(sw_misscount_old, 0.0f, 255.0f)) << 24));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_TileClass = TILE_CLASS_FULL_SW;
|
||||
}
|
||||
#endif // FFX_HYBRID_REFLECTIONS
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// First we figure out on a per thread basis if we need to shoot a reflection ray
|
||||
FfxBoolean is_on_screen = (dispatch_thread_id.x < screen_size.x) && (dispatch_thread_id.y < screen_size.y);
|
||||
// Allow for additional engine side checks. For example engines could additionally only cast reflection rays for specific depth ranges
|
||||
FfxBoolean is_surface = !IsBackground(depth);
|
||||
// Don't shoot a ray on very rough surfaces
|
||||
FfxBoolean is_glossy_reflection = is_surface && IsGlossyReflection(roughness);
|
||||
FfxBoolean needs_ray = is_on_screen && is_glossy_reflection;
|
||||
|
||||
// Decide which ray to keep
|
||||
FfxBoolean is_base_ray = IsBaseRay(dispatch_thread_id, samples_per_quad);
|
||||
FfxBoolean is_converged = true;
|
||||
if (enable_temporal_variance_guided_tracing)
|
||||
{
|
||||
FfxFloat32x2 uv = (dispatch_thread_id + 0.5) / screen_size;
|
||||
is_converged = IsConverged(dispatch_thread_id, uv);
|
||||
}
|
||||
|
||||
needs_ray = needs_ray && (is_base_ray || !is_converged);
|
||||
|
||||
// Extra check for back-facing rays, fresnel, mirror etc.
|
||||
if (abs(view_space_surface_normal.z) > ReflectionsBackfacingThreshold())
|
||||
{
|
||||
FillEnvironment(dispatch_thread_id, IBLFactor());
|
||||
needs_ray = false;
|
||||
}
|
||||
|
||||
// We need denoiser even for mirrors since ssr/hw transition ends up creating poping tile firefies.
|
||||
FfxBoolean needs_denoiser = is_glossy_reflection;
|
||||
|
||||
// Next we have to figure out for which pixels that ray is creating the values for. Thus, if we have to copy its value horizontal, vertical or across.
|
||||
FfxBoolean require_copy =
|
||||
!needs_ray && needs_denoiser; // Our pixel only requires a copy if we want to run a denoiser on it but don't want to shoot a ray for it.
|
||||
|
||||
FfxBoolean copy_horizontal = FfxBoolean(ffxWaveXorU1(FfxUInt32(require_copy), 1)) && (samples_per_quad != 4) && is_base_ray; // QuadReadAcrossX
|
||||
FfxBoolean copy_vertical = FfxBoolean(ffxWaveXorU1(FfxUInt32(require_copy), 2)) && (samples_per_quad == 1) && is_base_ray; // QuadReadAcrossY
|
||||
FfxBoolean copy_diagonal = FfxBoolean(ffxWaveXorU1(FfxUInt32(require_copy), 3)) && (samples_per_quad == 1) && is_base_ray; // QuadReadAcrossDiagonal
|
||||
|
||||
FfxBoolean needs_sw_ray = true;
|
||||
|
||||
// In case there's only software rays we don't do hybridization
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
needs_sw_ray = needs_ray && enable_screen_space_tracing;
|
||||
|
||||
FfxBoolean needs_hw_ray = false;
|
||||
if (enable_hw_ray_tracing && roughness < RTRoughnessThreshold())
|
||||
{
|
||||
FfxBoolean checkerboard = ((group_thread_id.x ^ group_thread_id.y) & 1) == 0;
|
||||
needs_sw_ray = needs_sw_ray && ((g_TileClass == TILE_CLASS_FULL_SW ? true : (g_TileClass == TILE_CLASS_HALF_SW ? checkerboard : false)));
|
||||
needs_hw_ray = needs_ray && !needs_sw_ray;
|
||||
}
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
FfxUInt32 local_ray_index_in_wave_sw = ffxWavePrefixCountBits(needs_sw_ray);
|
||||
FfxUInt32 wave_ray_offset_in_group_sw;
|
||||
FfxUInt32 wave_ray_count_sw = ffxWaveActiveCountBits(needs_sw_ray);
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
FfxUInt32 local_ray_index_in_wave_hw = ffxWavePrefixCountBits(needs_hw_ray);
|
||||
FfxUInt32 wave_ray_count_hw = ffxWaveActiveCountBits(needs_hw_ray);
|
||||
FfxUInt32 base_ray_index_hw = 0;
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
if (is_first_lane_of_wave)
|
||||
{
|
||||
if (wave_ray_count_sw > 0)
|
||||
{
|
||||
#ifdef FFX_GLSL
|
||||
wave_ray_offset_in_group_sw = FFX_ATOMIC_ADD(g_SWCount, FfxInt32(wave_ray_count_sw));
|
||||
#else
|
||||
InterlockedAdd(g_SWCount, wave_ray_count_sw, wave_ray_offset_in_group_sw);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
if (wave_ray_count_hw > 0)
|
||||
IncrementRayCounterHW(wave_ray_count_hw, base_ray_index_hw);
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
}
|
||||
|
||||
base_ray_index_hw = ffxWaveReadLaneFirstU1(base_ray_index_hw);
|
||||
wave_ray_offset_in_group_sw = ffxWaveReadLaneFirstU1(wave_ray_offset_in_group_sw);
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
if (flat_group_thread_id == 0 && g_SWCount > 0)
|
||||
{
|
||||
// [IMPORTANT] We need to round up to the multiple of 32 for software rays, because of the atomic increment coalescing optimization
|
||||
g_SWCountTotal = g_SWCount < 32 ? 32 : (g_SWCount > 32 ? 64 : 32);
|
||||
IncrementRayCounterSW(g_SWCountTotal, g_base_ray_index_sw);
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
if (needs_sw_ray)
|
||||
{
|
||||
FfxUInt32 ray_index_sw = g_base_ray_index_sw + wave_ray_offset_in_group_sw + local_ray_index_in_wave_sw;
|
||||
StoreRay(ray_index_sw, dispatch_thread_id, copy_horizontal, copy_vertical, copy_diagonal);
|
||||
}
|
||||
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
else if (needs_hw_ray)
|
||||
{
|
||||
FfxUInt32 ray_index_hw = base_ray_index_hw + local_ray_index_in_wave_hw;
|
||||
StoreRayHW(ray_index_hw, dispatch_thread_id, copy_horizontal, copy_vertical, copy_diagonal);
|
||||
}
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|
||||
if (flat_group_thread_id < g_SWCountTotal - g_SWCount)
|
||||
{
|
||||
// [IMPORTANT] We need to round up to the multiple of 32 for software rays, because of the atomic increment coalescing optimization
|
||||
// Emit helper(dead) lanes to fill up 32 lanes per 8x8 tile
|
||||
FfxUInt32 ray_index_sw = g_base_ray_index_sw + g_SWCount + flat_group_thread_id;
|
||||
StoreRaySWHelper(ray_index_sw);
|
||||
}
|
||||
|
||||
// We only need denoiser if we trace any rays in the tile
|
||||
if (is_first_lane_of_wave && (wave_ray_count_sw > 0
|
||||
#ifdef FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
|| wave_ray_count_hw > 0
|
||||
#endif // FFX_CLASSIFIER_CLASSIFICATION_HW_RAYTRACING_ENABLED
|
||||
))
|
||||
{
|
||||
FFX_ATOMIC_ADD(g_TileCount, 1);
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER; // Wait until all waves wrote into g_TileCount
|
||||
|
||||
if (g_TileCount > 0)
|
||||
{
|
||||
if (group_thread_id.x == 0 && group_thread_id.y == 0)
|
||||
{
|
||||
FfxUInt32 tile_index;
|
||||
IncrementDenoiserTileCounter(tile_index);
|
||||
StoreDenoiserTile(tile_index, dispatch_thread_id);
|
||||
}
|
||||
}
|
||||
|
||||
if ((!needs_ray && !require_copy) // Discarded for some reason
|
||||
|| (needs_ray && !needs_hw_ray && !needs_sw_ray) // Or needs a ray but was discarded for some other reason
|
||||
)
|
||||
{
|
||||
if (is_surface)
|
||||
{
|
||||
FillEnvironment(dispatch_thread_id, IBLFactor());
|
||||
}
|
||||
else
|
||||
ZeroBuffers(dispatch_thread_id);
|
||||
}
|
||||
}
|
||||
527
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_callbacks_glsl.h
vendored
Normal file
527
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
// 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_classifier_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core.h"
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_CB_CLASSIFIER, std140) uniform cbClassifierReflections_t
|
||||
{
|
||||
FfxFloat32Mat4 invViewProjection;
|
||||
FfxFloat32Mat4 projection;
|
||||
FfxFloat32Mat4 invProjection;
|
||||
FfxFloat32Mat4 viewMatrix;
|
||||
FfxFloat32Mat4 invView;
|
||||
FfxFloat32Mat4 prevViewProjection;
|
||||
FfxUInt32x2 renderSize;
|
||||
FfxFloat32x2 inverseRenderSize;
|
||||
FfxFloat32 iblFactor;
|
||||
FfxUInt32 frameIndex;
|
||||
FfxUInt32 samplesPerQuad;
|
||||
FfxUInt32 temporalVarianceGuidedTracingEnabled;
|
||||
FfxFloat32 globalRoughnessThreshold;
|
||||
FfxFloat32 rtRoughnessThreshold;
|
||||
FfxUInt32 mask;
|
||||
FfxUInt32 reflectionWidth;
|
||||
FfxUInt32 reflectionHeight;
|
||||
FfxFloat32 hybridMissWeight;
|
||||
FfxFloat32 hybridSpawnRate;
|
||||
FfxFloat32 vrtVarianceThreshold;
|
||||
FfxFloat32 reflectionsBackfacingThreshold;
|
||||
FfxUInt32 randomSamplesPerPixel;
|
||||
FfxFloat32x2 motionVectorScale;
|
||||
FfxFloat32 normalsUnpackMul;
|
||||
FfxFloat32 normalsUnpackAdd;
|
||||
FfxUInt32 roughnessChannel;
|
||||
FfxUInt32 isRoughnessPerceptual;
|
||||
} cbClassifierReflection;
|
||||
|
||||
FfxFloat32Mat4 InvViewProjection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.invViewProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 Projection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.projection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvProjection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.invProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewMatrix()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.viewMatrix;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvView()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.invView;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 PrevViewProjection()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.prevViewProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32x2 RenderSize()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.renderSize;
|
||||
#else
|
||||
return FfxUInt32x2(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 InverseRenderSize()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.inverseRenderSize;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 IBLFactor()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.iblFactor;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 FrameIndex()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.frameIndex;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 SamplesPerQuad()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.samplesPerQuad;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxBoolean TemporalVarianceGuidedTracingEnabled()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return FfxBoolean(cbClassifierReflection.temporalVarianceGuidedTracingEnabled);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 RoughnessThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.globalRoughnessThreshold;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 RTRoughnessThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.rtRoughnessThreshold;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 Mask()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.mask;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionWidth()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.reflectionWidth;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionHeight()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.reflectionHeight;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 HybridMissWeight()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.hybridMissWeight;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 HybridSpawnRate()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.hybridSpawnRate;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 VRTVarianceThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.vrtVarianceThreshold;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 ReflectionsBackfacingThreshold()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.reflectionsBackfacingThreshold;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 RandomSamplesPerPixel()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.randomSamplesPerPixel;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.motionVectorScale;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.normalsUnpackMul;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.normalsUnpackAdd;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 RoughnessChannel()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return cbClassifierReflection.roughnessChannel;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxBoolean IsRoughnessPerceptual()
|
||||
{
|
||||
#if defined CLASSIFIER_BIND_CB_CLASSIFIER
|
||||
return FfxBoolean(cbClassifierReflection.isRoughnessPerceptual);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #if defined(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
|
||||
layout (set = 0, binding = 1000) uniform sampler s_EnvironmentMapSampler;
|
||||
layout (set = 0, binding = 1001) uniform sampler s_LinearSampler;
|
||||
|
||||
// SRVs
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_DEPTH
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_DEPTH) uniform texture2D r_input_depth;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS) uniform texture2D r_input_motion_vectors;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_NORMAL
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_NORMAL) uniform texture2D r_input_normal;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS) uniform texture2D r_input_material_parameters;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP) uniform textureCube r_input_environment_map;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_VARIANCE_HISTORY
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_SRV_VARIANCE_HISTORY) uniform texture2D r_variance_history;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY
|
||||
layout(set = 0, binding = CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY) uniform utexture2D r_hit_counter_history;
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined CLASSIFIER_BIND_UAV_RADIANCE
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_RADIANCE, rgba32f) uniform image2D rw_radiance;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_LIST
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_RAY_LIST, std430) buffer rw_ray_list_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_ray_list;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HW_RAY_LIST
|
||||
layout(set = 0, binding = CLASSIFIER_BIND_UAV_HW_RAY_LIST, std430) buffer rw_hw_ray_list_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_hw_ray_list;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST, std430) buffer rw_denoiser_tile_list_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_denoiser_tile_list;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_COUNTER
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_RAY_COUNTER, std430) buffer rw_ray_counter_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_ray_counter;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS
|
||||
layout (set = 0, binding = CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS, r32f) uniform image2D rw_extracted_roughness;
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HIT_COUNTER
|
||||
layout(set = 0, binding = CLASSIFIER_BIND_UAV_HIT_COUNTER, r32ui) uniform uimage2D rw_hit_counter;
|
||||
#endif
|
||||
|
||||
|
||||
FfxFloat32x3 LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_NORMAL)
|
||||
return normalize(NormalsUnpackMul() * texelFetch(r_input_normal, pixel_coordinate, 0).xyz + NormalsUnpackAdd());
|
||||
#else
|
||||
return FfxFloat32x3(0.f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x3 SampleEnvironmentMap(FfxFloat32x3 direction, FfxFloat32 preceptualRoughness)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP)
|
||||
FfxInt32x2 cubeSize = textureSize(r_input_environment_map, 0);
|
||||
FfxInt32 maxMipLevel = FfxInt32(log2(FfxFloat32(cubeSize.x > 0 ? cubeSize.x : 1)));
|
||||
FfxFloat32 lod = clamp(preceptualRoughness * FfxFloat32(maxMipLevel), 0.0, FfxFloat32(maxMipLevel));
|
||||
return textureLod(samplerCube(r_input_environment_map, s_EnvironmentMapSampler), direction, lod).xyz * IBLFactor();
|
||||
#else
|
||||
return FfxFloat32x3(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IncrementRayCounterSW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
original_value = atomicAdd(rw_ray_counter.data[0], value);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IncrementRayCounterHW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
original_value = atomicAdd(rw_ray_counter.data[4], value);
|
||||
#endif
|
||||
}
|
||||
|
||||
void IncrementDenoiserTileCounter(FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
original_value = atomicAdd(rw_ray_counter.data[2], 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 PackRayCoords(FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 ray_x_15bit = ray_coord.x & 32767; // 0b111111111111111
|
||||
FfxUInt32 ray_y_14bit = ray_coord.y & 16383; // 0b11111111111111;
|
||||
FfxUInt32 copy_horizontal_1bit = copy_horizontal ? 1 : 0;
|
||||
FfxUInt32 copy_vertical_1bit = copy_vertical ? 1 : 0;
|
||||
FfxUInt32 copy_diagonal_1bit = copy_diagonal ? 1 : 0;
|
||||
|
||||
FfxUInt32 packed = (copy_diagonal_1bit << 31) | (copy_vertical_1bit << 30) | (copy_horizontal_1bit << 29) | (ray_y_14bit << 15) | (ray_x_15bit << 0);
|
||||
return packed;
|
||||
}
|
||||
|
||||
void StoreRay(FfxUInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_ray_list.data[index] = packedRayCoords;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreRaySWHelper(FfxUInt32 index)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
rw_ray_list.data[index] = 0xffffffffu;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreRayHW(FfxUInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_hw_ray_list.data[index] = packedRayCoords;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreDenoiserTile(FfxUInt32 index, FfxUInt32x2 tile_coord)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
rw_denoiser_tile_list.data[index] = ((tile_coord.y & 0xffffu) << 16) | ((tile_coord.x & 0xffffu) << 0); // Store out pixel to trace
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreExtractedRoughness(FfxUInt32x2 coordinate, FfxFloat32 roughness)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS)
|
||||
imageStore(rw_extracted_roughness, FfxInt32x2(coordinate), FfxFloat32x4(roughness));
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 LoadRoughnessFromMaterialParametersInput(FfxUInt32x3 coordinate)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS)
|
||||
FfxFloat32 rawRoughness = texelFetch(r_input_material_parameters, FfxInt32x2(coordinate.xy), FfxInt32(coordinate.z))[RoughnessChannel()];
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 SampleVarianceHistory(FfxFloat32x2 coordinate) /**/
|
||||
{
|
||||
#if defined ( CLASSIFIER_BIND_SRV_VARIANCE_HISTORY )
|
||||
return FfxFloat32(textureLod(sampler2D(r_variance_history, s_LinearSampler), coordinate, 0.0f).x);
|
||||
#else
|
||||
return 0.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreRadiance(FfxUInt32x2 coordinate, FfxFloat32x4 radiance)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_UAV_RADIANCE)
|
||||
imageStore(rw_radiance, FfxInt32x2(coordinate), radiance);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 GetInputDepth(FfxUInt32x2 coordinate)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
return texelFetch(r_input_depth, FfxInt32x2(coordinate), 0).r;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreHitCounter(FfxUInt32x2 coordinate, FfxUInt32 value)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_UAV_HIT_COUNTER)
|
||||
imageStore(rw_hit_counter, FfxInt32x2(coordinate), FfxUInt32x4(value));
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32 LoadHitCounterHistory(FfxUInt32x2 coordinate)
|
||||
{
|
||||
#if defined(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY)
|
||||
return FfxUInt32(texelFetch(r_hit_counter_history, FfxInt32x2(coordinate), 0).r);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 LoadMotionVector(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
return MotionVectorScale() * texelFetch(r_input_motion_vectors, pixel_coordinate, 0).xy;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
477
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_callbacks_hlsl.h
vendored
Normal file
477
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,477 @@
|
||||
// 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_classifier_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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
#define DECLARE_SRV_REGISTER(regIndex) t##regIndex
|
||||
#define DECLARE_UAV_REGISTER(regIndex) u##regIndex
|
||||
#define DECLARE_CB_REGISTER(regIndex) b##regIndex
|
||||
#define FFX_CLASSIFIER_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
cbuffer cbClassifierReflection : FFX_CLASSIFIER_DECLARE_CB(CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
{
|
||||
FfxFloat32Mat4 invViewProjection;
|
||||
FfxFloat32Mat4 projection;
|
||||
FfxFloat32Mat4 invProjection;
|
||||
FfxFloat32Mat4 viewMatrix;
|
||||
FfxFloat32Mat4 invView;
|
||||
FfxFloat32Mat4 prevViewProjection;
|
||||
FfxUInt32x2 renderSize;
|
||||
FfxFloat32x2 inverseRenderSize;
|
||||
FfxFloat32 iblFactor;
|
||||
FfxUInt32 frameIndex;
|
||||
FfxUInt32 samplesPerQuad;
|
||||
FfxUInt32 temporalVarianceGuidedTracingEnabled;
|
||||
FfxFloat32 globalRoughnessThreshold;
|
||||
FfxFloat32 rtRoughnessThreshold;
|
||||
FfxUInt32 mask;
|
||||
FfxUInt32 reflectionWidth;
|
||||
FfxUInt32 reflectionHeight;
|
||||
FfxFloat32 hybridMissWeight;
|
||||
FfxFloat32 hybridSpawnRate;
|
||||
FfxFloat32 vrtVarianceThreshold;
|
||||
FfxFloat32 reflectionsBackfacingThreshold;
|
||||
FfxUInt32 randomSamplesPerPixel;
|
||||
FfxFloat32x2 motionVectorScale;
|
||||
FfxFloat32 normalsUnpackMul;
|
||||
FfxFloat32 normalsUnpackAdd;
|
||||
FfxUInt32 roughnessChannel;
|
||||
FfxUInt32 isRoughnessPerceptual;
|
||||
|
||||
#define FFX_CLASSIFIER_CONSTANT_BUFFER_1_SIZE 120
|
||||
};
|
||||
#else
|
||||
#define invViewProjection 0
|
||||
#define projection 0
|
||||
#define invProjection 0
|
||||
#define viewMatrix 0
|
||||
#define invView 0
|
||||
#define prevViewProjection 0
|
||||
#define renderSize 0
|
||||
#define inverseRenderSize 0
|
||||
#define iblFactor 0
|
||||
#define roughnessThreshold 0
|
||||
#define varianceThreshold 0
|
||||
#define frameIndex 0
|
||||
#define samplesPerQuad 0
|
||||
#define temporalVarianceGuidedTracingEnabled 0
|
||||
#define globalRoughnessThreshold 0
|
||||
#define rtRoughnessThreshold 0
|
||||
#define mask 0
|
||||
#define reflectionWidth 0
|
||||
#define reflectionHeight 0
|
||||
#define hybridMissWeight 0
|
||||
#define hybridSpawnRate 0
|
||||
#define vrtVarianceThreshold 0
|
||||
#define reflectionsBackfacingThreshold 0
|
||||
#define randomSamplesPerPixel 0
|
||||
#define motionVectorScale 0
|
||||
#define normalsUnpackMul 0
|
||||
#define normalsUnpackAdd 0
|
||||
#define roughnessChannel 0
|
||||
#define isRoughnessPerceptual 0
|
||||
#endif
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STRINGIFY(p) FFX_CLASSIFIER_ROOTSIG_STR(p)
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STR(p) #p
|
||||
#define FFX_CLASSIFIER_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0), " \
|
||||
"StaticSampler(s0, filter = FILTER_MIN_MAG_MIP_LINEAR, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_WRAP, " \
|
||||
"comparisonFunc = COMPARISON_ALWAYS, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK, " \
|
||||
"maxAnisotropy = 1), " \
|
||||
"StaticSampler(s1, filter = FILTER_MIN_MAG_MIP_LINEAR, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"comparisonFunc = COMPARISON_ALWAYS, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK, " \
|
||||
"maxAnisotropy = 1)" )]
|
||||
|
||||
#if defined(FFX_CLASSIFIER_EMBED_ROOTSIG)
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT FFX_CLASSIFIER_ROOTSIG
|
||||
#else
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_CLASSIFIER_EMBED_ROOTSIG
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
SamplerState s_EnvironmentMapSampler : register(s0);
|
||||
SamplerState s_LinearSampler : register(s1);
|
||||
|
||||
FfxFloat32Mat4 InvViewProjection()
|
||||
{
|
||||
return invViewProjection;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 Projection()
|
||||
{
|
||||
return projection;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvProjection()
|
||||
{
|
||||
return invProjection;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewMatrix()
|
||||
{
|
||||
return viewMatrix;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvView()
|
||||
{
|
||||
return invView;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 PrevViewProjection()
|
||||
{
|
||||
return prevViewProjection;
|
||||
}
|
||||
|
||||
FfxUInt32x2 RenderSize()
|
||||
{
|
||||
return renderSize;
|
||||
}
|
||||
|
||||
FfxFloat32x2 InverseRenderSize()
|
||||
{
|
||||
return inverseRenderSize;
|
||||
}
|
||||
|
||||
FfxFloat32 IBLFactor()
|
||||
{
|
||||
return iblFactor;
|
||||
}
|
||||
|
||||
FfxFloat32 RoughnessThreshold()
|
||||
{
|
||||
return globalRoughnessThreshold;
|
||||
}
|
||||
|
||||
FfxUInt32 FrameIndex()
|
||||
{
|
||||
return frameIndex;
|
||||
}
|
||||
|
||||
FfxUInt32 SamplesPerQuad()
|
||||
{
|
||||
return samplesPerQuad;
|
||||
}
|
||||
|
||||
FfxBoolean TemporalVarianceGuidedTracingEnabled()
|
||||
{
|
||||
return FfxBoolean(temporalVarianceGuidedTracingEnabled);
|
||||
}
|
||||
|
||||
FfxFloat32 RTRoughnessThreshold()
|
||||
{
|
||||
return rtRoughnessThreshold;
|
||||
}
|
||||
|
||||
FfxUInt32 Mask()
|
||||
{
|
||||
return mask;
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionWidth()
|
||||
{
|
||||
return reflectionWidth;
|
||||
}
|
||||
|
||||
FfxUInt32 ReflectionHeight()
|
||||
{
|
||||
return reflectionHeight;
|
||||
}
|
||||
|
||||
FfxFloat32 HybridMissWeight()
|
||||
{
|
||||
return hybridMissWeight;
|
||||
}
|
||||
|
||||
FfxFloat32 HybridSpawnRate()
|
||||
{
|
||||
return hybridSpawnRate;
|
||||
}
|
||||
|
||||
FfxFloat32 VRTVarianceThreshold()
|
||||
{
|
||||
return vrtVarianceThreshold;
|
||||
}
|
||||
|
||||
FfxFloat32 ReflectionsBackfacingThreshold()
|
||||
{
|
||||
return reflectionsBackfacingThreshold;
|
||||
}
|
||||
|
||||
FfxUInt32 RandomSamplesPerPixel()
|
||||
{
|
||||
return randomSamplesPerPixel;
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
return motionVectorScale;
|
||||
}
|
||||
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
return normalsUnpackMul;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
return normalsUnpackAdd;
|
||||
}
|
||||
|
||||
FfxUInt32 RoughnessChannel()
|
||||
{
|
||||
return roughnessChannel;
|
||||
}
|
||||
|
||||
FfxBoolean IsRoughnessPerceptual()
|
||||
{
|
||||
return FfxBoolean(isRoughnessPerceptual);
|
||||
}
|
||||
|
||||
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_DEPTH
|
||||
Texture2D<FfxFloat32> r_input_depth : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_DEPTH);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS
|
||||
Texture2D<FfxFloat32x2> r_input_motion_vectors : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_NORMAL
|
||||
Texture2D<FfxFloat32x3> r_input_normal : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_NORMAL);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS
|
||||
Texture2D<FfxFloat32x4> r_input_material_parameters : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP
|
||||
TextureCube r_input_environment_map : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_VARIANCE_HISTORY
|
||||
Texture2D<FfxFloat32> r_variance_history : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_VARIANCE_HISTORY);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY
|
||||
Texture2D<FfxUInt32> r_hit_counter_history : FFX_CLASSIFIER_DECLARE_SRV(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY);
|
||||
#endif
|
||||
|
||||
|
||||
// UAVs
|
||||
#if defined CLASSIFIER_BIND_UAV_RADIANCE
|
||||
RWTexture2D<FfxFloat32x4> rw_radiance : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_RADIANCE);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_LIST
|
||||
RWStructuredBuffer<FfxUInt32> rw_ray_list : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_RAY_LIST);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HW_RAY_LIST
|
||||
RWStructuredBuffer<FfxUInt32> rw_hw_ray_list : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_HW_RAY_LIST);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST
|
||||
RWStructuredBuffer<FfxUInt32> rw_denoiser_tile_list : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_RAY_COUNTER
|
||||
globallycoherent RWStructuredBuffer<FfxUInt32> rw_ray_counter : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_RAY_COUNTER);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS
|
||||
RWTexture2D<FfxFloat32> rw_extracted_roughness : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS);
|
||||
#endif
|
||||
#if defined CLASSIFIER_BIND_UAV_HIT_COUNTER
|
||||
RWTexture2D<FfxUInt32> rw_hit_counter : FFX_CLASSIFIER_DECLARE_UAV(CLASSIFIER_BIND_UAV_HIT_COUNTER);
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#endif // #if defined(FFX_HALF)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_NORMAL)
|
||||
FfxFloat32x3 LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return normalize(NormalsUnpackMul() * r_input_normal.Load(FfxInt32x3(pixel_coordinate, 0)).xyz + NormalsUnpackAdd());
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_SRV_INPUT_NORMAL)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP)
|
||||
FfxFloat32x3 SampleEnvironmentMap(FfxFloat32x3 direction, FfxFloat32 preceptualRoughness)
|
||||
{
|
||||
FfxFloat32 Width; FfxFloat32 Height;
|
||||
r_input_environment_map.GetDimensions(Width, Height);
|
||||
FfxInt32 maxMipLevel = FfxInt32(log2(FfxFloat32(Width > 0 ? Width : 1)));
|
||||
FfxFloat32 mip = clamp(preceptualRoughness * FfxFloat32(maxMipLevel), 0.0, FfxFloat32(maxMipLevel));
|
||||
return r_input_environment_map.SampleLevel(s_EnvironmentMapSampler, direction, mip).xyz * IBLFactor();
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_SRV_INPUT_ENVIRONMENT_MAP)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
void IncrementRayCounterSW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
InterlockedAdd(rw_ray_counter[0], value, original_value);
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
void IncrementRayCounterHW(FfxUInt32 value, FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
InterlockedAdd(rw_ray_counter[4], value, original_value);
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
void IncrementDenoiserTileCounter(FFX_PARAMETER_OUT FfxUInt32 original_value)
|
||||
{
|
||||
InterlockedAdd(rw_ray_counter[2], 1, original_value);
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_COUNTER)
|
||||
|
||||
FfxUInt32 PackRayCoords(FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 ray_x_15bit = ray_coord.x & 32767; // 0b111111111111111
|
||||
FfxUInt32 ray_y_14bit = ray_coord.y & 16383; // 0b11111111111111;
|
||||
FfxUInt32 copy_horizontal_1bit = copy_horizontal ? 1 : 0;
|
||||
FfxUInt32 copy_vertical_1bit = copy_vertical ? 1 : 0;
|
||||
FfxUInt32 copy_diagonal_1bit = copy_diagonal ? 1 : 0;
|
||||
|
||||
FfxUInt32 packed = (copy_diagonal_1bit << 31) | (copy_vertical_1bit << 30) | (copy_horizontal_1bit << 29) | (ray_y_14bit << 15) | (ray_x_15bit << 0);
|
||||
return packed;
|
||||
}
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
void StoreRay(FfxInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_ray_list[index] = packedRayCoords;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
void StoreRaySWHelper(FfxInt32 index)
|
||||
{
|
||||
rw_ray_list[index] = 0xffffffffu;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RAY_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_HW_RAY_LIST)
|
||||
void StoreRayHW(FfxInt32 index, FfxUInt32x2 ray_coord, FfxBoolean copy_horizontal, FfxBoolean copy_vertical, FfxBoolean copy_diagonal)
|
||||
{
|
||||
FfxUInt32 packedRayCoords = PackRayCoords(ray_coord, copy_horizontal, copy_vertical, copy_diagonal); // Store out pixel to trace
|
||||
rw_hw_ray_list[index] = packedRayCoords;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_HW_RAY_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
void StoreDenoiserTile(FfxInt32 index, FfxUInt32x2 tile_coord)
|
||||
{
|
||||
rw_denoiser_tile_list[index] = ((tile_coord.y & 0xffffu) << 16) | ((tile_coord.x & 0xffffu) << 0); // Store out pixel to trace
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS)
|
||||
void StoreExtractedRoughness(FfxUInt32x2 coordinate, FfxFloat32 roughness)
|
||||
{
|
||||
rw_extracted_roughness[coordinate] = roughness;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_EXTRACTED_ROUGHNESS)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS)
|
||||
FfxFloat32 LoadRoughnessFromMaterialParametersInput(FfxUInt32x3 coordinate) /**/
|
||||
{
|
||||
FfxFloat32 rawRoughness = r_input_material_parameters.Load(coordinate)[RoughnessChannel()];
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_INPUT_MATERIAL_PARAMETERS)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_VARIANCE_HISTORY)
|
||||
FfxFloat32 SampleVarianceHistory(FfxFloat32x2 coordinate)
|
||||
{
|
||||
return (FfxFloat32)r_variance_history.SampleLevel(s_LinearSampler, coordinate, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_VARIANCE_HISTORY)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_UAV_RADIANCE)
|
||||
void StoreRadiance(FfxUInt32x2 coordinate, FfxFloat32x4 radiance) /**/
|
||||
{
|
||||
rw_radiance[coordinate] = radiance;
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_UAV_RADIANCE)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
FfxFloat32 GetInputDepth(FfxUInt32x2 coordinate)
|
||||
{
|
||||
return r_input_depth[coordinate];
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY)
|
||||
FfxUInt32 LoadHitCounterHistory(FfxUInt32x2 coordinate)
|
||||
{
|
||||
return r_hit_counter_history[coordinate];
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_SRV_HIT_COUNTER_HISTORY)
|
||||
|
||||
#if defined(CLASSIFIER_BIND_UAV_HIT_COUNTER)
|
||||
void StoreHitCounter(FfxUInt32x2 coordinate, FfxUInt32 value)
|
||||
{
|
||||
rw_hit_counter[coordinate] = value;
|
||||
}
|
||||
#endif // #if defined(CLASSIFIER_BIND_UAV_HIT_COUNTER)
|
||||
|
||||
#if defined (CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
FfxFloat32x2 LoadMotionVector(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return MotionVectorScale() * r_input_motion_vectors.Load(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
#endif // #if defined (CLASSIFIER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
118
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_common.h
vendored
Normal file
118
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_reflections_common.h
vendored
Normal file
@@ -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.
|
||||
|
||||
// Use hitcounter feedback
|
||||
#define FFX_CLASSIFIER_FLAGS_USE_HIT_COUNTER (1 << 0)
|
||||
// Traverse in screen space
|
||||
#define FFX_CLASSIFIER_FLAGS_USE_SCREEN_SPACE (1 << 1)
|
||||
// Traverse using HW ray tracing
|
||||
#define FFX_CLASSIFIER_FLAGS_USE_RAY_TRACING (1 << 2)
|
||||
// Iterate BVH to search for the opaque fragment
|
||||
#define FFX_CLASSIFIER_FLAGS_RESOLVE_TRANSPARENT (1 << 3)
|
||||
// Grab radiance from screen space shaded image for ray traced intersections, when possible
|
||||
#define FFX_CLASSIFIER_FLAGS_SHADING_USE_SCREEN (1 << 5)
|
||||
// defines FFX_HSR_OPTION_SHADING_USE_SCREEN
|
||||
|
||||
// Extra flags for debugging
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_0 (1 << 9)
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_1 (1 << 10)
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_2 (1 << 11)
|
||||
#define FFX_CLASSIFIER_FLAGS_FLAG_3 (1 << 12)
|
||||
|
||||
// Visualization tweaking
|
||||
#define FFX_CLASSIFIER_FLAGS_SHOW_DEBUG_TARGET (1 << 13)
|
||||
#define FFX_CLASSIFIER_FLAGS_SHOW_INTERSECTION (1 << 14)
|
||||
#define FFX_CLASSIFIER_FLAGS_SHOW_REFLECTION_TARGET (1 << 15)
|
||||
#define FFX_CLASSIFIER_FLAGS_APPLY_REFLECTIONS (1 << 16)
|
||||
#define FFX_CLASSIFIER_FLAGS_INTERSECTION_ACCUMULATE (1 << 17)
|
||||
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_WAVES (1 << 18)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_AVG_RADIANCE (1 << 19)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_VARIANCE (1 << 20)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_NUM_SAMPLES (1 << 21)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_RAY_LENGTH (1 << 23)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_REPROJECTION (1 << 25)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_TRANSPARENT_QUERY (1 << 26)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_HIT_COUNTER (1 << 27)
|
||||
#define FFX_CLASSIFIER_FLAGS_VISUALIZE_PRIMARY_RAYS (1 << 28)
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
|
||||
#define FFX_REFLECTIONS_SKY_DISTANCE 100.0f
|
||||
|
||||
// Helper defines for hitcouter and classification
|
||||
#define FFX_HITCOUNTER_SW_HIT_FLAG (1u << 0u)
|
||||
#define FFX_HITCOUNTER_SW_HIT_SHIFT 0u
|
||||
#define FFX_HITCOUNTER_SW_OLD_HIT_SHIFT 8u
|
||||
#define FFX_HITCOUNTER_MASK 0xffu
|
||||
#define FFX_HITCOUNTER_SW_MISS_FLAG (1u << 16u)
|
||||
#define FFX_HITCOUNTER_SW_MISS_SHIFT 16u
|
||||
#define FFX_HITCOUNTER_SW_OLD_MISS_SHIFT 24u
|
||||
|
||||
#define FFX_Hitcounter_GetSWHits(counter) ((counter >> FFX_HITCOUNTER_SW_HIT_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
#define FFX_Hitcounter_GetSWMisses(counter) ((counter >> FFX_HITCOUNTER_SW_MISS_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
#define FFX_Hitcounter_GetOldSWHits(counter) ((counter >> FFX_HITCOUNTER_SW_OLD_HIT_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
#define FFX_Hitcounter_GetOldSWMisses(counter) ((counter >> FFX_HITCOUNTER_SW_OLD_MISS_SHIFT) & FFX_HITCOUNTER_MASK)
|
||||
|
||||
//=== Common functions of the HsrSample ===
|
||||
|
||||
void UnpackRayCoords(FfxUInt32 packed, FFX_PARAMETER_OUT FfxUInt32x2 ray_coord, FFX_PARAMETER_OUT FfxBoolean copy_horizontal, FFX_PARAMETER_OUT FfxBoolean copy_vertical, FFX_PARAMETER_OUT FfxBoolean copy_diagonal) {
|
||||
ray_coord.x = (packed >> 0) & 32767; // 0b111111111111111;
|
||||
ray_coord.y = (packed >> 15) & 16383; // 0b11111111111111;
|
||||
copy_horizontal = FfxBoolean((packed >> 29) & 1u);
|
||||
copy_vertical = FfxBoolean((packed >> 30) & 1u);
|
||||
copy_diagonal = FfxBoolean((packed >> 31) & 1u);
|
||||
}
|
||||
|
||||
// Mat must be able to transform origin from texture space to a linear space.
|
||||
FfxFloat32x3 InvProjectPosition(FfxFloat32x3 coord, FfxFloat32Mat4 mat) {
|
||||
coord.y = (1 - coord.y);
|
||||
coord.xy = 2 * coord.xy - 1;
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(mat, FfxFloat32x4(coord, 1));
|
||||
projected.xyz /= projected.w;
|
||||
return projected.xyz;
|
||||
}
|
||||
|
||||
FfxBoolean IsGlossyReflection(FfxFloat32 roughness) {
|
||||
return roughness < RoughnessThreshold();
|
||||
}
|
||||
|
||||
FfxFloat32x3 ScreenSpaceToViewSpace(FfxFloat32x3 screen_uv_coord) {
|
||||
return InvProjectPosition(screen_uv_coord, InvProjection());
|
||||
}
|
||||
|
||||
FfxBoolean IsBackground(FfxFloat32 depth)
|
||||
{
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
return depth < 1.e-6f;
|
||||
#else
|
||||
return depth >= (1.0f - 1.e-6f);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Rounds value to the nearest multiple of 8
|
||||
FfxUInt32x2 FFX_DNSR_Reflections_RoundUp8(FfxUInt32x2 value) {
|
||||
FfxUInt32x2 round_down = value & ~7; // 0b111;
|
||||
return FFX_SELECT((round_down == value), value, value + 8);
|
||||
}
|
||||
|
||||
#endif
|
||||
59
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_resources.h
vendored
Normal file
59
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_resources.h
vendored
Normal file
@@ -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_CLASSIFIER_RESOURCES_H
|
||||
#define FFX_CLASSIFIER_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_DEPTH 1
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_NORMAL 2
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_WORK_QUEUE 3
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_WORK_QUEUE_COUNTER 4
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_RAY_HIT 5
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_SHADOW_MAPS 7
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_MOTION_VECTORS 8
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_SPECULAR_ROUGHNESS 9
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_ENVIRONMENT_MAP 10
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_VARIANCE_HISTORY 11
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_HIT_COUNTER_HISTORY 12
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_HIT_COUNTER 13
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_RAY_LIST 14
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_HW_RAY_LIST 15
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_EXTRACTED_ROUGHNESS 16
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_RAY_COUNTER 17
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_DENOISER_TILE_LIST 18
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_DEBUG_IMAGE 19
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_RADIANCE 20
|
||||
|
||||
#define FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT 25 // 21 + FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT
|
||||
#if defined(FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT)
|
||||
static_assert(FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT == 4,
|
||||
"This count represents 21 + FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT. This assert monitors if MAX_SHADOW_MAP_TEXTURES_COUNT has changed");
|
||||
#endif // #if defined(FFX_CLASSIFIER_MAX_SHADOW_MAP_TEXTURES_COUNT)
|
||||
|
||||
#define FFX_CLASSIFIER_CONSTANTBUFFER_IDENTIFIER_CLASSIFIER 0
|
||||
#define FFX_CLASSIFIER_CONSTANTBUFFER_IDENTIFIER_REFLECTION 1
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif //!defined( FFX_CLASSIFIER_RESOURCES_H )
|
||||
221
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows.h
vendored
Normal file
221
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows.h
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
// 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.
|
||||
|
||||
/// @defgroup FfxGPUClassifier FidelityFX Classifier
|
||||
/// FidelityFX Classifier GPU documentation
|
||||
///
|
||||
/// @ingroup FfxGPUEffects
|
||||
|
||||
#include "ffx_classifier_common.h"
|
||||
|
||||
struct ClassifyResults
|
||||
{
|
||||
FfxBoolean bIsActiveLane;
|
||||
FfxBoolean bIsInLight;
|
||||
FfxFloat32 minT;
|
||||
FfxFloat32 maxT;
|
||||
};
|
||||
|
||||
ClassifyResults FfxClassify(const FfxUInt32x2 pixelCoord,
|
||||
const FfxBoolean bUseNormal,
|
||||
const FfxBoolean bUseCascadeBlocking)
|
||||
{
|
||||
const FfxBoolean bIsInViewport = all(FFX_LESS_THAN(pixelCoord, TextureSize().xy));
|
||||
const FfxFloat32 depth = FfxClassifierSampleDepth(pixelCoord);
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
FfxBoolean bIsActiveLane = bIsInViewport && (depth > 0.0f);
|
||||
#else
|
||||
FfxBoolean bIsActiveLane = bIsInViewport && (depth < 1.0f);
|
||||
#endif
|
||||
FfxBoolean bIsInLight = FFX_FALSE;
|
||||
FfxFloat32 minT = FFX_POSITIVE_INFINITY_FLOAT;
|
||||
FfxFloat32 maxT = 0.f;
|
||||
|
||||
if (bUseNormal && bIsActiveLane)
|
||||
{
|
||||
const FfxFloat32x3 normal = normalize(FfxClassifierSampleNormal(pixelCoord));
|
||||
const FfxBoolean bIsNormalFacingLight = dot(normal, -LightDir()) > 0;
|
||||
|
||||
bIsActiveLane = bIsActiveLane && bIsNormalFacingLight;
|
||||
}
|
||||
|
||||
if (bUseCascadeBlocking && bIsActiveLane)
|
||||
{
|
||||
const FfxFloat32x2 uv = pixelCoord * TextureSize().zw;
|
||||
const FfxFloat32x4 homogeneous = FFX_MATRIX_MULTIPLY(ViewToWorld(), FfxFloat32x4(2.0f * FfxFloat32x2(uv.x, 1.0f - uv.y) - 1.0f, depth, 1));
|
||||
const FfxFloat32x3 worldPos = homogeneous.xyz / homogeneous.w;
|
||||
|
||||
const FfxFloat32x3 lightViewSpacePos = FFX_MATRIX_MULTIPLY(LightView(), FfxFloat32x4(worldPos, 1)).xyz;
|
||||
|
||||
FfxBoolean bIsInActiveCascade = FFX_FALSE;
|
||||
|
||||
if (bUseCascadeBlocking)
|
||||
{
|
||||
const FfxFloat32 radius = SunSizeLightSpace() * lightViewSpacePos.z;
|
||||
|
||||
FfxFloat32x3 shadowCoord = FfxFloat32x3(0, 0, 0);
|
||||
FfxUInt32 cascadeIndex = 0;
|
||||
for (FfxUInt32 i = 0; i < CascadeCount(); ++i)
|
||||
{
|
||||
shadowCoord = lightViewSpacePos * CascadeScale(i).xyz + CascadeOffset(i).xyz;
|
||||
if (all(FFX_GREATER_THAN(shadowCoord.xy, FfxFloat32x2(0, 0))) && all(FFX_LESS_THAN(shadowCoord.xy, FfxFloat32x2(1, 1))))
|
||||
{
|
||||
cascadeIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// grow search area by a pixel to make sure we search a wide enough area
|
||||
// also scale everything from UV to pixel coord for image loads.
|
||||
const FfxFloat32x2 radiusCoord = abs(FfxFloat32x2(radius, radius) * CascadeScale(cascadeIndex).xy) * FfxFloat32x2(CascadeSize(), CascadeSize()) + FfxFloat32x2(1,1);
|
||||
shadowCoord.xy *= CascadeSize();
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
const FfxFloat32 depthCmp = shadowCoord.z + BlockerOffset();
|
||||
#else
|
||||
const FfxFloat32 depthCmp = shadowCoord.z - BlockerOffset();
|
||||
#endif
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
FfxFloat32 maxD = 1;
|
||||
FfxFloat32 minD = 0;
|
||||
FfxFloat32 closetDepth = 1;
|
||||
#else
|
||||
FfxFloat32 maxD = 0;
|
||||
FfxFloat32 minD = 1;
|
||||
FfxFloat32 closetDepth = 0;
|
||||
#endif
|
||||
|
||||
|
||||
// With small shadow maps we will be bound on filtering since the shadow map can end up completely in LO cache
|
||||
// using an image load is faster then a sample in RDNA but we will be losing the benefit of doing some of the ALU
|
||||
// in the filter and getting 4 pixels of data per tap.
|
||||
for (FfxUInt32 x = 0; x < k_poissonDiscSampleCountHigh; ++x)
|
||||
{
|
||||
const FfxFloat32x2 sampleUV = shadowCoord.xy + k_poissonDisc[x] * radiusCoord + 0.5f;
|
||||
|
||||
// UV bounds check
|
||||
if (!(all(FFX_GREATER_THAN_EQUAL(sampleUV.xy, FfxFloat32x2(0, 0))) &&
|
||||
all(FFX_LESS_THAN(sampleUV.xy, FfxFloat32x2(CascadeSize(), CascadeSize())))))
|
||||
continue;
|
||||
const FfxFloat32 pixelDepth = FfxClassifierSampleShadowMap(sampleUV, cascadeIndex);
|
||||
|
||||
// using min and max to reduce number of cmps
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
maxD = min(maxD, pixelDepth);
|
||||
minD = max(minD, pixelDepth);
|
||||
|
||||
// need to find closet point in front of the receiver
|
||||
if (pixelDepth > depthCmp)
|
||||
{
|
||||
closetDepth = min(closetDepth, pixelDepth);
|
||||
}
|
||||
#else
|
||||
maxD = max(maxD, pixelDepth);
|
||||
minD = min(minD, pixelDepth);
|
||||
|
||||
// need to find closet point in front of the receiver
|
||||
if (pixelDepth < depthCmp)
|
||||
{
|
||||
closetDepth = max(closetDepth, pixelDepth);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
const FfxBoolean bIsInShadow = (maxD >= depthCmp);
|
||||
bIsInLight = RejectLitPixels() && (minD <= depthCmp);
|
||||
#else
|
||||
const FfxBoolean bIsInShadow = (maxD <= depthCmp);
|
||||
bIsInLight = RejectLitPixels() && (minD >= depthCmp);
|
||||
#endif
|
||||
bIsInActiveCascade = !bIsInShadow && !bIsInLight;
|
||||
|
||||
if (bIsInActiveCascade && UseCascadesForRayT())
|
||||
{
|
||||
#if FFX_CLASSIFIER_OPTION_INVERTED_DEPTH
|
||||
const FfxFloat32 viewMinT = abs(min(shadowCoord.z + closetDepth + BlockerOffset(), 0) / CascadeScale(cascadeIndex).z);
|
||||
const FfxFloat32 viewMaxT = abs((shadowCoord.z + minD - BlockerOffset()) / CascadeScale(cascadeIndex).z);
|
||||
#else
|
||||
const FfxFloat32 viewMinT = abs(max(shadowCoord.z - closetDepth - BlockerOffset(), 0) / CascadeScale(cascadeIndex).z);
|
||||
const FfxFloat32 viewMaxT = abs((shadowCoord.z - minD + BlockerOffset()) / CascadeScale(cascadeIndex).z);
|
||||
#endif
|
||||
|
||||
// if its known that the light view matrix is only a rotation or has uniform scale this can be optimized.
|
||||
minT = length(FFX_MATRIX_MULTIPLY(InverseLightView(), FfxFloat32x4(0, 0, viewMinT, 0)).xyz);
|
||||
maxT = length(FFX_MATRIX_MULTIPLY(InverseLightView(), FfxFloat32x4(0, radius, viewMaxT, 0)).xyz);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bIsActiveLane = bIsActiveLane && bIsInActiveCascade;
|
||||
}
|
||||
|
||||
const ClassifyResults results = { bIsActiveLane, bIsInLight, minT, maxT };
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/// Classifier pass entry point.
|
||||
///
|
||||
/// @param LocalThreadId The "flattened" index of a thread within a thread group (SV_GroupIndex).
|
||||
/// @param WorkGroupId Index of the thread group currently executed (SV_GroupID).
|
||||
/// @ingroup FfxGPUClassifier
|
||||
void FfxClassifyShadows(FfxUInt32 LocalThreadId, FfxUInt32x3 WorkGroupId)
|
||||
{
|
||||
const FfxUInt32x2 localID = ffxRemapForWaveReduction(LocalThreadId);
|
||||
const FfxUInt32x2 pixelCoord = WorkGroupId.xy * k_tileSize + localID.xy;
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_CLASSIFIER_MODE == 0
|
||||
ClassifyResults results = FfxClassify(pixelCoord, FFX_TRUE, FFX_FALSE);
|
||||
#endif
|
||||
#if FFX_CLASSIFIER_OPTION_CLASSIFIER_MODE == 1
|
||||
ClassifyResults results = FfxClassify(pixelCoord, FFX_TRUE, FFX_TRUE);
|
||||
#endif
|
||||
Tile currentTile = TileCreate(WorkGroupId.xy);
|
||||
const FfxUInt32 mask = BoolToWaveMask(results.bIsActiveLane, localID);
|
||||
currentTile.mask = mask;
|
||||
|
||||
#if FFX_CLASSIFIER_OPTION_CLASSIFIER_MODE == 1
|
||||
if (UseCascadesForRayT())
|
||||
{
|
||||
// At lest one lane must be active for the tile to be written out, so the infinitly and zero will be emoved by the wave min and max.
|
||||
// Otherwise we will get minT to be infinite and maxT to be 0
|
||||
currentTile.minT = max(ffxWaveMin(results.minT), currentTile.minT);
|
||||
currentTile.maxT = min(ffxWaveMax(results.maxT), currentTile.maxT);
|
||||
}
|
||||
#endif
|
||||
|
||||
const FfxUInt32 lightMask = BoolToWaveMask(results.bIsInLight, localID);
|
||||
const FfxBoolean bDiscardTile = (CountBits(mask) <= TileTolerance());
|
||||
|
||||
if (LocalThreadId == 0)
|
||||
{
|
||||
if (!bDiscardTile)
|
||||
{
|
||||
FfxClassifierStoreTile(TileToUint(currentTile));
|
||||
}
|
||||
|
||||
FfxClassifierStoreLightMask(WorkGroupId.xy, lightMask);
|
||||
}
|
||||
}
|
||||
287
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows_callbacks_glsl.h
vendored
Normal file
287
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
// 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_classifier_resources.h"
|
||||
#include "ffx_core.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
|
||||
const FfxFloat32x2 k_poissonDisc[] = {
|
||||
FfxFloat32x2(0.640736f, -0.355205f), FfxFloat32x2(-0.725411f, -0.688316f), FfxFloat32x2(-0.185095f, 0.722648f), FfxFloat32x2(0.770596f, 0.637324f),
|
||||
FfxFloat32x2(-0.921445f, 0.196997f), FfxFloat32x2(0.076571f, -0.98822f), FfxFloat32x2(-0.1348f, -0.0908536f), FfxFloat32x2(0.320109f, 0.257241f),
|
||||
FfxFloat32x2(0.994021f, 0.109193f), FfxFloat32x2(0.304934f, 0.952374f), FfxFloat32x2(-0.698577f, 0.715535f), FfxFloat32x2(0.548701f, -0.836019f),
|
||||
FfxFloat32x2(-0.443159f, 0.296121f), FfxFloat32x2(0.15067f, -0.489731f), FfxFloat32x2(-0.623829f, -0.208167f), FfxFloat32x2(-0.294778f, -0.596545f),
|
||||
FfxFloat32x2(0.334086f, -0.128208f), FfxFloat32x2(-0.0619831f, 0.311747f), FfxFloat32x2(0.166112f, 0.61626f), FfxFloat32x2(-0.289127f, -0.957291f),
|
||||
FfxFloat32x2(-0.98748f, -0.157745f), FfxFloat32x2(0.637501f, 0.0651571f), FfxFloat32x2(0.971376f, -0.237545f), FfxFloat32x2(-0.0170599f, 0.98059f),
|
||||
FfxFloat32x2(-0.442564f, 0.896737f), FfxFloat32x2(0.48619f, 0.518723f), FfxFloat32x2(-0.725272f, 0.419965f), FfxFloat32x2(0.781417f, -0.624009f),
|
||||
FfxFloat32x2(-0.899227f, -0.437482f), FfxFloat32x2(0.769219f, 0.33372f), FfxFloat32x2(-0.414411f, 0.00375378f), FfxFloat32x2(0.262856f, -0.759514f),
|
||||
};
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_CB_CLASSIFIER, std140) uniform cbClassifier_t
|
||||
{
|
||||
FfxFloat32x4 textureSize;
|
||||
FfxFloat32x3 lightDir;
|
||||
FfxFloat32 skyHeight;
|
||||
|
||||
FfxFloat32x4 blockerOffset_cascadeSize_sunSizeLightSpace_pad;
|
||||
FfxUInt32x4 cascadeCount_tileTolerance_pad_pad;
|
||||
FfxFloat32x4 bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd;
|
||||
|
||||
FfxFloat32x4 cascadeScale[4];
|
||||
FfxFloat32x4 cascadeOffset[4];
|
||||
|
||||
// Matrices
|
||||
FfxFloat32Mat4 viewToWorld;
|
||||
FfxFloat32Mat4 lightView;
|
||||
FfxFloat32Mat4 inverseLightView;
|
||||
|
||||
//#define FFX_CLASSIFIER_CONSTANT_BUFFER_1_SIZE 18 + 2 booleans + 32 + 48// Number of 32-bit values
|
||||
} cbClassifier;
|
||||
#endif
|
||||
|
||||
FfxFloat32x4 TextureSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.textureSize;
|
||||
#endif
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
}
|
||||
|
||||
FfxFloat32x3 LightDir()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.lightDir;
|
||||
#endif
|
||||
return FfxFloat32x3(0, 0, 0);
|
||||
}
|
||||
|
||||
FfxFloat32 SkyHeight()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.skyHeight;
|
||||
#endif
|
||||
return FfxFloat32(0);
|
||||
}
|
||||
|
||||
FfxUInt32 CascadeCount()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeCount_tileTolerance_pad_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxUInt32 TileTolerance()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeCount_tileTolerance_pad_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 BlockerOffset()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.blockerOffset_cascadeSize_sunSizeLightSpace_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 CascadeSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.blockerOffset_cascadeSize_sunSizeLightSpace_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 SunSizeLightSpace()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.blockerOffset_cascadeSize_sunSizeLightSpace_pad[2];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxBoolean RejectLitPixels()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return FfxBoolean(cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[0]);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxBoolean UseCascadesForRayT()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return FfxBoolean(cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[1]);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[2];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[3];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeScale(FfxUInt32 index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeScale[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeOffset(FfxUInt32 index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.cascadeOffset[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewToWorld()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.viewToWorld;
|
||||
#endif
|
||||
return FfxFloat32Mat4(0);
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 LightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.lightView;
|
||||
#endif
|
||||
return FfxFloat32Mat4(0);
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InverseLightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cbClassifier.inverseLightView;
|
||||
#endif
|
||||
return FfxFloat32Mat4(0);
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
uniform texture2D r_input_depth;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
uniform texture2D r_input_normal;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
uniform texture2D r_input_shadowMap[4];
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES, std430)
|
||||
buffer rwsb_tiles_t
|
||||
{
|
||||
FfxUInt32x4 data[];
|
||||
} rwsb_tiles;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT, std430)
|
||||
coherent buffer rwb_tileCount_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rwb_tileCount;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT, r32ui)
|
||||
uniform uimage2D rwt2d_rayHitResults;
|
||||
#endif
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_TEXTURE)
|
||||
layout (set = 0, binding = FFX_CLASSIFIER_BIND_UAV_OUTPUT_TEXTURE, rgba32f)
|
||||
uniform image2D rwt2d_output;
|
||||
#endif
|
||||
|
||||
FfxFloat32 FfxClassifierSampleDepth(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
return texelFetch(r_input_depth, ivec2(uiPxPos), 0).r;
|
||||
#else
|
||||
return 0.0;
|
||||
#endif // defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
}
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
FfxFloat32x3 FfxClassifierSampleNormal(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
FfxFloat32x3 normal = texelFetch(r_input_normal, ivec2(uiPxPos), 0).rgb;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
return normalize(normal);
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
FfxFloat32 FfxClassifierSampleShadowMap(FfxFloat32x2 sampleUV, FfxUInt32 cascadeIndex)
|
||||
{
|
||||
nonuniformEXT FfxUInt32 nonUniformCascadeIndex = cascadeIndex;
|
||||
return texelFetch(r_input_shadowMap[nonUniformCascadeIndex], ivec2(sampleUV), 0).r;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
void FfxClassifierStoreLightMask(FfxUInt32x2 index, FfxUInt32 lightMask)
|
||||
{
|
||||
imageStore(rwt2d_rayHitResults, ivec2(index), FfxUInt32x4(~lightMask, 0,0,0));
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
|
||||
FfxUInt32 CountBits(const FfxUInt32 mask)
|
||||
{
|
||||
return bitCount(mask);
|
||||
}
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
void FfxClassifierStoreTile(FfxUInt32x4 uiTile)
|
||||
{
|
||||
uint index = ~0;
|
||||
index = atomicAdd(rwb_tileCount.data[0], 1);
|
||||
rwsb_tiles.data[index] = uiTile;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
311
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows_callbacks_hlsl.h
vendored
Normal file
311
manul/thirdparty/fsr2/include/FidelityFX/gpu/classifier/ffx_classifier_shadows_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
// 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_classifier_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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
|
||||
static const FfxFloat32x2 k_poissonDisc[] = {
|
||||
FfxFloat32x2(0.640736f, -0.355205f), FfxFloat32x2(-0.725411f, -0.688316f), FfxFloat32x2(-0.185095f, 0.722648f), FfxFloat32x2(0.770596f, 0.637324f),
|
||||
FfxFloat32x2(-0.921445f, 0.196997f), FfxFloat32x2(0.076571f, -0.98822f), FfxFloat32x2(-0.1348f, -0.0908536f), FfxFloat32x2(0.320109f, 0.257241f),
|
||||
FfxFloat32x2(0.994021f, 0.109193f), FfxFloat32x2(0.304934f, 0.952374f), FfxFloat32x2(-0.698577f, 0.715535f), FfxFloat32x2(0.548701f, -0.836019f),
|
||||
FfxFloat32x2(-0.443159f, 0.296121f), FfxFloat32x2(0.15067f, -0.489731f), FfxFloat32x2(-0.623829f, -0.208167f), FfxFloat32x2(-0.294778f, -0.596545f),
|
||||
FfxFloat32x2(0.334086f, -0.128208f), FfxFloat32x2(-0.0619831f, 0.311747f), FfxFloat32x2(0.166112f, 0.61626f), FfxFloat32x2(-0.289127f, -0.957291f),
|
||||
FfxFloat32x2(-0.98748f, -0.157745f), FfxFloat32x2(0.637501f, 0.0651571f), FfxFloat32x2(0.971376f, -0.237545f), FfxFloat32x2(-0.0170599f, 0.98059f),
|
||||
FfxFloat32x2(-0.442564f, 0.896737f), FfxFloat32x2(0.48619f, 0.518723f), FfxFloat32x2(-0.725272f, 0.419965f), FfxFloat32x2(0.781417f, -0.624009f),
|
||||
FfxFloat32x2(-0.899227f, -0.437482f), FfxFloat32x2(0.769219f, 0.33372f), FfxFloat32x2(-0.414411f, 0.00375378f), FfxFloat32x2(0.262856f, -0.759514f),
|
||||
};
|
||||
|
||||
|
||||
#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_CLASSIFIER_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_CLASSIFIER_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
cbuffer cbClassifier : FFX_CLASSIFIER_DECLARE_CB(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
{
|
||||
FfxFloat32x4 textureSize;
|
||||
FfxFloat32x3 lightDir;
|
||||
FfxFloat32 skyHeight;
|
||||
|
||||
FfxFloat32x4 blockerOffset_cascadeSize_sunSizeLightSpace_pad;
|
||||
FfxUInt32x4 cascadeCount_tileTolerance_pad_pad;
|
||||
FfxFloat32x4 bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd;
|
||||
|
||||
FfxFloat32x4 cascadeScale[4];
|
||||
FfxFloat32x4 cascadeOffset[4];
|
||||
|
||||
// Matrices
|
||||
FfxFloat32Mat4 viewToWorld;
|
||||
FfxFloat32Mat4 lightView;
|
||||
FfxFloat32Mat4 inverseLightView;
|
||||
|
||||
#define FFX_CLASSIFIER_CONSTANT_BUFFER_1_SIZE 100
|
||||
};
|
||||
#endif
|
||||
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STRINGIFY(p) FFX_CLASSIFIER_ROOTSIG_STR(p)
|
||||
#define FFX_CLASSIFIER_ROOTSIG_STR(p) #p
|
||||
#define FFX_CLASSIFIER_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_CLASSIFIER_ROOTSIG_STRINGIFY(FFX_CLASSIFIER_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)" )]
|
||||
|
||||
#if defined(FFX_CLASSIFIER_EMBED_ROOTSIG)
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT FFX_CLASSIFIER_ROOTSIG
|
||||
#else
|
||||
#define FFX_CLASSIFIER_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_CLASSIFIER_EMBED_ROOTSIG
|
||||
|
||||
FfxFloat32x4 TextureSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return textureSize;
|
||||
#endif
|
||||
return FfxFloat32x4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
FfxFloat32x3 LightDir()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return lightDir;
|
||||
#endif
|
||||
return FfxFloat32x3(0, 0, 0);
|
||||
}
|
||||
|
||||
FfxFloat32 SkyHeight()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return skyHeight;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxUInt32 CascadeCount()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeCount_tileTolerance_pad_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxUInt32 TileTolerance()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeCount_tileTolerance_pad_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 BlockerOffset()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return blockerOffset_cascadeSize_sunSizeLightSpace_pad[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 CascadeSize()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return blockerOffset_cascadeSize_sunSizeLightSpace_pad[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 SunSizeLightSpace()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return blockerOffset_cascadeSize_sunSizeLightSpace_pad[2];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxBoolean RejectLitPixels()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[0];
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxBoolean UseCascadesForRayT()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[1];
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[2];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return bRejectLitPixels_bUseCascadesForRayT_normalsUnpackMul_unpackAdd[3];
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeScale(int index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeScale[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x4 CascadeOffset(int index)
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return cascadeOffset[index];
|
||||
#else
|
||||
return FfxFloat32x4(0,0,0,0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 ViewToWorld()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return viewToWorld;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 LightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return lightView;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InverseLightView()
|
||||
{
|
||||
#if defined(FFX_CLASSIFIER_BIND_CB_CLASSIFIER)
|
||||
return inverseLightView;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH
|
||||
Texture2D<FfxFloat32x4> r_input_depth : FFX_CLASSIFIER_DECLARE_SRV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_DEPTH);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS
|
||||
Texture2D<FfxFloat32x4> r_input_normal : FFX_CLASSIFIER_DECLARE_SRV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_NORMAL);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS
|
||||
Texture2D<FfxFloat32> r_input_shadowMap[4] : FFX_CLASSIFIER_DECLARE_SRV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_INPUT_SHADOW_MAPS);
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES
|
||||
RWStructuredBuffer<FfxUInt32x4> rwsb_tiles : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_WORK_QUEUE);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT
|
||||
globallycoherent RWStructuredBuffer<FfxUInt32> rwb_tileCount : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_WORK_QUEUE_COUNTER);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT
|
||||
RWTexture2D<FfxUInt32> rwt2d_rayHitResults : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_RAY_HIT);
|
||||
#endif
|
||||
#if defined FFX_CLASSIFIER_BIND_UAV_OUTPUT_TEXTURE
|
||||
RWTexture2D<FfxFloat32x4> rwt2d_output : FFX_CLASSIFIER_DECLARE_UAV(FFX_CLASSIFIER_RESOURCE_IDENTIFIER_OUTPUT_COLOR);
|
||||
#endif
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
FfxFloat32 FfxClassifierSampleDepth(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
return r_input_depth[uiPxPos].r;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_DEPTH)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
FfxFloat32x3 FfxClassifierSampleNormal(FfxUInt32x2 uiPxPos)
|
||||
{
|
||||
FfxFloat32x3 normal = r_input_normal[uiPxPos].rgb;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
return normalize(normal);
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_NORMALS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
FfxFloat32 FfxClassifierSampleShadowMap(FfxFloat32x2 sampleUV, FfxUInt32 cascadeIndex)
|
||||
{
|
||||
return r_input_shadowMap[NonUniformResourceIndex(cascadeIndex)][FfxUInt32x2(sampleUV)];
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_SRV_INPUT_SHADOW_MAPS)
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
void FfxClassifierStoreLightMask(FfxUInt32x2 index, FfxUInt32 lightMask)
|
||||
{
|
||||
rwt2d_rayHitResults[index] = ~lightMask;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_RAY_HIT)
|
||||
|
||||
FfxUInt32 CountBits(const FfxUInt32 mask)
|
||||
{
|
||||
return countbits(mask);
|
||||
}
|
||||
|
||||
#if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
void FfxClassifierStoreTile(FfxUInt32x4 uiTile)
|
||||
{
|
||||
uint index = ~0;
|
||||
InterlockedAdd(rwb_tileCount[0], 1, index);
|
||||
rwsb_tiles[index] = uiTile;
|
||||
}
|
||||
#endif // #if defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES) || defined(FFX_CLASSIFIER_BIND_UAV_OUTPUT_WORK_TILES_COUNT)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
52
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/CMakeCompileDenoiserShaders.txt
vendored
Normal file
52
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/CMakeCompileDenoiserShaders.txt
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# 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(DENOISER_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(DENOISER_PERMUTATION_ARGS
|
||||
-DFFX_DENOISER_OPTION_INVERTED_DEPTH={0,1})
|
||||
|
||||
set(DENOISER_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/denoiser")
|
||||
|
||||
if (NOT DENOISER_SHADER_EXT)
|
||||
set(DENOISER_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB DENOISER_SHADERS
|
||||
"shaders/denoiser/ffx_denoiser_prepare_shadow_mask_pass.${DENOISER_SHADER_EXT}"
|
||||
"shaders/denoiser/ffx_denoiser_shadows_tile_classification_pass.${DENOISER_SHADER_EXT}"
|
||||
"shaders/denoiser/ffx_denoiser_filter_soft_shadows_0_pass.${DENOISER_SHADER_EXT}"
|
||||
"shaders/denoiser/ffx_denoiser_filter_soft_shadows_1_pass.${DENOISER_SHADER_EXT}"
|
||||
"shaders/denoiser/ffx_denoiser_filter_soft_shadows_2_pass.${DENOISER_SHADER_EXT}"
|
||||
"shaders/denoiser/ffx_denoiser_prefilter_reflections_pass.${DENOISER_SHADER_EXT}"
|
||||
"shaders/denoiser/ffx_denoiser_reproject_reflections_pass.${DENOISER_SHADER_EXT}"
|
||||
"shaders/denoiser/ffx_denoiser_resolve_temporal_reflections_pass.${DENOISER_SHADER_EXT}")
|
||||
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${DENOISER_BASE_ARGS}" "${DENOISER_API_BASE_ARGS}" "${DENOISER_PERMUTATION_ARGS}" "${DENOISER_INCLUDE_ARGS}"
|
||||
"${DENOISER_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" DENOISER_PERMUTATION_OUTPUTS)
|
||||
|
||||
add_shader_output("${DENOISER_PERMUTATION_OUTPUTS}")
|
||||
642
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_callbacks_glsl.h
vendored
Normal file
642
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,642 @@
|
||||
// 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_denoiser_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core.h"
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(DENOISER_BIND_CB_DENOISER)
|
||||
layout (set = 0, binding = DENOISER_BIND_CB_DENOISER, std140) uniform cbDenoiserReflections_t
|
||||
{
|
||||
FfxFloat32Mat4 invProjection;
|
||||
FfxFloat32Mat4 invView;
|
||||
FfxFloat32Mat4 prevViewProjection;
|
||||
FfxUInt32x2 renderSize;
|
||||
FfxFloat32x2 inverseRenderSize;
|
||||
FfxFloat32x2 motionVectorScale;
|
||||
FfxFloat32 normalsUnpackMul;
|
||||
FfxFloat32 normalsUnpackAdd;
|
||||
FfxBoolean isRoughnessPerceptual;
|
||||
FfxFloat32 temporalStabilityFactor;
|
||||
FfxFloat32 roughnessThreshold;
|
||||
} cbDenoiserReflections;
|
||||
|
||||
FfxFloat32Mat4 InvProjection()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.invProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvView()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.invView;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 PrevViewProjection()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.prevViewProjection;
|
||||
#else
|
||||
return FfxFloat32Mat4(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxUInt32x2 RenderSize()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.renderSize;
|
||||
#else
|
||||
return FfxUInt32x2(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 InverseRenderSize()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.inverseRenderSize;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.motionVectorScale;
|
||||
#else
|
||||
return FfxFloat32x2(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.normalsUnpackMul;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.normalsUnpackAdd;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxBoolean IsRoughnessPerceptual()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.isRoughnessPerceptual;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 TemporalStabilityFactor()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.temporalStabilityFactor;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 RoughnessThreshold()
|
||||
{
|
||||
#if defined DENOISER_BIND_CB_DENOISER
|
||||
return cbDenoiserReflections.roughnessThreshold;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // #if defined(DENOISER_BIND_CB_DENOISER)
|
||||
|
||||
layout (set = 0, binding = 1000) uniform sampler s_LinearSampler;
|
||||
|
||||
#if defined DENOISER_BIND_SRV_INPUT_DEPTH_HIERARCHY
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_INPUT_DEPTH_HIERARCHY) uniform texture2D r_input_depth_hierarchy;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_INPUT_MOTION_VECTORS
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_INPUT_MOTION_VECTORS) uniform texture2D r_input_motion_vectors;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_INPUT_NORMAL
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_INPUT_NORMAL) uniform texture2D r_input_normal;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_RADIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_RADIANCE) uniform texture2D r_radiance;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_RADIANCE_HISTORY
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_RADIANCE_HISTORY) uniform texture2D r_radiance_history;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_VARIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_VARIANCE) uniform texture2D r_variance;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_SAMPLE_COUNT
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_SAMPLE_COUNT) uniform texture2D r_sample_count;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_AVERAGE_RADIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_AVERAGE_RADIANCE) uniform texture2D r_average_radiance;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS) uniform texture2D r_extracted_roughness;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_DEPTH_HISTORY
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_DEPTH_HISTORY) uniform texture2D r_depth_history;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_NORMAL_HISTORY
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_NORMAL_HISTORY) uniform texture2D r_normal_history;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_ROUGHNESS_HISTORY
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_ROUGHNESS_HISTORY) uniform texture2D r_roughness_history;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_REPROJECTED_RADIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_SRV_REPROJECTED_RADIANCE) uniform texture2D r_reprojected_radiance;
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined DENOISER_BIND_UAV_RADIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_UAV_RADIANCE, rgba16f) uniform image2D rw_radiance;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_VARIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_UAV_VARIANCE, r16f) uniform image2D rw_variance;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_SAMPLE_COUNT
|
||||
layout (set = 0, binding = DENOISER_BIND_UAV_SAMPLE_COUNT, r16f) uniform image2D rw_sample_count;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_AVERAGE_RADIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_UAV_AVERAGE_RADIANCE, r11f_g11f_b10f) uniform image2D rw_average_radiance;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_DENOISER_TILE_LIST
|
||||
layout (set = 0, binding = DENOISER_BIND_UAV_DENOISER_TILE_LIST, std430) buffer rw_denoiser_tile_list_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_denoiser_tile_list;
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_REPROJECTED_RADIANCE
|
||||
layout (set = 0, binding = DENOISER_BIND_UAV_REPROJECTED_RADIANCE, rgba16f) uniform image2D rw_reprojected_radiance;
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
FfxFloat16x3 FFX_DENOISER_LoadWorldSpaceNormalH(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined(DENOISER_BIND_SRV_INPUT_NORMAL)
|
||||
return normalize(FfxFloat16x3(NormalsUnpackMul() * texelFetch(r_input_normal, pixel_coordinate, 0).xyz + NormalsUnpackAdd()));
|
||||
#else
|
||||
return FfxFloat16x3(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat16x3 LoadRadianceH(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
return FfxFloat16x3(texelFetch(r_radiance, coordinate.xy, coordinate.z).xyz);
|
||||
#else
|
||||
return FfxFloat16x3(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat16 LoadVarianceH(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
return FfxFloat16(texelFetch(r_variance, coordinate.xy, coordinate.z).x);
|
||||
#else
|
||||
return FfxFloat16(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_SampleAverageRadiance(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat16x3(textureLod(sampler2D(r_average_radiance, s_LinearSampler), uv, 0.0f).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadRoughness(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
FfxFloat16 rawRoughness = FfxFloat16(texelFetch(r_extracted_roughness, pixel_coordinate, 0).x);
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
|
||||
void StoreRadianceH(FfxInt32x2 coordinate, FfxFloat16x4 radiance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_RADIANCE)
|
||||
imageStore(rw_radiance, coordinate, radiance);
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreVarianceH(FfxInt32x2 coordinate, FfxFloat16 variance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_VARIANCE)
|
||||
imageStore(rw_variance, coordinate, FfxFloat16x4(variance));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StorePrefilteredReflections(FfxInt32x2 pixel_coordinate, FfxFloat16x3 radiance, FfxFloat16 variance)
|
||||
{
|
||||
StoreRadianceH(pixel_coordinate, radiance.xyzz);
|
||||
StoreVarianceH(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreTemporalAccumulation(FfxInt32x2 pixel_coordinate, FfxFloat16x3 radiance, FfxFloat16 variance)
|
||||
{
|
||||
StoreRadianceH(pixel_coordinate, radiance.xyzz);
|
||||
StoreVarianceH(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadRadianceHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat16x3(texelFetch(r_radiance_history, pixel_coordinate, 0).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_SampleRadianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat16x3(textureLod(sampler2D(r_radiance_history, s_LinearSampler), uv, 0.0f).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
FfxFloat16 FFX_DNSR_Reflections_SampleVarianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat16(textureLod(sampler2D(r_variance, s_LinearSampler), uv, 0.0f).x);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat16 FFX_DNSR_Reflections_SampleNumSamplesHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat16(textureLod(sampler2D(r_sample_count, s_LinearSampler), uv, 0.0f).x);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreRadianceReprojected(FfxInt32x2 pixel_coordinate, FfxFloat16x3 value)
|
||||
{
|
||||
imageStore(rw_reprojected_radiance, pixel_coordinate, FfxFloat16x4(value, 0.0f));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreAverageRadiance(FfxInt32x2 pixel_coordinate, FfxFloat16x3 value)
|
||||
{
|
||||
imageStore(rw_average_radiance, pixel_coordinate, FfxFloat16x4(value, 0.0f));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FFX_DENOISER_LoadWorldSpaceNormalH(pixel_coordinate);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
FfxFloat16 FFX_DNSR_Reflections_SampleRoughnessHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat16 rawRoughness = FfxFloat16(textureLod(sampler2D(r_roughness_history, s_LinearSampler), uv, 0.0f).x);
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return normalize(FfxFloat16x3(NormalsUnpackMul() * texelFetch(r_normal_history, pixel_coordinate.xy, 0).xyz + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return normalize(FfxFloat16x3(NormalsUnpackMul() * textureLod(sampler2D(r_normal_history, s_LinearSampler), uv, 0.0f).xyz + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadRayLength(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat16(texelFetch(r_radiance, pixel_coordinate, 0).w);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
|
||||
void FFX_DNSR_Reflections_StoreVariance(FfxInt32x2 pixel_coordinate, FfxFloat16 value)
|
||||
{
|
||||
StoreVarianceH(pixel_coordinate, value);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
void FFX_DNSR_Reflections_StoreNumSamples(FfxInt32x2 pixel_coordinate, FfxFloat16 value)
|
||||
{
|
||||
imageStore(rw_sample_count, pixel_coordinate, FfxFloat16x4(value));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadRadiance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadRadianceH(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadRadianceReprojected(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat16x3(texelFetch(r_reprojected_radiance, pixel_coordinate, 0).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadVariance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadVarianceH(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadNumSamples(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat16(texelFetch(r_sample_count, pixel_coordinate, 0).x);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
FfxFloat32x3 LoadRadiance(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
return texelFetch(r_radiance, coordinate.xy, coordinate.z).xyz;
|
||||
#else
|
||||
return FfxFloat32x3(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 LoadVariance(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
return texelFetch(r_variance, coordinate.xy, coordinate.z).x;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_DENOISER_LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined(DENOISER_BIND_SRV_INPUT_NORMAL)
|
||||
return normalize(NormalsUnpackMul() * texelFetch(r_input_normal, pixel_coordinate, 0).xyz + NormalsUnpackAdd());
|
||||
#else
|
||||
return FfxFloat32x3(0.0f);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadRoughness(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
FfxFloat32 rawRoughness = FfxFloat32(texelFetch(r_extracted_roughness, pixel_coordinate, 0).x);
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
|
||||
void StoreRadiance(FfxInt32x2 coordinate, FfxFloat32x4 radiance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_RADIANCE)
|
||||
imageStore(rw_radiance, coordinate, radiance);
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreVariance(FfxInt32x2 coordinate, FfxFloat32 variance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_VARIANCE)
|
||||
imageStore(rw_variance, coordinate, FfxFloat32x4(variance));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StorePrefilteredReflections(FfxInt32x2 pixel_coordinate, FfxFloat32x3 radiance, FfxFloat32 variance)
|
||||
{
|
||||
StoreRadiance(pixel_coordinate, radiance.xyzz);
|
||||
StoreVariance(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreTemporalAccumulation(FfxInt32x2 pixel_coordinate, FfxFloat32x3 radiance, FfxFloat32 variance)
|
||||
{
|
||||
StoreRadiance(pixel_coordinate, radiance.xyzz);
|
||||
StoreVariance(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_SampleAverageRadiance(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat32x3(textureLod(sampler2D(r_average_radiance, s_LinearSampler), uv, 0.0f).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadRadianceHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat32x3(texelFetch(r_radiance_history, pixel_coordinate, 0).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_SampleRadianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat32x3(textureLod(sampler2D(r_radiance_history, s_LinearSampler), uv, 0.0f).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleVarianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat32(textureLod(sampler2D(r_variance, s_LinearSampler), uv, 0.0f).x);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleNumSamplesHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return FfxFloat32(textureLod(sampler2D(r_sample_count, s_LinearSampler), uv, 0.0f).x);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreRadianceReprojected(FfxInt32x2 pixel_coordinate, FfxFloat32x3 value)
|
||||
{
|
||||
imageStore(rw_reprojected_radiance, pixel_coordinate, FfxFloat32x4(value, 0.0f));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreAverageRadiance(FfxInt32x2 pixel_coordinate, FfxFloat32x3 value)
|
||||
{
|
||||
imageStore(rw_average_radiance, pixel_coordinate, FfxFloat32x4(value, 0.0f));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FFX_DENOISER_LoadWorldSpaceNormal(pixel_coordinate);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleRoughnessHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat32 rawRoughness = FfxFloat32(textureLod(sampler2D(r_roughness_history, s_LinearSampler), uv, 0.0f).x);
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return normalize(FfxFloat32x3(NormalsUnpackMul() * texelFetch(r_normal_history, pixel_coordinate.xy, 0).xyz + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return normalize(FfxFloat32x3(NormalsUnpackMul() * textureLod(sampler2D(r_normal_history, s_LinearSampler), uv, 0.0f).xyz + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadRayLength(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat32(texelFetch(r_radiance, pixel_coordinate, 0).w);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
|
||||
void FFX_DNSR_Reflections_StoreVariance(FfxInt32x2 pixel_coordinate, FfxFloat32 value)
|
||||
{
|
||||
StoreVariance(pixel_coordinate, value);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
void FFX_DNSR_Reflections_StoreNumSamples(FfxInt32x2 pixel_coordinate, FfxFloat32 value)
|
||||
{
|
||||
imageStore(rw_sample_count, pixel_coordinate, FfxFloat32x4(value));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadRadiance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadRadiance(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadRadianceReprojected(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat32x3(texelFetch(r_reprojected_radiance, pixel_coordinate, 0).xyz);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadVariance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadVariance(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadNumSamples(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FfxFloat32(texelFetch(r_sample_count, pixel_coordinate, 0).x);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#endif // #if defined(FFX_HALF)
|
||||
|
||||
FfxFloat32 FFX_DENOISER_LoadDepth(FfxInt32x2 pixel_coordinate, FfxInt32 mip)
|
||||
{
|
||||
#if defined(DENOISER_BIND_SRV_INPUT_DEPTH_HIERARCHY)
|
||||
return texelFetch(r_input_depth_hierarchy, pixel_coordinate, mip).x;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
FfxUInt32 GetDenoiserTile(FfxUInt32 group_id)
|
||||
{
|
||||
return rw_denoiser_tile_list.data[group_id];
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
FfxFloat32x2 FFX_DNSR_Reflections_LoadMotionVector(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return MotionVectorScale() * texelFetch(r_input_motion_vectors, pixel_coordinate, 0).xy;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadDepth(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FFX_DENOISER_LoadDepth(pixel_coordinate, 0);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadDepthHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return texelFetch(r_depth_history, pixel_coordinate, 0).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleDepthHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return textureLod(sampler2D(r_depth_history, s_LinearSampler), uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
647
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_callbacks_hlsl.h
vendored
Normal file
647
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,647 @@
|
||||
// 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_denoiser_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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#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_DENOISER_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_DENOISER_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_DENOISER_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(DENOISER_BIND_CB_DENOISER)
|
||||
cbuffer cbDenoiserReflections : FFX_DENOISER_DECLARE_CB(DENOISER_BIND_CB_DENOISER)
|
||||
{
|
||||
FfxFloat32Mat4 invProjection;
|
||||
FfxFloat32Mat4 invView;
|
||||
FfxFloat32Mat4 prevViewProjection;
|
||||
FfxUInt32x2 renderSize;
|
||||
FfxFloat32x2 inverseRenderSize;
|
||||
FfxFloat32x2 motionVectorScale;
|
||||
FfxFloat32 normalsUnpackMul;
|
||||
FfxFloat32 normalsUnpackAdd;
|
||||
FfxBoolean isRoughnessPerceptual;
|
||||
FfxFloat32 temporalStabilityFactor;
|
||||
FfxFloat32 roughnessThreshold;
|
||||
#define FFX_DENOISER_CONSTANT_BUFFER_1_SIZE 54 // Number of 32-bit values. This must be kept in sync with the cbDenoiser size.
|
||||
};
|
||||
#else
|
||||
#define invProjection 0
|
||||
#define invView 0
|
||||
#define prevViewProjection 0
|
||||
#define renderSize 0
|
||||
#define inverseRenderSize 0
|
||||
#define motionVectorScale 0
|
||||
#define normalsUnpackMul 0
|
||||
#define normalsUnpackAdd 0
|
||||
#define isRoughnessPerceptual 0
|
||||
#define temporalStabilityFactor 0
|
||||
#define roughnessThreshold 0
|
||||
#endif
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#define FFX_DENOISER_ROOTSIG_STRINGIFY(p) FFX_DENOISER_ROOTSIG_STR(p)
|
||||
#define FFX_DENOISER_ROOTSIG_STR(p) #p
|
||||
#define FFX_DENOISER_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_DENOISER_ROOTSIG_STRINGIFY(FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_DENOISER_ROOTSIG_STRINGIFY(FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0), " \
|
||||
"StaticSampler(s0, filter = FILTER_MIN_MAG_LINEAR_MIP_POINT, " \
|
||||
"addressU = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressV = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"addressW = TEXTURE_ADDRESS_CLAMP, " \
|
||||
"comparisonFunc = COMPARISON_ALWAYS, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_TRANSPARENT_BLACK, " \
|
||||
"maxAnisotropy = 1)" )]
|
||||
|
||||
#if defined(FFX_DENOISER_EMBED_ROOTSIG)
|
||||
#define FFX_DENOISER_EMBED_ROOTSIG_CONTENT FFX_DENOISER_ROOTSIG
|
||||
#else
|
||||
#define FFX_DENOISER_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_DENOISER_EMBED_ROOTSIG
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
SamplerState s_LinearSampler : register(s0);
|
||||
|
||||
FfxFloat32Mat4 InvProjection()
|
||||
{
|
||||
return invProjection;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 InvView()
|
||||
{
|
||||
return invView;
|
||||
}
|
||||
|
||||
FfxFloat32Mat4 PrevViewProjection()
|
||||
{
|
||||
return prevViewProjection;
|
||||
}
|
||||
|
||||
FfxUInt32x2 RenderSize()
|
||||
{
|
||||
return renderSize;
|
||||
}
|
||||
|
||||
FfxFloat32x2 InverseRenderSize()
|
||||
{
|
||||
return inverseRenderSize;
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
return motionVectorScale;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
return normalsUnpackMul;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
return normalsUnpackAdd;
|
||||
}
|
||||
|
||||
FfxBoolean IsRoughnessPerceptual()
|
||||
{
|
||||
return isRoughnessPerceptual;
|
||||
}
|
||||
|
||||
FfxFloat32 TemporalStabilityFactor()
|
||||
{
|
||||
return temporalStabilityFactor;
|
||||
}
|
||||
|
||||
FfxFloat32 RoughnessThreshold()
|
||||
{
|
||||
return roughnessThreshold;
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined DENOISER_BIND_SRV_INPUT_DEPTH_HIERARCHY
|
||||
Texture2D<FfxFloat32> r_input_depth_hierarchy : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_INPUT_DEPTH_HIERARCHY);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_INPUT_MOTION_VECTORS
|
||||
Texture2D<FfxFloat32x2> r_input_motion_vectors : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_INPUT_MOTION_VECTORS);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_INPUT_NORMAL
|
||||
Texture2D<FfxFloat32x3> r_input_normal : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_INPUT_NORMAL);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_RADIANCE
|
||||
Texture2D<FfxFloat32x4> r_radiance : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_RADIANCE);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_RADIANCE_HISTORY
|
||||
Texture2D<FfxFloat32x4> r_radiance_history : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_RADIANCE_HISTORY);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_VARIANCE
|
||||
Texture2D<FfxFloat32> r_variance : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_VARIANCE);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_SAMPLE_COUNT
|
||||
Texture2D<FfxFloat32> r_sample_count : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_SAMPLE_COUNT);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_AVERAGE_RADIANCE
|
||||
Texture2D<FfxFloat32x3> r_average_radiance : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_AVERAGE_RADIANCE);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS
|
||||
Texture2D<FfxFloat32> r_extracted_roughness : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_DEPTH_HISTORY
|
||||
Texture2D<FfxFloat32> r_depth_history : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_DEPTH_HISTORY);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_NORMAL_HISTORY
|
||||
Texture2D<FfxFloat32x3> r_normal_history : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_NORMAL_HISTORY);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_ROUGHNESS_HISTORY
|
||||
Texture2D<FfxFloat32> r_roughness_history : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_ROUGHNESS_HISTORY);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_SRV_REPROJECTED_RADIANCE
|
||||
Texture2D<FfxFloat32x4> r_reprojected_radiance : FFX_DENOISER_DECLARE_SRV(DENOISER_BIND_SRV_REPROJECTED_RADIANCE);
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined DENOISER_BIND_UAV_RADIANCE
|
||||
RWTexture2D<FfxFloat32x4> rw_radiance : FFX_DENOISER_DECLARE_UAV(DENOISER_BIND_UAV_RADIANCE);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_VARIANCE
|
||||
RWTexture2D<FfxFloat32> rw_variance : FFX_DENOISER_DECLARE_UAV(DENOISER_BIND_UAV_VARIANCE);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_SAMPLE_COUNT
|
||||
RWTexture2D<FfxFloat32> rw_sample_count : FFX_DENOISER_DECLARE_UAV(DENOISER_BIND_UAV_SAMPLE_COUNT);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_AVERAGE_RADIANCE
|
||||
RWTexture2D<FfxFloat32x3> rw_average_radiance : FFX_DENOISER_DECLARE_UAV(DENOISER_BIND_UAV_AVERAGE_RADIANCE);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_DENOISER_TILE_LIST
|
||||
RWStructuredBuffer<FfxUInt32> rw_denoiser_tile_list : FFX_DENOISER_DECLARE_UAV(DENOISER_BIND_UAV_DENOISER_TILE_LIST);
|
||||
#endif
|
||||
#if defined DENOISER_BIND_UAV_REPROJECTED_RADIANCE
|
||||
RWTexture2D<FfxFloat32x3> rw_reprojected_radiance : FFX_DENOISER_DECLARE_UAV(DENOISER_BIND_UAV_REPROJECTED_RADIANCE);
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
|
||||
FfxFloat16x3 FFX_DENOISER_LoadWorldSpaceNormalH(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined(DENOISER_BIND_SRV_INPUT_NORMAL)
|
||||
return normalize((FfxFloat16x3)(NormalsUnpackMul() * r_input_normal.Load(FfxInt32x3(pixel_coordinate, 0)) + NormalsUnpackAdd()));
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif // #if defined(DENOISER_BIND_SRV_INPUT_NORMAL)
|
||||
}
|
||||
|
||||
FfxFloat16x3 LoadRadianceH(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
return (FfxFloat16x3)r_radiance.Load(coordinate).xyz;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
}
|
||||
|
||||
FfxFloat16 LoadVarianceH(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
return (FfxFloat16)r_variance.Load(coordinate).x;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif // #if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_SampleAverageRadiance(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat16x3)r_average_radiance.SampleLevel(s_LinearSampler, uv, 0.0f).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadRoughness(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
FfxFloat16 rawRoughness = (FfxFloat16)r_extracted_roughness.Load(FfxInt32x3(pixel_coordinate, 0));
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
|
||||
void StoreRadianceH(FfxInt32x2 coordinate, FfxFloat16x4 radiance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_RADIANCE)
|
||||
rw_radiance[coordinate] = radiance;
|
||||
#endif // #if defined (DENOISER_BIND_UAV_RADIANCE)
|
||||
}
|
||||
|
||||
void StoreVarianceH(FfxInt32x2 coordinate, FfxFloat16 variance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_VARIANCE)
|
||||
rw_variance[coordinate] = variance;
|
||||
#endif // #if defined (DENOISER_BIND_UAV_VARIANCE)
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StorePrefilteredReflections(FfxInt32x2 pixel_coordinate, FfxFloat16x3 radiance, FfxFloat16 variance)
|
||||
{
|
||||
StoreRadianceH(pixel_coordinate, radiance.xyzz);
|
||||
StoreVarianceH(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreTemporalAccumulation(FfxInt32x2 pixel_coordinate, FfxFloat16x3 radiance, FfxFloat16 variance)
|
||||
{
|
||||
StoreRadianceH(pixel_coordinate, radiance.xyzz);
|
||||
StoreVarianceH(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadRadianceHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat16x3)r_radiance_history.Load(FfxInt32x3(pixel_coordinate, 0)).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_SampleRadianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat16x3)r_radiance_history.SampleLevel(s_LinearSampler, uv, 0.0f).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
FfxFloat16 FFX_DNSR_Reflections_SampleVarianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat16)r_variance.SampleLevel(s_LinearSampler, uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat16 FFX_DNSR_Reflections_SampleNumSamplesHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat16)r_sample_count.SampleLevel(s_LinearSampler, uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreRadianceReprojected(FfxInt32x2 pixel_coordinate, FfxFloat16x3 value)
|
||||
{
|
||||
rw_reprojected_radiance[pixel_coordinate] = value;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreAverageRadiance(FfxInt32x2 pixel_coordinate, FfxFloat16x3 value)
|
||||
{
|
||||
rw_average_radiance[pixel_coordinate] = value;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FFX_DENOISER_LoadWorldSpaceNormalH(pixel_coordinate);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
FfxFloat16 FFX_DNSR_Reflections_SampleRoughnessHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat16 rawRoughness = (FfxFloat16)r_roughness_history.SampleLevel(s_LinearSampler, uv, 0.0f);
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return normalize((FfxFloat16x3)(NormalsUnpackMul() * r_normal_history.Load(FfxInt32x3(pixel_coordinate, 0)) + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return normalize((FfxFloat16x3)(NormalsUnpackMul() * r_normal_history.SampleLevel(s_LinearSampler, uv, 0.0f) + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadRayLength(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat16)r_radiance.Load(FfxInt32x3(pixel_coordinate, 0)).w;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
|
||||
void FFX_DNSR_Reflections_StoreVariance(FfxInt32x2 pixel_coordinate, FfxFloat16 value)
|
||||
{
|
||||
StoreVarianceH(pixel_coordinate, value);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
void FFX_DNSR_Reflections_StoreNumSamples(FfxInt32x2 pixel_coordinate, FfxFloat16 value)
|
||||
{
|
||||
rw_sample_count[pixel_coordinate] = value;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadRadiance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadRadianceH(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_LoadRadianceReprojected(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat16x3)r_reprojected_radiance.Load(FfxInt32x3(pixel_coordinate, 0)).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadVariance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadVarianceH(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat16 FFX_DNSR_Reflections_LoadNumSamples(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat16)r_sample_count.Load(FfxInt32x3(pixel_coordinate, 0)).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
FfxFloat32x3 LoadRadiance(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
return r_radiance.Load(coordinate).xyz;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32 LoadVariance(FfxInt32x3 coordinate)
|
||||
{
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
return r_variance.Load(coordinate).x;
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_DENOISER_LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
#if defined(DENOISER_BIND_SRV_INPUT_NORMAL)
|
||||
return normalize(NormalsUnpackMul() * r_input_normal.Load(FfxInt32x3(pixel_coordinate, 0)) + NormalsUnpackAdd());
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadRoughness(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
FfxFloat32 rawRoughness = (FfxFloat32)r_extracted_roughness.Load(FfxInt32x3(pixel_coordinate, 0));
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_EXTRACTED_ROUGHNESS)
|
||||
|
||||
void StoreRadiance(FfxInt32x2 coordinate, FfxFloat32x4 radiance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_RADIANCE)
|
||||
rw_radiance[coordinate] = radiance;
|
||||
#endif
|
||||
}
|
||||
|
||||
void StoreVariance(FfxInt32x2 coordinate, FfxFloat32 variance)
|
||||
{
|
||||
#if defined (DENOISER_BIND_UAV_VARIANCE)
|
||||
rw_variance[coordinate] = variance;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StorePrefilteredReflections(FfxInt32x2 pixel_coordinate, FfxFloat32x3 radiance, FfxFloat32 variance)
|
||||
{
|
||||
StoreRadiance(pixel_coordinate, radiance.xyzz);
|
||||
StoreVariance(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreTemporalAccumulation(FfxInt32x2 pixel_coordinate, FfxFloat32x3 radiance, FfxFloat32 variance)
|
||||
{
|
||||
StoreRadiance(pixel_coordinate, radiance.xyzz);
|
||||
StoreVariance(pixel_coordinate, variance.x);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_SampleAverageRadiance(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat32x3)r_average_radiance.SampleLevel(s_LinearSampler, uv, 0.0f).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_AVERAGE_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadRadianceHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat32x3)r_radiance_history.Load(FfxInt32x3(pixel_coordinate, 0)).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_SampleRadianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat32x3)r_radiance_history.SampleLevel(s_LinearSampler, uv, 0.0f).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleVarianceHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat32)r_variance.SampleLevel(s_LinearSampler, uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_VARIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleNumSamplesHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return (FfxFloat32)r_sample_count.SampleLevel(s_LinearSampler, uv, 0.0f).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreRadianceReprojected(FfxInt32x2 pixel_coordinate, FfxFloat32x3 value)
|
||||
{
|
||||
rw_reprojected_radiance[pixel_coordinate] = value;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_REPROJECTED_RADIANCE)
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
void FFX_DNSR_Reflections_StoreAverageRadiance(FfxInt32x2 pixel_coordinate, FfxFloat32x3 value)
|
||||
{
|
||||
rw_average_radiance[pixel_coordinate] = value;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_AVERAGE_RADIANCE)
|
||||
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadWorldSpaceNormal(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FFX_DENOISER_LoadWorldSpaceNormal(pixel_coordinate);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleRoughnessHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
FfxFloat32 rawRoughness = (FfxFloat32)r_roughness_history.SampleLevel(s_LinearSampler, uv, 0.0f);
|
||||
if (IsRoughnessPerceptual())
|
||||
{
|
||||
rawRoughness *= rawRoughness;
|
||||
}
|
||||
|
||||
return rawRoughness;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_ROUGHNESS_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return normalize((FfxFloat32x3)(NormalsUnpackMul() * r_normal_history.Load(FfxInt32x3(pixel_coordinate, 0)) + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return normalize((FfxFloat32x3)(NormalsUnpackMul() * r_normal_history.SampleLevel(s_LinearSampler, uv, 0.0f) + NormalsUnpackAdd()));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_NORMAL_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadRayLength(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat32)r_radiance.Load(FfxInt32x3(pixel_coordinate, 0)).w;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_RADIANCE)
|
||||
|
||||
void FFX_DNSR_Reflections_StoreVariance(FfxInt32x2 pixel_coordinate, FfxFloat32 value)
|
||||
{
|
||||
StoreVariance(pixel_coordinate, value);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
void FFX_DNSR_Reflections_StoreNumSamples(FfxInt32x2 pixel_coordinate, FfxFloat32 value)
|
||||
{
|
||||
rw_sample_count[pixel_coordinate] = value;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_SAMPLE_COUNT)
|
||||
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadRadiance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadRadiance(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_LoadRadianceReprojected(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat32x3)r_reprojected_radiance.Load(FfxInt32x3(pixel_coordinate, 0)).xyz;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_REPROJECTED_RADIANCE)
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadVariance(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return LoadVariance(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadNumSamples(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return (FfxFloat32)r_sample_count.Load(FfxInt32x3(pixel_coordinate, 0)).x;
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_SAMPLE_COUNT)
|
||||
|
||||
#endif // #if defined(FFX_HALF)
|
||||
|
||||
FfxFloat32 FFX_DENOISER_LoadDepth(FfxInt32x2 pixel_coordinate, FfxInt32 mip)
|
||||
{
|
||||
#if defined(DENOISER_BIND_SRV_INPUT_DEPTH_HIERARCHY)
|
||||
return r_input_depth_hierarchy.Load(FfxInt32x3(pixel_coordinate, mip));
|
||||
#else
|
||||
return 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
FfxUInt32 GetDenoiserTile(FfxUInt32 group_id)
|
||||
{
|
||||
return rw_denoiser_tile_list[group_id];
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_UAV_DENOISER_TILE_LIST)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
FfxFloat32x2 FFX_DNSR_Reflections_LoadMotionVector(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return MotionVectorScale() * r_input_motion_vectors.Load(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_INPUT_MOTION_VECTORS)
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadDepth(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return FFX_DENOISER_LoadDepth(pixel_coordinate, 0);
|
||||
}
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
FfxFloat32 FFX_DNSR_Reflections_LoadDepthHistory(FfxInt32x2 pixel_coordinate)
|
||||
{
|
||||
return r_depth_history.Load(FfxInt32x3(pixel_coordinate, 0));
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
|
||||
#if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
FfxFloat32 FFX_DNSR_Reflections_SampleDepthHistory(FfxFloat32x2 uv)
|
||||
{
|
||||
return r_depth_history.SampleLevel(s_LinearSampler, uv, 0.0f);
|
||||
}
|
||||
#endif // #if defined (DENOISER_BIND_SRV_DEPTH_HISTORY)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
286
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_common.h
vendored
Normal file
286
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_common.h
vendored
Normal file
@@ -0,0 +1,286 @@
|
||||
// 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_DNSR_REFLECTIONS_COMMON
|
||||
#define FFX_DNSR_REFLECTIONS_COMMON
|
||||
|
||||
#include "ffx_denoiser_reflections_config.h"
|
||||
|
||||
FfxBoolean FFX_DNSR_Reflections_IsGlossyReflection(FfxFloat32 roughness) {
|
||||
return roughness < RoughnessThreshold();
|
||||
}
|
||||
|
||||
FfxBoolean FFX_DNSR_Reflections_IsMirrorReflection(FfxFloat32 roughness) {
|
||||
return roughness < 0.0001;
|
||||
}
|
||||
|
||||
// Transforms origin to uv space
|
||||
// Mat must be able to transform origin from its current space into clip space.
|
||||
FfxFloat32x3 ProjectPosition(FfxFloat32x3 origin, FfxFloat32Mat4 mat) {
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(mat, FfxFloat32x4(origin, 1));
|
||||
projected.xyz /= projected.w;
|
||||
projected.xy = 0.5 * projected.xy + 0.5;
|
||||
projected.y = (1 - projected.y);
|
||||
return projected.xyz;
|
||||
}
|
||||
|
||||
// Mat must be able to transform origin from texture space to a linear space.
|
||||
FfxFloat32x3 FFX_DNSR_InvProjectPosition(FfxFloat32x3 coord, FfxFloat32Mat4 mat) {
|
||||
coord.y = (1 - coord.y);
|
||||
coord.xy = 2 * coord.xy - 1;
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(mat, FfxFloat32x4(coord, 1));
|
||||
projected.xyz /= projected.w;
|
||||
return projected.xyz;
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_GetLinearDepth(FfxFloat32x2 uv, FfxFloat32 depth) {
|
||||
const FfxFloat32x3 view_space_pos = FFX_DNSR_InvProjectPosition(FfxFloat32x3(uv, depth), InvProjection());
|
||||
return abs(view_space_pos.z);
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_ScreenSpaceToViewSpace(FfxFloat32x3 screen_uv_coord) {
|
||||
return FFX_DNSR_InvProjectPosition(screen_uv_coord, InvProjection());
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_WorldSpaceToScreenSpacePrevious(FfxFloat32x3 world_space_pos) {
|
||||
return ProjectPosition(world_space_pos, PrevViewProjection());
|
||||
}
|
||||
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_ViewSpaceToWorldSpace(FfxFloat32x4 view_space_coord) {
|
||||
return FFX_MATRIX_MULTIPLY(InvView(), view_space_coord).xyz;
|
||||
}
|
||||
|
||||
// Rounds value to the nearest multiple of 8
|
||||
FfxUInt32x2 FFX_DNSR_Reflections_RoundUp8(FfxUInt32x2 value) {
|
||||
FfxUInt32x2 round_down = value & ~7; // 0b111;
|
||||
return FFX_SELECT((round_down == value), value, value + 8);
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_Luminance(FfxFloat16x3 color)
|
||||
{
|
||||
return max(FfxFloat16(dot(color, FfxFloat16x3(0.299f, 0.587f, 0.114f))), FfxFloat16(0.001));
|
||||
}
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_ComputeTemporalVariance(FfxFloat16x3 history_radiance, FfxFloat16x3 radiance) {
|
||||
FfxFloat16 history_luminance = FFX_DNSR_Reflections_Luminance(history_radiance);
|
||||
FfxFloat16 luminance = FFX_DNSR_Reflections_Luminance(radiance);
|
||||
FfxFloat16 diff = abs(history_luminance - luminance) / max(max(history_luminance, luminance), FfxFloat16(0.5f));
|
||||
return diff * diff;
|
||||
}
|
||||
|
||||
FfxUInt32 FFX_DNSR_Reflections_PackFloat16(FfxFloat16x2 v)
|
||||
{
|
||||
#if defined(FFX_GLSL)
|
||||
return ffxPackHalf2x16(FfxFloat32x2(v));
|
||||
#elif defined(FFX_HLSL)
|
||||
FfxUInt32x2 p = ffxF32ToF16(FfxFloat32x2(v));
|
||||
return p.x | (p.y << 16);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat16x2 FFX_DNSR_Reflections_UnpackFloat16(FfxUInt32 a)
|
||||
{
|
||||
#if defined(FFX_GLSL)
|
||||
return FfxFloat16x2(unpackHalf2x16(a));
|
||||
#elif defined(FFX_HLSL)
|
||||
FfxFloat32x2 tmp = f16tof32(FfxUInt32x2(a & 0xFFFF, a >> 16));
|
||||
return FfxFloat16x2(tmp);
|
||||
#endif
|
||||
|
||||
return FfxFloat16x2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
FfxUInt32x2 FFX_DNSR_Reflections_PackFloat16_4(FfxFloat16x4 v) { return FfxUInt32x2(FFX_DNSR_Reflections_PackFloat16(v.xy), FFX_DNSR_Reflections_PackFloat16(v.zw)); }
|
||||
|
||||
FfxFloat16x4 FFX_DNSR_Reflections_UnpackFloat16_4(FfxUInt32x2 a) { return FfxFloat16x4(FFX_DNSR_Reflections_UnpackFloat16(a.x), FFX_DNSR_Reflections_UnpackFloat16(a.y)); }
|
||||
|
||||
// From "Temporal Reprojection Anti-Aliasing"
|
||||
// https://github.com/playdeadgames/temporal
|
||||
/**********************************************************************
|
||||
Copyright (c) [2015] [Playdead]
|
||||
|
||||
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.
|
||||
********************************************************************/
|
||||
FfxFloat16x3 FFX_DNSR_Reflections_ClipAABB(FfxFloat16x3 aabb_min, FfxFloat16x3 aabb_max, FfxFloat16x3 prev_sample) {
|
||||
// Main idea behind clipping - it prevents clustering when neighbor color space
|
||||
// is distant from history sample
|
||||
|
||||
// Here we find intersection between color vector and aabb color box
|
||||
|
||||
// Note: only clips towards aabb center
|
||||
FfxFloat32x3 aabb_center = 0.5 * (aabb_max + aabb_min);
|
||||
FfxFloat32x3 extent_clip = 0.5 * (aabb_max - aabb_min) + 0.001;
|
||||
|
||||
// Find color vector
|
||||
FfxFloat32x3 color_vector = prev_sample - aabb_center;
|
||||
// Transform into clip space
|
||||
FfxFloat32x3 color_vector_clip = color_vector / extent_clip;
|
||||
// Find max absolute component
|
||||
color_vector_clip = abs(color_vector_clip);
|
||||
FfxFloat16 max_abs_unit = FfxFloat16(max(max(color_vector_clip.x, color_vector_clip.y), color_vector_clip.z));
|
||||
|
||||
if (max_abs_unit > 1.0) {
|
||||
return FfxFloat16x3(aabb_center + color_vector / max_abs_unit); // clip towards color vector
|
||||
} else {
|
||||
return FfxFloat16x3(prev_sample); // point is inside aabb
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FFX_DNSR_REFLECTIONS_ESTIMATES_LOCAL_NEIGHBORHOOD
|
||||
|
||||
# ifndef FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS
|
||||
# define FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS 4
|
||||
# endif
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat16 i) {
|
||||
const FfxFloat16 radius = FfxFloat16(FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS + 1.0f);
|
||||
return FfxFloat16(exp(-FFX_DNSR_REFLECTIONS_GAUSSIAN_K * (i * i) / (radius * radius)));
|
||||
}
|
||||
|
||||
#endif // FFX_DNSR_REFLECTIONS_ESTIMATES_LOCAL_NEIGHBORHOOD
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_Luminance(FfxFloat32x3 color)
|
||||
{
|
||||
return max(FfxFloat32(dot(color, FfxFloat32x3(0.299f, 0.587f, 0.114f))), FfxFloat32(0.001));
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_ComputeTemporalVariance(FfxFloat32x3 history_radiance, FfxFloat32x3 radiance) {
|
||||
FfxFloat32 history_luminance = FFX_DNSR_Reflections_Luminance(history_radiance);
|
||||
FfxFloat32 luminance = FFX_DNSR_Reflections_Luminance(radiance);
|
||||
FfxFloat32 diff = abs(history_luminance - luminance) / max(max(history_luminance, luminance), FfxFloat32(0.5f));
|
||||
return diff * diff;
|
||||
}
|
||||
|
||||
FfxUInt32 FFX_DNSR_Reflections_PackFloat16(FfxFloat32x2 v)
|
||||
{
|
||||
#if defined(FFX_GLSL)
|
||||
return ffxPackHalf2x16(v);
|
||||
#elif defined(FFX_HLSL)
|
||||
FfxUInt32x2 p = ffxF32ToF16(v);
|
||||
return p.x | (p.y << 16);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Reflections_UnpackFloat16(FfxUInt32 a)
|
||||
{
|
||||
#if defined(FFX_GLSL)
|
||||
return unpackHalf2x16(a);
|
||||
#elif defined(FFX_HLSL)
|
||||
FfxFloat32x2 tmp = f16tof32(FfxUInt32x2(a & 0xFFFF, a >> 16));
|
||||
return tmp;
|
||||
#endif
|
||||
|
||||
return FfxFloat32x2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
FfxUInt32x2 FFX_DNSR_Reflections_PackFloat16_4(FfxFloat32x4 v) { return FfxUInt32x2(FFX_DNSR_Reflections_PackFloat16(v.xy), FFX_DNSR_Reflections_PackFloat16(v.zw)); }
|
||||
|
||||
FfxFloat32x4 FFX_DNSR_Reflections_UnpackFloat16_4(FfxUInt32x2 a) { return FfxFloat32x4(FFX_DNSR_Reflections_UnpackFloat16(a.x), FFX_DNSR_Reflections_UnpackFloat16(a.y)); }
|
||||
|
||||
// From "Temporal Reprojection Anti-Aliasing"
|
||||
// https://github.com/playdeadgames/temporal
|
||||
/**********************************************************************
|
||||
Copyright (c) [2015] [Playdead]
|
||||
|
||||
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.
|
||||
********************************************************************/
|
||||
FfxFloat32x3 FFX_DNSR_Reflections_ClipAABB(FfxFloat32x3 aabb_min, FfxFloat32x3 aabb_max, FfxFloat32x3 prev_sample) {
|
||||
// Main idea behind clipping - it prevents clustering when neighbor color space
|
||||
// is distant from history sample
|
||||
|
||||
// Here we find intersection between color vector and aabb color box
|
||||
|
||||
// Note: only clips towards aabb center
|
||||
FfxFloat32x3 aabb_center = 0.5 * (aabb_max + aabb_min);
|
||||
FfxFloat32x3 extent_clip = 0.5 * (aabb_max - aabb_min) + 0.001;
|
||||
|
||||
// Find color vector
|
||||
FfxFloat32x3 color_vector = prev_sample - aabb_center;
|
||||
// Transform into clip space
|
||||
FfxFloat32x3 color_vector_clip = color_vector / extent_clip;
|
||||
// Find max absolute component
|
||||
color_vector_clip = abs(color_vector_clip);
|
||||
FfxFloat32 max_abs_unit = FfxFloat32(max(max(color_vector_clip.x, color_vector_clip.y), color_vector_clip.z));
|
||||
|
||||
if (max_abs_unit > 1.0) {
|
||||
return FfxFloat32x3(aabb_center + color_vector / max_abs_unit); // clip towards color vector
|
||||
} else {
|
||||
return FfxFloat32x3(prev_sample); // point is inside aabb
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FFX_DNSR_REFLECTIONS_ESTIMATES_LOCAL_NEIGHBORHOOD
|
||||
|
||||
# ifndef FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS
|
||||
# define FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS 4
|
||||
# endif
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat32 i) {
|
||||
const FfxFloat32 radius = FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS + 1.0;
|
||||
return exp(-FFX_DNSR_REFLECTIONS_GAUSSIAN_K * (i * i) / (radius * radius));
|
||||
}
|
||||
|
||||
#endif // FFX_DNSR_REFLECTIONS_ESTIMATES_LOCAL_NEIGHBORHOOD
|
||||
|
||||
#endif // FFX_HALF
|
||||
|
||||
#endif // FFX_DNSR_REFLECTIONS_COMMON
|
||||
41
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_config.h
vendored
Normal file
41
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_config.h
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// 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_DNSR_REFLECTIONS_CONFIG
|
||||
#define FFX_DNSR_REFLECTIONS_CONFIG
|
||||
|
||||
#define FFX_DNSR_REFLECTIONS_GAUSSIAN_K 3.0
|
||||
#define FFX_DNSR_REFLECTIONS_RADIANCE_WEIGHT_BIAS 0.6
|
||||
#define FFX_DNSR_REFLECTIONS_RADIANCE_WEIGHT_VARIANCE_K 0.1
|
||||
#define FFX_DNSR_REFLECTIONS_AVG_RADIANCE_LUMINANCE_WEIGHT 0.3
|
||||
#define FFX_DNSR_REFLECTIONS_PREFILTER_VARIANCE_WEIGHT 4.4
|
||||
#define FFX_DNSR_REFLECTIONS_REPROJECT_SURFACE_DISCARD_VARIANCE_WEIGHT 1.5
|
||||
#define FFX_DNSR_REFLECTIONS_PREFILTER_VARIANCE_BIAS 0.1
|
||||
#define FFX_DNSR_REFLECTIONS_PREFILTER_NORMAL_SIGMA 512.0
|
||||
#define FFX_DNSR_REFLECTIONS_PREFILTER_DEPTH_SIGMA 4.0
|
||||
#define FFX_DNSR_REFLECTIONS_DISOCCLUSION_NORMAL_WEIGHT 1.4
|
||||
#define FFX_DNSR_REFLECTIONS_DISOCCLUSION_DEPTH_WEIGHT 1.0
|
||||
#define FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD 0.9
|
||||
#define FFX_DNSR_REFLECTIONS_REPROJECTION_NORMAL_SIMILARITY_THRESHOLD 0.9999
|
||||
#define FFX_DNSR_REFLECTIONS_SAMPLES_FOR_ROUGHNESS(r) (1.0 - exp(-r * 100.0))
|
||||
|
||||
#endif // FFX_DNSR_REFLECTIONS_CONFIG
|
||||
340
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_prefilter.h
vendored
Normal file
340
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_prefilter.h
vendored
Normal file
@@ -0,0 +1,340 @@
|
||||
// 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_DNSR_REFLECTIONS_PREFILTER
|
||||
#define FFX_DNSR_REFLECTIONS_PREFILTER
|
||||
|
||||
#include "ffx_denoiser_reflections_common.h"
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_0[16][16];
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_1[16][16];
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_2[16][16];
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_3[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 g_ffx_dnsr_shared_depth[16][16];
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
struct FFX_DNSR_Reflections_NeighborhoodSample {
|
||||
FfxFloat16x3 radiance;
|
||||
FfxFloat16 variance;
|
||||
FfxFloat16x3 normal;
|
||||
FfxFloat32 depth;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample FFX_DNSR_Reflections_LoadFromGroupSharedMemory(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
FfxFloat16x4 unpacked_radiance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance);
|
||||
FfxUInt32x2 packed_normal_variance = FfxUInt32x2(g_ffx_dnsr_shared_2[idx.y][idx.x], g_ffx_dnsr_shared_3[idx.y][idx.x]);
|
||||
FfxFloat16x4 unpacked_normal_variance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_normal_variance);
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighborSample;
|
||||
neighborSample.radiance = unpacked_radiance.xyz;
|
||||
neighborSample.normal = unpacked_normal_variance.xyz;
|
||||
neighborSample.variance = unpacked_normal_variance.w;
|
||||
neighborSample.depth = g_ffx_dnsr_shared_depth[idx.y][idx.x];
|
||||
return neighborSample;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat16x3 radiance, FfxFloat16 variance, FfxFloat16x3 normal, FfxFloat32 depth) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.zz);
|
||||
g_ffx_dnsr_shared_2[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(normal.xy);
|
||||
g_ffx_dnsr_shared_3[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(FfxFloat16x2(normal.z, variance));
|
||||
g_ffx_dnsr_shared_depth[group_thread_id.y][group_thread_id.x] = depth;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_LoadNeighborhood(
|
||||
FfxInt32x2 pixel_coordinate,
|
||||
FFX_PARAMETER_OUT FfxFloat16x3 radiance,
|
||||
FFX_PARAMETER_OUT FfxFloat16 variance,
|
||||
FFX_PARAMETER_OUT FfxFloat16x3 normal,
|
||||
FFX_PARAMETER_OUT FfxFloat32 depth,
|
||||
FfxInt32x2 screen_size) {
|
||||
|
||||
radiance = LoadRadianceH(FfxInt32x3(pixel_coordinate, 0));
|
||||
variance = LoadVarianceH(FfxInt32x3(pixel_coordinate, 0));
|
||||
|
||||
normal = FFX_DENOISER_LoadWorldSpaceNormalH(pixel_coordinate);
|
||||
|
||||
FfxFloat32x2 uv = (pixel_coordinate.xy + (0.5f).xx) / FfxFloat32x2(screen_size.xy);
|
||||
depth = FFX_DNSR_Reflections_GetLinearDepth(uv, FFX_DENOISER_LoadDepth(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_InitializeGroupSharedMemory(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxInt32x2 screen_size) {
|
||||
// Load 16x16 region into shared memory using 4 8x8 blocks.
|
||||
FfxInt32x2 offset[4] = {FfxInt32x2(0, 0), FfxInt32x2(8, 0), FfxInt32x2(0, 8), FfxInt32x2(8, 8)};
|
||||
|
||||
// Intermediate storage registers to cache the result of all loads
|
||||
FfxFloat16x3 radiance[4];
|
||||
FfxFloat16 variance[4];
|
||||
FfxFloat16x3 normal[4];
|
||||
FfxFloat32 depth[4];
|
||||
|
||||
// Start in the upper left corner of the 16x16 region.
|
||||
dispatch_thread_id -= 4;
|
||||
|
||||
// First store all loads in registers
|
||||
for (FfxInt32 i = 0; i < 4; ++i) {
|
||||
FFX_DNSR_Reflections_LoadNeighborhood(dispatch_thread_id + offset[i], radiance[i], variance[i], normal[i], depth[i], screen_size);
|
||||
}
|
||||
|
||||
// Then move all registers to groupshared memory
|
||||
for (FfxInt32 j = 0; j < 4; ++j) {
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id + offset[j], radiance[j], variance[j], normal[j], depth[j]); // X
|
||||
}
|
||||
}
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_GetEdgeStoppingNormalWeight(FfxFloat16x3 normal_p, FfxFloat16x3 normal_q) {
|
||||
return FfxFloat16(pow(max(dot(normal_p, normal_q), FfxFloat16(0.0f)), FFX_DNSR_REFLECTIONS_PREFILTER_NORMAL_SIGMA));
|
||||
}
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_GetEdgeStoppingDepthWeight(FfxFloat32 center_depth, FfxFloat32 neighbor_depth) {
|
||||
return FfxFloat16(exp(-abs(center_depth - neighbor_depth) * center_depth * FFX_DNSR_REFLECTIONS_PREFILTER_DEPTH_SIGMA));
|
||||
}
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_GetRadianceWeight(FfxFloat16x3 center_radiance, FfxFloat16x3 neighbor_radiance, FfxFloat16 variance) {
|
||||
return FfxFloat16(max(exp(-(FFX_DNSR_REFLECTIONS_RADIANCE_WEIGHT_BIAS + variance * FFX_DNSR_REFLECTIONS_RADIANCE_WEIGHT_VARIANCE_K)
|
||||
* length(center_radiance - neighbor_radiance.xyz))
|
||||
, 1.0e-2));
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_Resolve(FfxInt32x2 group_thread_id, FfxFloat16x3 avg_radiance, FFX_DNSR_Reflections_NeighborhoodSample center,
|
||||
out FfxFloat16x3 resolved_radiance, out FfxFloat16 resolved_variance) {
|
||||
// Initial weight is important to remove fireflies.
|
||||
// That removes quite a bit of energy but makes everything much more stable.
|
||||
FfxFloat16 accumulated_weight = FFX_DNSR_Reflections_GetRadianceWeight(avg_radiance, center.radiance.xyz, center.variance);
|
||||
FfxFloat16x3 accumulated_radiance = center.radiance.xyz * accumulated_weight;
|
||||
FfxFloat16 accumulated_variance = center.variance * accumulated_weight * accumulated_weight;
|
||||
// First 15 numbers of Halton(2,3) streteched to [-3,3]. Skipping the center, as we already have that in center_radiance and center_variance.
|
||||
const FfxUInt32 sample_count = 15;
|
||||
const FfxInt32x2 sample_offsets[] = {FfxInt32x2(0, 1), FfxInt32x2(-2, 1), FfxInt32x2(2, -3), FfxInt32x2(-3, 0), FfxInt32x2(1, 2), FfxInt32x2(-1, -2), FfxInt32x2(3, 0), FfxInt32x2(-3, 3),
|
||||
FfxInt32x2(0, -3), FfxInt32x2(-1, -1), FfxInt32x2(2, 1), FfxInt32x2(-2, -2), FfxInt32x2(1, 0), FfxInt32x2(0, 2), FfxInt32x2(3, -1)};
|
||||
FfxFloat16 variance_weight = FfxFloat16(max(FFX_DNSR_REFLECTIONS_PREFILTER_VARIANCE_BIAS,
|
||||
1.0 - exp(-(center.variance * FFX_DNSR_REFLECTIONS_PREFILTER_VARIANCE_WEIGHT))
|
||||
));
|
||||
for (FfxInt32 i = 0; i < sample_count; ++i) {
|
||||
FfxInt32x2 new_idx = group_thread_id + sample_offsets[i];
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighbor = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(new_idx);
|
||||
|
||||
FfxFloat16 weight = FfxFloat16(1.0f);
|
||||
weight *= FFX_DNSR_Reflections_GetEdgeStoppingNormalWeight(center.normal, neighbor.normal);
|
||||
weight *= FFX_DNSR_Reflections_GetEdgeStoppingDepthWeight(center.depth, neighbor.depth);
|
||||
weight *= FFX_DNSR_Reflections_GetRadianceWeight(avg_radiance, neighbor.radiance.xyz, center.variance);
|
||||
weight *= variance_weight;
|
||||
|
||||
// Accumulate all contributions.
|
||||
accumulated_weight += weight;
|
||||
accumulated_radiance += weight * neighbor.radiance.xyz;
|
||||
accumulated_variance += weight * weight * neighbor.variance;
|
||||
}
|
||||
|
||||
accumulated_radiance /= accumulated_weight;
|
||||
accumulated_variance /= (accumulated_weight * accumulated_weight);
|
||||
resolved_radiance = accumulated_radiance;
|
||||
resolved_variance = accumulated_variance;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_Prefilter(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxUInt32x2 screen_size) {
|
||||
FfxFloat16 center_roughness = FFX_DNSR_Reflections_LoadRoughness(dispatch_thread_id);
|
||||
FFX_DNSR_Reflections_InitializeGroupSharedMemory(dispatch_thread_id, group_thread_id, FfxInt32x2(screen_size));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
group_thread_id += 4; // Center threads in groupshared memory
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample center = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(group_thread_id);
|
||||
|
||||
FfxFloat16x3 resolved_radiance = center.radiance;
|
||||
FfxFloat16 resolved_variance = center.variance;
|
||||
|
||||
// Check if we have to denoise or if a simple copy is enough
|
||||
bool needs_denoiser = center.variance > 0.0 && FFX_DNSR_Reflections_IsGlossyReflection(center_roughness) && !FFX_DNSR_Reflections_IsMirrorReflection(center_roughness);
|
||||
if (needs_denoiser) {
|
||||
FfxFloat32x2 uv8 = (FfxFloat32x2(dispatch_thread_id.xy) + (0.5).xx) / FFX_DNSR_Reflections_RoundUp8(screen_size);
|
||||
FfxFloat16x3 avg_radiance = FFX_DNSR_Reflections_SampleAverageRadiance(uv8);
|
||||
FFX_DNSR_Reflections_Resolve(group_thread_id, avg_radiance, center, resolved_radiance, resolved_variance);
|
||||
}
|
||||
|
||||
FFX_DNSR_Reflections_StorePrefilteredReflections(dispatch_thread_id, resolved_radiance, resolved_variance);
|
||||
}
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
struct FFX_DNSR_Reflections_NeighborhoodSample {
|
||||
FfxFloat32x3 radiance;
|
||||
FfxFloat32 variance;
|
||||
FfxFloat32x3 normal;
|
||||
FfxFloat32 depth;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample FFX_DNSR_Reflections_LoadFromGroupSharedMemory(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
FfxFloat32x4 unpacked_radiance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance);
|
||||
FfxUInt32x2 packed_normal_variance = FfxUInt32x2(g_ffx_dnsr_shared_2[idx.y][idx.x], g_ffx_dnsr_shared_3[idx.y][idx.x]);
|
||||
FfxFloat32x4 unpacked_normal_variance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_normal_variance);
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighborSample;
|
||||
neighborSample.radiance = unpacked_radiance.xyz;
|
||||
neighborSample.normal = unpacked_normal_variance.xyz;
|
||||
neighborSample.variance = unpacked_normal_variance.w;
|
||||
neighborSample.depth = g_ffx_dnsr_shared_depth[idx.y][idx.x];
|
||||
return neighborSample;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat32x3 radiance, FfxFloat32 variance, FfxFloat32x3 normal, FfxFloat32 depth) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.zz);
|
||||
g_ffx_dnsr_shared_2[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(normal.xy);
|
||||
g_ffx_dnsr_shared_3[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(FfxFloat32x2(normal.z, variance));
|
||||
g_ffx_dnsr_shared_depth[group_thread_id.y][group_thread_id.x] = depth;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_LoadNeighborhood(
|
||||
FfxInt32x2 pixel_coordinate,
|
||||
FFX_PARAMETER_OUT FfxFloat32x3 radiance,
|
||||
FFX_PARAMETER_OUT FfxFloat32 variance,
|
||||
FFX_PARAMETER_OUT FfxFloat32x3 normal,
|
||||
FFX_PARAMETER_OUT FfxFloat32 depth,
|
||||
FfxInt32x2 screen_size) {
|
||||
|
||||
radiance = LoadRadiance(FfxInt32x3(pixel_coordinate, 0));
|
||||
variance = LoadVariance(FfxInt32x3(pixel_coordinate, 0));
|
||||
|
||||
normal = FFX_DENOISER_LoadWorldSpaceNormal(pixel_coordinate);
|
||||
|
||||
FfxFloat32x2 uv = (pixel_coordinate.xy + (0.5f).xx) / FfxFloat32x2(screen_size.xy);
|
||||
depth = FFX_DNSR_Reflections_GetLinearDepth(uv, FFX_DENOISER_LoadDepth(pixel_coordinate, 0));
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_InitializeGroupSharedMemory(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxInt32x2 screen_size) {
|
||||
// Load 16x16 region into shared memory using 4 8x8 blocks.
|
||||
FfxInt32x2 offset[4] = {FfxInt32x2(0, 0), FfxInt32x2(8, 0), FfxInt32x2(0, 8), FfxInt32x2(8, 8)};
|
||||
|
||||
// Intermediate storage registers to cache the result of all loads
|
||||
FfxFloat32x3 radiance[4];
|
||||
FfxFloat32 variance[4];
|
||||
FfxFloat32x3 normal[4];
|
||||
FfxFloat32 depth[4];
|
||||
|
||||
// Start in the upper left corner of the 16x16 region.
|
||||
dispatch_thread_id -= 4;
|
||||
|
||||
// First store all loads in registers
|
||||
for (FfxInt32 i = 0; i < 4; ++i) {
|
||||
FFX_DNSR_Reflections_LoadNeighborhood(dispatch_thread_id + offset[i], radiance[i], variance[i], normal[i], depth[i], screen_size);
|
||||
}
|
||||
|
||||
// Then move all registers to groupshared memory
|
||||
for (FfxInt32 j = 0; j < 4; ++j) {
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id + offset[j], radiance[j], variance[j], normal[j], depth[j]); // X
|
||||
}
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_GetEdgeStoppingNormalWeight(FfxFloat32x3 normal_p, FfxFloat32x3 normal_q) {
|
||||
return FfxFloat32(pow(max(dot(normal_p, normal_q), FfxFloat32(0.0f)), FFX_DNSR_REFLECTIONS_PREFILTER_NORMAL_SIGMA));
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_GetEdgeStoppingDepthWeight(FfxFloat32 center_depth, FfxFloat32 neighbor_depth) {
|
||||
return FfxFloat32(exp(-abs(center_depth - neighbor_depth) * center_depth * FFX_DNSR_REFLECTIONS_PREFILTER_DEPTH_SIGMA));
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_GetRadianceWeight(FfxFloat32x3 center_radiance, FfxFloat32x3 neighbor_radiance, FfxFloat32 variance) {
|
||||
return FfxFloat32(max(exp(-(FFX_DNSR_REFLECTIONS_RADIANCE_WEIGHT_BIAS + variance * FFX_DNSR_REFLECTIONS_RADIANCE_WEIGHT_VARIANCE_K)
|
||||
* length(center_radiance - neighbor_radiance.xyz))
|
||||
, 1.0e-2));
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_Resolve(FfxInt32x2 group_thread_id, FfxFloat32x3 avg_radiance, FFX_DNSR_Reflections_NeighborhoodSample center,
|
||||
out FfxFloat32x3 resolved_radiance, out FfxFloat32 resolved_variance) {
|
||||
// Initial weight is important to remove fireflies.
|
||||
// That removes quite a bit of energy but makes everything much more stable.
|
||||
FfxFloat32 accumulated_weight = FFX_DNSR_Reflections_GetRadianceWeight(avg_radiance, center.radiance.xyz, center.variance);
|
||||
FfxFloat32x3 accumulated_radiance = center.radiance.xyz * accumulated_weight;
|
||||
FfxFloat32 accumulated_variance = center.variance * accumulated_weight * accumulated_weight;
|
||||
// First 15 numbers of Halton(2,3) streteched to [-3,3]. Skipping the center, as we already have that in center_radiance and center_variance.
|
||||
const FfxUInt32 sample_count = 15;
|
||||
const FfxInt32x2 sample_offsets[] = {FfxInt32x2(0, 1), FfxInt32x2(-2, 1), FfxInt32x2(2, -3), FfxInt32x2(-3, 0), FfxInt32x2(1, 2), FfxInt32x2(-1, -2), FfxInt32x2(3, 0), FfxInt32x2(-3, 3),
|
||||
FfxInt32x2(0, -3), FfxInt32x2(-1, -1), FfxInt32x2(2, 1), FfxInt32x2(-2, -2), FfxInt32x2(1, 0), FfxInt32x2(0, 2), FfxInt32x2(3, -1)};
|
||||
FfxFloat32 variance_weight = FfxFloat32(max(FFX_DNSR_REFLECTIONS_PREFILTER_VARIANCE_BIAS,
|
||||
1.0 - exp(-(center.variance * FFX_DNSR_REFLECTIONS_PREFILTER_VARIANCE_WEIGHT))
|
||||
));
|
||||
for (FfxInt32 i = 0; i < sample_count; ++i) {
|
||||
FfxInt32x2 new_idx = group_thread_id + sample_offsets[i];
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighbor = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(new_idx);
|
||||
|
||||
FfxFloat32 weight = FfxFloat32(1.0f);
|
||||
weight *= FFX_DNSR_Reflections_GetEdgeStoppingNormalWeight(center.normal, neighbor.normal);
|
||||
weight *= FFX_DNSR_Reflections_GetEdgeStoppingDepthWeight(center.depth, neighbor.depth);
|
||||
weight *= FFX_DNSR_Reflections_GetRadianceWeight(avg_radiance, neighbor.radiance.xyz, center.variance);
|
||||
weight *= variance_weight;
|
||||
|
||||
// Accumulate all contributions.
|
||||
accumulated_weight += weight;
|
||||
accumulated_radiance += weight * neighbor.radiance.xyz;
|
||||
accumulated_variance += weight * weight * neighbor.variance;
|
||||
}
|
||||
|
||||
accumulated_radiance /= accumulated_weight;
|
||||
accumulated_variance /= (accumulated_weight * accumulated_weight);
|
||||
resolved_radiance = accumulated_radiance;
|
||||
resolved_variance = accumulated_variance;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_Prefilter(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxUInt32x2 screen_size) {
|
||||
FfxFloat32 center_roughness = FFX_DNSR_Reflections_LoadRoughness(dispatch_thread_id);
|
||||
FFX_DNSR_Reflections_InitializeGroupSharedMemory(dispatch_thread_id, group_thread_id, FfxInt32x2(screen_size));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
group_thread_id += 4; // Center threads in groupshared memory
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample center = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(group_thread_id);
|
||||
|
||||
FfxFloat32x3 resolved_radiance = center.radiance;
|
||||
FfxFloat32 resolved_variance = center.variance;
|
||||
|
||||
// Check if we have to denoise or if a simple copy is enough
|
||||
bool needs_denoiser = center.variance > 0.0 && FFX_DNSR_Reflections_IsGlossyReflection(center_roughness) && !FFX_DNSR_Reflections_IsMirrorReflection(center_roughness);
|
||||
if (needs_denoiser) {
|
||||
FfxFloat32x2 uv8 = (FfxFloat32x2(dispatch_thread_id.xy) + (0.5).xx) / FFX_DNSR_Reflections_RoundUp8(screen_size);
|
||||
FfxFloat32x3 avg_radiance = FFX_DNSR_Reflections_SampleAverageRadiance(uv8);
|
||||
FFX_DNSR_Reflections_Resolve(group_thread_id, avg_radiance, center, resolved_radiance, resolved_variance);
|
||||
}
|
||||
|
||||
FFX_DNSR_Reflections_StorePrefilteredReflections(dispatch_thread_id, resolved_radiance, resolved_variance);
|
||||
}
|
||||
|
||||
#endif // FFX_HALF
|
||||
|
||||
void Prefilter(FfxUInt32 group_index, FfxUInt32 group_id, FfxInt32x2 group_thread_id) {
|
||||
FfxUInt32 packed_coords = GetDenoiserTile(group_id);
|
||||
FfxInt32x2 dispatch_thread_id = FfxInt32x2(packed_coords & 0xffffu, (packed_coords >> 16) & 0xffffu) + group_thread_id;
|
||||
FfxInt32x2 dispatch_group_id = dispatch_thread_id / 8;
|
||||
FfxInt32x2 remapped_group_thread_id = FfxInt32x2(ffxRemapForWaveReduction(group_index));
|
||||
FfxInt32x2 remapped_dispatch_thread_id = FfxInt32x2(dispatch_group_id * 8 + remapped_group_thread_id);
|
||||
|
||||
FFX_DNSR_Reflections_Prefilter(remapped_dispatch_thread_id, remapped_group_thread_id, RenderSize());
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void Prefilter(FfxUInt32 group_index, FfxUInt32 group_id, FfxInt32x2 group_thread_id) {}
|
||||
|
||||
#endif // FFX_DNSR_REFLECTIONS_PREFILTER
|
||||
722
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_reproject.h
vendored
Normal file
722
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_reproject.h
vendored
Normal file
@@ -0,0 +1,722 @@
|
||||
// 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_DNSR_REFLECTIONS_REPROJECT
|
||||
#define FFX_DNSR_REFLECTIONS_REPROJECT
|
||||
|
||||
#define FFX_DNSR_REFLECTIONS_ESTIMATES_LOCAL_NEIGHBORHOOD
|
||||
#include "ffx_denoiser_reflections_common.h"
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_0[16][16];
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_1[16][16];
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
struct FFX_DNSR_Reflections_NeighborhoodSample {
|
||||
FfxFloat16x3 radiance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample FFX_DNSR_Reflections_LoadFromGroupSharedMemory(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
FfxFloat16x4 unpacked_radiance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance);
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighborSample;
|
||||
neighborSample.radiance = unpacked_radiance.xyz;
|
||||
return neighborSample;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat16x3 radiance) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.zz);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat16x4 radiance_variance) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance_variance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance_variance.zw);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_InitializeGroupSharedMemory(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxInt32x2 screen_size) {
|
||||
// Load 16x16 region into shared memory using 4 8x8 blocks.
|
||||
FfxInt32x2 offset[4] = {FfxInt32x2(0, 0), FfxInt32x2(8, 0), FfxInt32x2(0, 8), FfxInt32x2(8, 8)};
|
||||
|
||||
// Intermediate storage registers to cache the result of all loads
|
||||
FfxFloat16x3 radiance[4];
|
||||
|
||||
// Start in the upper left corner of the 16x16 region.
|
||||
dispatch_thread_id -= 4;
|
||||
|
||||
// First store all loads in registers
|
||||
for (FfxInt32 i = 0; i < 4; ++i) {
|
||||
radiance[i] = FFX_DNSR_Reflections_LoadRadiance(dispatch_thread_id + offset[i]);
|
||||
}
|
||||
|
||||
// Then move all registers to FFX_GROUPSHARED memory
|
||||
for (FfxInt32 j = 0; j < 4; ++j) {
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id + offset[j], radiance[j]); // X
|
||||
}
|
||||
}
|
||||
|
||||
FfxFloat16x4 FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
return FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance);
|
||||
}
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_GetLuminanceWeight(FfxFloat16x3 val) {
|
||||
FfxFloat16 luma = FFX_DNSR_Reflections_Luminance(val.xyz);
|
||||
FfxFloat16 weight = FfxFloat16(max(exp(-luma * FFX_DNSR_REFLECTIONS_AVG_RADIANCE_LUMINANCE_WEIGHT), 1.0e-2));
|
||||
return weight;
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Reflections_GetSurfaceReprojection(FfxInt32x2 dispatch_thread_id, FfxFloat32x2 uv, FfxFloat32x2 motion_vector) {
|
||||
// Reflector position reprojection
|
||||
FfxFloat32x2 history_uv = uv + motion_vector;
|
||||
return history_uv;
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Reflections_GetHitPositionReprojection(FfxInt32x2 dispatch_thread_id, FfxFloat32x2 uv, FfxFloat32 reflected_ray_length) {
|
||||
FfxFloat32 z = FFX_DNSR_Reflections_LoadDepth(dispatch_thread_id);
|
||||
FfxFloat32x3 view_space_ray = FFX_DNSR_Reflections_ScreenSpaceToViewSpace(FfxFloat32x3(uv, z));
|
||||
|
||||
// We start out with reconstructing the ray length in view space.
|
||||
// This includes the portion from the camera to the reflecting surface as well as the portion from the surface to the hit position.
|
||||
FfxFloat32 surface_depth = length(view_space_ray);
|
||||
FfxFloat32 ray_length = surface_depth + reflected_ray_length;
|
||||
|
||||
// We then perform a parallax correction by shooting a ray
|
||||
// of the same length "straight through" the reflecting surface
|
||||
// and reprojecting the tip of that ray to the previous frame.
|
||||
view_space_ray /= surface_depth; // == normalize(view_space_ray)
|
||||
view_space_ray *= ray_length;
|
||||
FfxFloat32x3 world_hit_position =
|
||||
FFX_DNSR_Reflections_ViewSpaceToWorldSpace(FfxFloat32x4(view_space_ray, 1)); // This is the "fake" hit position if we would follow the ray straight through the surface.
|
||||
FfxFloat32x3 prev_hit_position = FFX_DNSR_Reflections_WorldSpaceToScreenSpacePrevious(world_hit_position);
|
||||
FfxFloat32x2 history_uv = prev_hit_position.xy;
|
||||
return history_uv;
|
||||
}
|
||||
|
||||
FfxFloat16 FFX_DNSR_Reflections_GetDisocclusionFactor(FfxFloat16x3 normal, FfxFloat16x3 history_normal, FfxFloat32 linear_depth, FfxFloat32 history_linear_depth) {
|
||||
FfxFloat16 factor = FfxFloat16(1.0f //
|
||||
* exp(-abs(1.0f - max(FfxFloat16(0.0f), dot(normal, history_normal))) * FFX_DNSR_REFLECTIONS_DISOCCLUSION_NORMAL_WEIGHT) //
|
||||
* exp(-abs(history_linear_depth - linear_depth) / linear_depth * FFX_DNSR_REFLECTIONS_DISOCCLUSION_DEPTH_WEIGHT));
|
||||
return factor;
|
||||
}
|
||||
|
||||
struct FFX_DNSR_Reflections_Moments {
|
||||
FfxFloat16x3 mean;
|
||||
FfxFloat16x3 variance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_Moments FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(FfxInt32x2 group_thread_id) {
|
||||
FFX_DNSR_Reflections_Moments estimate;
|
||||
estimate.mean = FfxFloat16x3(0.0f, 0.0f, 0.0f);
|
||||
estimate.variance = FfxFloat16x3(0.0f, 0.0f, 0.0f);
|
||||
FfxFloat16 accumulated_weight = FfxFloat16(0.0f);
|
||||
for (FfxInt32 j = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; j <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++j) {
|
||||
for (FfxInt32 i = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; i <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++i) {
|
||||
FfxInt32x2 new_idx = group_thread_id + FfxInt32x2(i, j);
|
||||
FfxFloat16x3 radiance = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(new_idx).radiance;
|
||||
FfxFloat16 weight = FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat16(i)) * FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat16(j));
|
||||
accumulated_weight += weight;
|
||||
estimate.mean += radiance * weight;
|
||||
estimate.variance += radiance * radiance * weight;
|
||||
}
|
||||
}
|
||||
estimate.mean /= accumulated_weight;
|
||||
estimate.variance /= accumulated_weight;
|
||||
|
||||
estimate.variance = abs(estimate.variance - estimate.mean * estimate.mean);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
FfxFloat32 dot2(FfxFloat32x3 a) { return dot(a, a); }
|
||||
|
||||
void FFX_DNSR_Reflections_PickReprojection(FfxInt32x2 dispatch_thread_id, //
|
||||
FfxInt32x2 group_thread_id, //
|
||||
FfxUInt32x2 screen_size, //
|
||||
FfxFloat16 roughness, //
|
||||
FfxFloat16 ray_length, //
|
||||
out FfxFloat16 disocclusion_factor, //
|
||||
out FfxFloat32x2 reprojection_uv, //
|
||||
out FfxFloat16x3 reprojection) {
|
||||
|
||||
FFX_DNSR_Reflections_Moments local_neighborhood = FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(group_thread_id);
|
||||
|
||||
FfxFloat32x2 uv = FfxFloat32x2(dispatch_thread_id.x + 0.5, dispatch_thread_id.y + 0.5) / screen_size;
|
||||
FfxFloat16x3 normal = FFX_DNSR_Reflections_LoadWorldSpaceNormal(dispatch_thread_id);
|
||||
FfxFloat16x3 history_normal;
|
||||
FfxFloat32 history_linear_depth;
|
||||
|
||||
{
|
||||
const FfxFloat32x2 motion_vector = FFX_DNSR_Reflections_LoadMotionVector(dispatch_thread_id);
|
||||
const FfxFloat32x2 surface_reprojection_uv = FFX_DNSR_Reflections_GetSurfaceReprojection(dispatch_thread_id, uv, motion_vector);
|
||||
const FfxFloat32x2 hit_reprojection_uv = FFX_DNSR_Reflections_GetHitPositionReprojection(dispatch_thread_id, uv, ray_length);
|
||||
const FfxFloat16x3 surface_normal = FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(surface_reprojection_uv);
|
||||
const FfxFloat16x3 hit_normal = FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(hit_reprojection_uv);
|
||||
const FfxFloat16x3 surface_history = FFX_DNSR_Reflections_SampleRadianceHistory(surface_reprojection_uv);
|
||||
const FfxFloat16x3 hit_history = FFX_DNSR_Reflections_SampleRadianceHistory(hit_reprojection_uv);
|
||||
const FfxFloat32 hit_normal_similarity = dot(normalize(FfxFloat32x3(hit_normal)), normalize(FfxFloat32x3(normal)));
|
||||
const FfxFloat32 surface_normal_similarity = dot(normalize(FfxFloat32x3(surface_normal)), normalize(FfxFloat32x3(normal)));
|
||||
const FfxFloat16 hit_roughness = FFX_DNSR_Reflections_SampleRoughnessHistory(hit_reprojection_uv);
|
||||
const FfxFloat16 surface_roughness = FFX_DNSR_Reflections_SampleRoughnessHistory(surface_reprojection_uv);
|
||||
|
||||
// Choose reprojection uv based on similarity to the local neighborhood.
|
||||
if (hit_normal_similarity > FFX_DNSR_REFLECTIONS_REPROJECTION_NORMAL_SIMILARITY_THRESHOLD // Candidate for mirror reflection parallax
|
||||
&& hit_normal_similarity + 1.0e-3 > surface_normal_similarity //
|
||||
&& abs(hit_roughness - roughness) < abs(surface_roughness - roughness) + 1.0e-3 //
|
||||
) {
|
||||
history_normal = hit_normal;
|
||||
FfxFloat32 hit_history_depth = FFX_DNSR_Reflections_SampleDepthHistory(hit_reprojection_uv);
|
||||
FfxFloat32 hit_history_linear_depth = FFX_DNSR_Reflections_GetLinearDepth(hit_reprojection_uv, hit_history_depth);
|
||||
history_linear_depth = hit_history_linear_depth;
|
||||
reprojection_uv = hit_reprojection_uv;
|
||||
reprojection = hit_history;
|
||||
} else {
|
||||
// Reject surface reprojection based on simple distance
|
||||
if (dot2(surface_history - local_neighborhood.mean) <
|
||||
FFX_DNSR_REFLECTIONS_REPROJECT_SURFACE_DISCARD_VARIANCE_WEIGHT * length(local_neighborhood.variance)) {
|
||||
history_normal = surface_normal;
|
||||
FfxFloat32 surface_history_depth = FFX_DNSR_Reflections_SampleDepthHistory(surface_reprojection_uv);
|
||||
FfxFloat32 surface_history_linear_depth = FFX_DNSR_Reflections_GetLinearDepth(surface_reprojection_uv, surface_history_depth);
|
||||
history_linear_depth = surface_history_linear_depth;
|
||||
reprojection_uv = surface_reprojection_uv;
|
||||
reprojection = surface_history;
|
||||
} else {
|
||||
disocclusion_factor = FfxFloat16(0.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
FfxFloat32 depth = FFX_DNSR_Reflections_LoadDepth(dispatch_thread_id);
|
||||
FfxFloat32 linear_depth = FFX_DNSR_Reflections_GetLinearDepth(uv, depth);
|
||||
// Determine disocclusion factor based on history
|
||||
disocclusion_factor = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, history_normal, linear_depth, history_linear_depth);
|
||||
|
||||
if (disocclusion_factor > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) // Early out, good enough
|
||||
return;
|
||||
|
||||
// Try to find the closest sample in the vicinity if we are not convinced of a disocclusion
|
||||
if (disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) {
|
||||
FfxFloat32x2 closest_uv = reprojection_uv;
|
||||
FfxFloat32x2 dudv = 1.0 / FfxFloat32x2(screen_size);
|
||||
const FfxInt32 search_radius = 1;
|
||||
for (FfxInt32 y = -search_radius; y <= search_radius; y++) {
|
||||
for (FfxInt32 x = -search_radius; x <= search_radius; x++) {
|
||||
FfxFloat32x2 uv = reprojection_uv + FfxFloat32x2(x, y) * dudv;
|
||||
FfxFloat16x3 history_normal = FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(uv);
|
||||
FfxFloat32 history_depth = FFX_DNSR_Reflections_SampleDepthHistory(uv);
|
||||
FfxFloat32 history_linear_depth = FFX_DNSR_Reflections_GetLinearDepth(uv, history_depth);
|
||||
FfxFloat16 weight = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, history_normal, linear_depth, history_linear_depth);
|
||||
if (weight > disocclusion_factor) {
|
||||
disocclusion_factor = weight;
|
||||
closest_uv = uv;
|
||||
reprojection_uv = closest_uv;
|
||||
}
|
||||
}
|
||||
}
|
||||
reprojection = FFX_DNSR_Reflections_SampleRadianceHistory(reprojection_uv);
|
||||
}
|
||||
|
||||
// Rare slow path - triggered only on the edges.
|
||||
// Try to get rid of potential leaks at bilinear interpolation level.
|
||||
if (disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) {
|
||||
// If we've got a discarded history, try to construct a better sample out of 2x2 interpolation neighborhood
|
||||
// Helps quite a bit on the edges in movement
|
||||
FfxFloat32 uvx = ffxFract(FfxFloat32(screen_size.x) * reprojection_uv.x + 0.5);
|
||||
FfxFloat32 uvy = ffxFract(FfxFloat32(screen_size.y) * reprojection_uv.y + 0.5);
|
||||
FfxInt32x2 reproject_texel_coords = FfxInt32x2(screen_size * reprojection_uv - 0.5);
|
||||
FfxFloat16x3 reprojection00 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(0, 0));
|
||||
FfxFloat16x3 reprojection10 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(1, 0));
|
||||
FfxFloat16x3 reprojection01 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(0, 1));
|
||||
FfxFloat16x3 reprojection11 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(1, 1));
|
||||
FfxFloat16x3 normal00 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(0, 0));
|
||||
FfxFloat16x3 normal10 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(1, 0));
|
||||
FfxFloat16x3 normal01 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(0, 1));
|
||||
FfxFloat16x3 normal11 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(1, 1));
|
||||
FfxFloat32 depth00 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(0, 0)));
|
||||
FfxFloat32 depth10 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(1, 0)));
|
||||
FfxFloat32 depth01 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(0, 1)));
|
||||
FfxFloat32 depth11 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(1, 1)));
|
||||
FfxFloat16x4 w = FfxFloat16x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// Initialize with occlusion weights
|
||||
w.x = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal00, linear_depth, depth00) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat16(1.0f) : FfxFloat16(0.0f);
|
||||
w.y = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal10, linear_depth, depth10) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat16(1.0f) : FfxFloat16(0.0f);
|
||||
w.z = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal01, linear_depth, depth01) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat16(1.0f) : FfxFloat16(0.0f);
|
||||
w.w = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal11, linear_depth, depth11) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat16(1.0f) : FfxFloat16(0.0f);
|
||||
// And then mix in bilinear weights
|
||||
w.x = FfxFloat16(w.x * (1.0 - uvx) * (1.0 - uvy));
|
||||
w.y = FfxFloat16(w.y * (uvx) * (1.0 - uvy));
|
||||
w.z = FfxFloat16(w.z * (1.0 - uvx) * (uvy));
|
||||
w.w = FfxFloat16(w.w * (uvx) * (uvy));
|
||||
FfxFloat16 ws = max(w.x + w.y + w.z + w.w, FfxFloat16(1.0e-3));
|
||||
// normalize
|
||||
w /= ws;
|
||||
|
||||
FfxFloat16x3 history_normal;
|
||||
FfxFloat32 history_linear_depth;
|
||||
reprojection = reprojection00 * w.x + reprojection10 * w.y + reprojection01 * w.z + reprojection11 * w.w;
|
||||
history_linear_depth = depth00 * w.x + depth10 * w.y + depth01 * w.z + depth11 * w.w;
|
||||
history_normal = normal00 * w.x + normal10 * w.y + normal01 * w.z + normal11 * w.w;
|
||||
disocclusion_factor = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, history_normal, linear_depth, history_linear_depth);
|
||||
}
|
||||
disocclusion_factor = disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD ? FfxFloat16(0.0f) : disocclusion_factor;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_Reproject(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxUInt32x2 screen_size, FfxFloat32 temporal_stability_factor, FfxInt32 max_samples) {
|
||||
FFX_DNSR_Reflections_InitializeGroupSharedMemory(dispatch_thread_id, group_thread_id, FfxInt32x2(screen_size));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
group_thread_id += 4; // Center threads in FFX_GROUPSHARED memory
|
||||
|
||||
FfxFloat16 variance = FfxFloat16(1.0f);
|
||||
FfxFloat16 num_samples = FfxFloat16(0.0f);
|
||||
FfxFloat16 roughness = FFX_DNSR_Reflections_LoadRoughness(dispatch_thread_id);
|
||||
FfxFloat32x3 normal = FFX_DNSR_Reflections_LoadWorldSpaceNormal(dispatch_thread_id);
|
||||
FfxFloat16x3 radiance = FFX_DNSR_Reflections_LoadRadiance(dispatch_thread_id);
|
||||
const FfxFloat16 ray_length = FFX_DNSR_Reflections_LoadRayLength(dispatch_thread_id);
|
||||
|
||||
if (FFX_DNSR_Reflections_IsGlossyReflection(roughness)) {
|
||||
FfxFloat16 disocclusion_factor;
|
||||
FfxFloat32x2 reprojection_uv;
|
||||
FfxFloat16x3 reprojection;
|
||||
FFX_DNSR_Reflections_PickReprojection(/*in*/ dispatch_thread_id,
|
||||
/* in */ group_thread_id,
|
||||
/* in */ screen_size,
|
||||
/* in */ roughness,
|
||||
/* in */ ray_length,
|
||||
/* out */ disocclusion_factor,
|
||||
/* out */ reprojection_uv,
|
||||
/* out */ reprojection);
|
||||
if ( (reprojection_uv.x > 0.0f) && (reprojection_uv.y > 0.0f) && (reprojection_uv.x < 1.0f) && (reprojection_uv.y< 1.0f)) {
|
||||
FfxFloat16 prev_variance = FFX_DNSR_Reflections_SampleVarianceHistory(reprojection_uv);
|
||||
num_samples = FFX_DNSR_Reflections_SampleNumSamplesHistory(reprojection_uv) * disocclusion_factor;
|
||||
FfxFloat16 s_max_samples = FfxFloat16(max(8.0f, FfxFloat16(max_samples) * FFX_DNSR_REFLECTIONS_SAMPLES_FOR_ROUGHNESS(roughness)));
|
||||
num_samples = min(s_max_samples, num_samples + FfxFloat16(1.0f));
|
||||
FfxFloat16 new_variance = FFX_DNSR_Reflections_ComputeTemporalVariance(radiance.xyz, reprojection.xyz);
|
||||
if (disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) {
|
||||
FFX_DNSR_Reflections_StoreRadianceReprojected(dispatch_thread_id, FfxFloat16x3(0.0f, 0.0f, 0.0f));
|
||||
FFX_DNSR_Reflections_StoreVariance(dispatch_thread_id, FfxFloat16(1.0f));
|
||||
FFX_DNSR_Reflections_StoreNumSamples(dispatch_thread_id, FfxFloat16(1.0f));
|
||||
} else {
|
||||
FfxFloat16 variance_mix = ffxLerp(new_variance, prev_variance, FfxFloat16(1.0f / num_samples));
|
||||
FFX_DNSR_Reflections_StoreRadianceReprojected(dispatch_thread_id, reprojection);
|
||||
FFX_DNSR_Reflections_StoreVariance(dispatch_thread_id, variance_mix);
|
||||
FFX_DNSR_Reflections_StoreNumSamples(dispatch_thread_id, num_samples);
|
||||
// Mix in reprojection for radiance mip computation
|
||||
radiance = ffxLerp(radiance, reprojection, FfxFloat16(0.3f));
|
||||
}
|
||||
} else {
|
||||
FFX_DNSR_Reflections_StoreRadianceReprojected(dispatch_thread_id, FfxFloat16x3(0.0f, 0.0f, 0.0f));
|
||||
FFX_DNSR_Reflections_StoreVariance(dispatch_thread_id, FfxFloat16(1.0f));
|
||||
FFX_DNSR_Reflections_StoreNumSamples(dispatch_thread_id, FfxFloat16(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
// Downsample 8x8 -> 1 radiance using FFX_GROUPSHARED memory
|
||||
// Initialize FFX_GROUPSHARED array for downsampling
|
||||
FfxFloat16 weight = FFX_DNSR_Reflections_GetLuminanceWeight(radiance.xyz);
|
||||
radiance.xyz *= weight;
|
||||
if ( (dispatch_thread_id.x >= screen_size.x) || (dispatch_thread_id.y >= screen_size.y) || any(isinf(radiance)) || any(isnan(radiance)) || (weight > FfxFloat16(1.0e3))) {
|
||||
radiance = FfxFloat16x3(0.0f, 0.0f, 0.0f);
|
||||
weight = FfxFloat16(0.0f);
|
||||
}
|
||||
|
||||
group_thread_id -= 4; // Center threads in FFX_GROUPSHARED memory
|
||||
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id, FfxFloat16x4(radiance.xyz, weight));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
for (FfxInt32 i = 2; i <= 8; i = i * 2) {
|
||||
FfxInt32 ox = group_thread_id.x * i;
|
||||
FfxInt32 oy = group_thread_id.y * i;
|
||||
FfxInt32 ix = group_thread_id.x * i + i / 2;
|
||||
FfxInt32 iy = group_thread_id.y * i + i / 2;
|
||||
if (ix < 8 && iy < 8) {
|
||||
FfxFloat16x4 rad_weight00 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ox, oy));
|
||||
FfxFloat16x4 rad_weight10 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ox, iy));
|
||||
FfxFloat16x4 rad_weight01 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ix, oy));
|
||||
FfxFloat16x4 rad_weight11 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ix, iy));
|
||||
FfxFloat16x4 sum = rad_weight00 + rad_weight01 + rad_weight10 + rad_weight11;
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2(ox, oy), sum);
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
}
|
||||
|
||||
if ((group_thread_id.x == 0) && (group_thread_id.y == 0)) {
|
||||
FfxFloat16x4 sum = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(0, 0));
|
||||
FfxFloat16 weight_acc = max(sum.w, FfxFloat16(1.0e-3));
|
||||
FfxFloat32x3 radiance_avg = sum.xyz / weight_acc;
|
||||
FFX_DNSR_Reflections_StoreAverageRadiance(dispatch_thread_id.xy / 8, FfxFloat16x3(radiance_avg));
|
||||
}
|
||||
}
|
||||
|
||||
#else // #if FFX_HALF
|
||||
|
||||
struct FFX_DNSR_Reflections_NeighborhoodSample {
|
||||
FfxFloat32x3 radiance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample FFX_DNSR_Reflections_LoadFromGroupSharedMemory(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
FfxFloat32x4 unpacked_radiance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance);
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighborSample;
|
||||
neighborSample.radiance = unpacked_radiance.xyz;
|
||||
return neighborSample;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat32x3 radiance) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.zz);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat32x4 radiance_variance) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance_variance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance_variance.zw);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_InitializeGroupSharedMemory(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxInt32x2 screen_size) {
|
||||
// Load 16x16 region into shared memory using 4 8x8 blocks.
|
||||
FfxInt32x2 offset[4] = {FfxInt32x2(0, 0), FfxInt32x2(8, 0), FfxInt32x2(0, 8), FfxInt32x2(8, 8)};
|
||||
|
||||
// Intermediate storage registers to cache the result of all loads
|
||||
FfxFloat32x3 radiance[4];
|
||||
|
||||
// Start in the upper left corner of the 16x16 region.
|
||||
dispatch_thread_id -= 4;
|
||||
|
||||
// First store all loads in registers
|
||||
for (FfxInt32 i = 0; i < 4; ++i) {
|
||||
radiance[i] = FFX_DNSR_Reflections_LoadRadiance(dispatch_thread_id + offset[i]);
|
||||
}
|
||||
|
||||
// Then move all registers to FFX_GROUPSHARED memory
|
||||
for (FfxInt32 j = 0; j < 4; ++j) {
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id + offset[j], radiance[j]); // X
|
||||
}
|
||||
}
|
||||
|
||||
FfxFloat32x4 FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
return FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance);
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_GetLuminanceWeight(FfxFloat32x3 val) {
|
||||
FfxFloat32 luma = FFX_DNSR_Reflections_Luminance(val.xyz);
|
||||
FfxFloat32 weight = FfxFloat32(max(exp(-luma * FFX_DNSR_REFLECTIONS_AVG_RADIANCE_LUMINANCE_WEIGHT), 1.0e-2));
|
||||
return weight;
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Reflections_GetSurfaceReprojection(FfxInt32x2 dispatch_thread_id, FfxFloat32x2 uv, FfxFloat32x2 motion_vector) {
|
||||
// Reflector position reprojection
|
||||
FfxFloat32x2 history_uv = uv + motion_vector;
|
||||
return history_uv;
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Reflections_GetHitPositionReprojection(FfxInt32x2 dispatch_thread_id, FfxFloat32x2 uv, FfxFloat32 reflected_ray_length) {
|
||||
FfxFloat32 z = FFX_DNSR_Reflections_LoadDepth(dispatch_thread_id);
|
||||
FfxFloat32x3 view_space_ray = FFX_DNSR_Reflections_ScreenSpaceToViewSpace(FfxFloat32x3(uv, z));
|
||||
|
||||
// We start out with reconstructing the ray length in view space.
|
||||
// This includes the portion from the camera to the reflecting surface as well as the portion from the surface to the hit position.
|
||||
FfxFloat32 surface_depth = length(view_space_ray);
|
||||
FfxFloat32 ray_length = surface_depth + reflected_ray_length;
|
||||
|
||||
// We then perform a parallax correction by shooting a ray
|
||||
// of the same length "straight through" the reflecting surface
|
||||
// and reprojecting the tip of that ray to the previous frame.
|
||||
view_space_ray /= surface_depth; // == normalize(view_space_ray)
|
||||
view_space_ray *= ray_length;
|
||||
FfxFloat32x3 world_hit_position =
|
||||
FFX_DNSR_Reflections_ViewSpaceToWorldSpace(FfxFloat32x4(view_space_ray, 1)); // This is the "fake" hit position if we would follow the ray straight through the surface.
|
||||
FfxFloat32x3 prev_hit_position = FFX_DNSR_Reflections_WorldSpaceToScreenSpacePrevious(world_hit_position);
|
||||
FfxFloat32x2 history_uv = prev_hit_position.xy;
|
||||
return history_uv;
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Reflections_GetDisocclusionFactor(FfxFloat32x3 normal, FfxFloat32x3 history_normal, FfxFloat32 linear_depth, FfxFloat32 history_linear_depth) {
|
||||
FfxFloat32 factor = FfxFloat32(1.0f //
|
||||
* exp(-abs(1.0f - max(FfxFloat32(0.0f), dot(normal, history_normal))) * FFX_DNSR_REFLECTIONS_DISOCCLUSION_NORMAL_WEIGHT) //
|
||||
* exp(-abs(history_linear_depth - linear_depth) / linear_depth * FFX_DNSR_REFLECTIONS_DISOCCLUSION_DEPTH_WEIGHT));
|
||||
return factor;
|
||||
}
|
||||
|
||||
struct FFX_DNSR_Reflections_Moments {
|
||||
FfxFloat32x3 mean;
|
||||
FfxFloat32x3 variance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_Moments FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(FfxInt32x2 group_thread_id) {
|
||||
FFX_DNSR_Reflections_Moments estimate;
|
||||
estimate.mean = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
estimate.variance = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
FfxFloat32 accumulated_weight = FfxFloat32(0.0f);
|
||||
for (FfxInt32 j = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; j <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++j) {
|
||||
for (FfxInt32 i = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; i <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++i) {
|
||||
FfxInt32x2 new_idx = group_thread_id + FfxInt32x2(i, j);
|
||||
FfxFloat32x3 radiance = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(new_idx).radiance;
|
||||
FfxFloat32 weight = FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat32(i)) * FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat32(j));
|
||||
accumulated_weight += weight;
|
||||
estimate.mean += radiance * weight;
|
||||
estimate.variance += radiance * radiance * weight;
|
||||
}
|
||||
}
|
||||
estimate.mean /= accumulated_weight;
|
||||
estimate.variance /= accumulated_weight;
|
||||
|
||||
estimate.variance = abs(estimate.variance - estimate.mean * estimate.mean);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
FfxFloat32 dot2(FfxFloat32x3 a) { return dot(a, a); }
|
||||
|
||||
void FFX_DNSR_Reflections_PickReprojection(FfxInt32x2 dispatch_thread_id, //
|
||||
FfxInt32x2 group_thread_id, //
|
||||
FfxUInt32x2 screen_size, //
|
||||
FfxFloat32 roughness, //
|
||||
FfxFloat32 ray_length, //
|
||||
out FfxFloat32 disocclusion_factor, //
|
||||
out FfxFloat32x2 reprojection_uv, //
|
||||
out FfxFloat32x3 reprojection) {
|
||||
|
||||
FFX_DNSR_Reflections_Moments local_neighborhood = FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(group_thread_id);
|
||||
|
||||
FfxFloat32x2 uv = FfxFloat32x2(dispatch_thread_id.x + 0.5, dispatch_thread_id.y + 0.5) / screen_size;
|
||||
FfxFloat32x3 normal = FFX_DNSR_Reflections_LoadWorldSpaceNormal(dispatch_thread_id);
|
||||
FfxFloat32x3 history_normal;
|
||||
FfxFloat32 history_linear_depth;
|
||||
|
||||
{
|
||||
const FfxFloat32x2 motion_vector = FFX_DNSR_Reflections_LoadMotionVector(dispatch_thread_id);
|
||||
const FfxFloat32x2 surface_reprojection_uv = FFX_DNSR_Reflections_GetSurfaceReprojection(dispatch_thread_id, uv, motion_vector);
|
||||
const FfxFloat32x2 hit_reprojection_uv = FFX_DNSR_Reflections_GetHitPositionReprojection(dispatch_thread_id, uv, ray_length);
|
||||
const FfxFloat32x3 surface_normal = FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(surface_reprojection_uv);
|
||||
const FfxFloat32x3 hit_normal = FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(hit_reprojection_uv);
|
||||
const FfxFloat32x3 surface_history = FFX_DNSR_Reflections_SampleRadianceHistory(surface_reprojection_uv);
|
||||
const FfxFloat32x3 hit_history = FFX_DNSR_Reflections_SampleRadianceHistory(hit_reprojection_uv);
|
||||
const FfxFloat32 hit_normal_similarity = dot(normalize(FfxFloat32x3(hit_normal)), normalize(FfxFloat32x3(normal)));
|
||||
const FfxFloat32 surface_normal_similarity = dot(normalize(FfxFloat32x3(surface_normal)), normalize(FfxFloat32x3(normal)));
|
||||
const FfxFloat32 hit_roughness = FFX_DNSR_Reflections_SampleRoughnessHistory(hit_reprojection_uv);
|
||||
const FfxFloat32 surface_roughness = FFX_DNSR_Reflections_SampleRoughnessHistory(surface_reprojection_uv);
|
||||
|
||||
// Choose reprojection uv based on similarity to the local neighborhood.
|
||||
if (hit_normal_similarity > FFX_DNSR_REFLECTIONS_REPROJECTION_NORMAL_SIMILARITY_THRESHOLD // Candidate for mirror reflection parallax
|
||||
&& hit_normal_similarity + 1.0e-3 > surface_normal_similarity //
|
||||
&& abs(hit_roughness - roughness) < abs(surface_roughness - roughness) + 1.0e-3 //
|
||||
) {
|
||||
history_normal = hit_normal;
|
||||
FfxFloat32 hit_history_depth = FFX_DNSR_Reflections_SampleDepthHistory(hit_reprojection_uv);
|
||||
FfxFloat32 hit_history_linear_depth = FFX_DNSR_Reflections_GetLinearDepth(hit_reprojection_uv, hit_history_depth);
|
||||
history_linear_depth = hit_history_linear_depth;
|
||||
reprojection_uv = hit_reprojection_uv;
|
||||
reprojection = hit_history;
|
||||
} else {
|
||||
// Reject surface reprojection based on simple distance
|
||||
if (dot2(surface_history - local_neighborhood.mean) <
|
||||
FFX_DNSR_REFLECTIONS_REPROJECT_SURFACE_DISCARD_VARIANCE_WEIGHT * length(local_neighborhood.variance)) {
|
||||
history_normal = surface_normal;
|
||||
FfxFloat32 surface_history_depth = FFX_DNSR_Reflections_SampleDepthHistory(surface_reprojection_uv);
|
||||
FfxFloat32 surface_history_linear_depth = FFX_DNSR_Reflections_GetLinearDepth(surface_reprojection_uv, surface_history_depth);
|
||||
history_linear_depth = surface_history_linear_depth;
|
||||
reprojection_uv = surface_reprojection_uv;
|
||||
reprojection = surface_history;
|
||||
} else {
|
||||
disocclusion_factor = FfxFloat32(0.0f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
FfxFloat32 depth = FFX_DNSR_Reflections_LoadDepth(dispatch_thread_id);
|
||||
FfxFloat32 linear_depth = FFX_DNSR_Reflections_GetLinearDepth(uv, depth);
|
||||
// Determine disocclusion factor based on history
|
||||
disocclusion_factor = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, history_normal, linear_depth, history_linear_depth);
|
||||
|
||||
if (disocclusion_factor > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) // Early out, good enough
|
||||
return;
|
||||
|
||||
// Try to find the closest sample in the vicinity if we are not convinced of a disocclusion
|
||||
if (disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) {
|
||||
FfxFloat32x2 closest_uv = reprojection_uv;
|
||||
FfxFloat32x2 dudv = 1.0 / FfxFloat32x2(screen_size);
|
||||
const FfxInt32 search_radius = 1;
|
||||
for (FfxInt32 y = -search_radius; y <= search_radius; y++) {
|
||||
for (FfxInt32 x = -search_radius; x <= search_radius; x++) {
|
||||
FfxFloat32x2 uv = reprojection_uv + FfxFloat32x2(x, y) * dudv;
|
||||
FfxFloat32x3 history_normal = FFX_DNSR_Reflections_SampleWorldSpaceNormalHistory(uv);
|
||||
FfxFloat32 history_depth = FFX_DNSR_Reflections_SampleDepthHistory(uv);
|
||||
FfxFloat32 history_linear_depth = FFX_DNSR_Reflections_GetLinearDepth(uv, history_depth);
|
||||
FfxFloat32 weight = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, history_normal, linear_depth, history_linear_depth);
|
||||
if (weight > disocclusion_factor) {
|
||||
disocclusion_factor = weight;
|
||||
closest_uv = uv;
|
||||
reprojection_uv = closest_uv;
|
||||
}
|
||||
}
|
||||
}
|
||||
reprojection = FFX_DNSR_Reflections_SampleRadianceHistory(reprojection_uv);
|
||||
}
|
||||
|
||||
// Rare slow path - triggered only on the edges.
|
||||
// Try to get rid of potential leaks at bilinear interpolation level.
|
||||
if (disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) {
|
||||
// If we've got a discarded history, try to construct a better sample out of 2x2 interpolation neighborhood
|
||||
// Helps quite a bit on the edges in movement
|
||||
FfxFloat32 uvx = ffxFract(FfxFloat32(screen_size.x) * reprojection_uv.x + 0.5);
|
||||
FfxFloat32 uvy = ffxFract(FfxFloat32(screen_size.y) * reprojection_uv.y + 0.5);
|
||||
FfxInt32x2 reproject_texel_coords = FfxInt32x2(screen_size * reprojection_uv - 0.5);
|
||||
FfxFloat32x3 reprojection00 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(0, 0));
|
||||
FfxFloat32x3 reprojection10 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(1, 0));
|
||||
FfxFloat32x3 reprojection01 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(0, 1));
|
||||
FfxFloat32x3 reprojection11 = FFX_DNSR_Reflections_LoadRadianceHistory(reproject_texel_coords + FfxInt32x2(1, 1));
|
||||
FfxFloat32x3 normal00 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(0, 0));
|
||||
FfxFloat32x3 normal10 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(1, 0));
|
||||
FfxFloat32x3 normal01 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(0, 1));
|
||||
FfxFloat32x3 normal11 = FFX_DNSR_Reflections_LoadWorldSpaceNormalHistory(reproject_texel_coords + FfxInt32x2(1, 1));
|
||||
FfxFloat32 depth00 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(0, 0)));
|
||||
FfxFloat32 depth10 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(1, 0)));
|
||||
FfxFloat32 depth01 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(0, 1)));
|
||||
FfxFloat32 depth11 = FFX_DNSR_Reflections_GetLinearDepth(reprojection_uv, FFX_DNSR_Reflections_LoadDepthHistory(reproject_texel_coords + FfxInt32x2(1, 1)));
|
||||
FfxFloat32x4 w = FfxFloat32x4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// Initialize with occlusion weights
|
||||
w.x = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal00, linear_depth, depth00) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat32(1.0f) : FfxFloat32(0.0f);
|
||||
w.y = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal10, linear_depth, depth10) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat32(1.0f) : FfxFloat32(0.0f);
|
||||
w.z = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal01, linear_depth, depth01) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat32(1.0f) : FfxFloat32(0.0f);
|
||||
w.w = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, normal11, linear_depth, depth11) > FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD / 2.0f ? FfxFloat32(1.0f) : FfxFloat32(0.0f);
|
||||
// And then mix in bilinear weights
|
||||
w.x = FfxFloat32(w.x * (1.0 - uvx) * (1.0 - uvy));
|
||||
w.y = FfxFloat32(w.y * (uvx) * (1.0 - uvy));
|
||||
w.z = FfxFloat32(w.z * (1.0 - uvx) * (uvy));
|
||||
w.w = FfxFloat32(w.w * (uvx) * (uvy));
|
||||
FfxFloat32 ws = max(w.x + w.y + w.z + w.w, FfxFloat32(1.0e-3));
|
||||
// normalize
|
||||
w /= ws;
|
||||
|
||||
FfxFloat32x3 history_normal;
|
||||
FfxFloat32 history_linear_depth;
|
||||
reprojection = reprojection00 * w.x + reprojection10 * w.y + reprojection01 * w.z + reprojection11 * w.w;
|
||||
history_linear_depth = depth00 * w.x + depth10 * w.y + depth01 * w.z + depth11 * w.w;
|
||||
history_normal = normal00 * w.x + normal10 * w.y + normal01 * w.z + normal11 * w.w;
|
||||
disocclusion_factor = FFX_DNSR_Reflections_GetDisocclusionFactor(normal, history_normal, linear_depth, history_linear_depth);
|
||||
}
|
||||
disocclusion_factor = disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD ? FfxFloat32(0.0f) : disocclusion_factor;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_Reproject(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxUInt32x2 screen_size, FfxFloat32 temporal_stability_factor, FfxInt32 max_samples) {
|
||||
FFX_DNSR_Reflections_InitializeGroupSharedMemory(dispatch_thread_id, group_thread_id, FfxInt32x2(screen_size));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
group_thread_id += 4; // Center threads in FFX_GROUPSHARED memory
|
||||
|
||||
FfxFloat32 variance = FfxFloat32(1.0f);
|
||||
FfxFloat32 num_samples = FfxFloat32(0.0f);
|
||||
FfxFloat32 roughness = FFX_DNSR_Reflections_LoadRoughness(dispatch_thread_id);
|
||||
FfxFloat32x3 normal = FFX_DNSR_Reflections_LoadWorldSpaceNormal(dispatch_thread_id);
|
||||
FfxFloat32x3 radiance = FFX_DNSR_Reflections_LoadRadiance(dispatch_thread_id);
|
||||
const FfxFloat32 ray_length = FFX_DNSR_Reflections_LoadRayLength(dispatch_thread_id);
|
||||
|
||||
if (FFX_DNSR_Reflections_IsGlossyReflection(roughness)) {
|
||||
FfxFloat32 disocclusion_factor;
|
||||
FfxFloat32x2 reprojection_uv;
|
||||
FfxFloat32x3 reprojection;
|
||||
FFX_DNSR_Reflections_PickReprojection(/*in*/ dispatch_thread_id,
|
||||
/* in */ group_thread_id,
|
||||
/* in */ screen_size,
|
||||
/* in */ roughness,
|
||||
/* in */ ray_length,
|
||||
/* out */ disocclusion_factor,
|
||||
/* out */ reprojection_uv,
|
||||
/* out */ reprojection);
|
||||
if ( (reprojection_uv.x > 0.0f) && (reprojection_uv.y > 0.0f) && (reprojection_uv.x < 1.0f) && (reprojection_uv.y< 1.0f)) {
|
||||
FfxFloat32 prev_variance = FFX_DNSR_Reflections_SampleVarianceHistory(reprojection_uv);
|
||||
num_samples = FFX_DNSR_Reflections_SampleNumSamplesHistory(reprojection_uv) * disocclusion_factor;
|
||||
FfxFloat32 s_max_samples = FfxFloat32(max(8.0f, max_samples * FFX_DNSR_REFLECTIONS_SAMPLES_FOR_ROUGHNESS(roughness)));
|
||||
num_samples = min(s_max_samples, num_samples + FfxFloat32(1.0f));
|
||||
FfxFloat32 new_variance = FFX_DNSR_Reflections_ComputeTemporalVariance(radiance.xyz, reprojection.xyz);
|
||||
if (disocclusion_factor < FFX_DNSR_REFLECTIONS_DISOCCLUSION_THRESHOLD) {
|
||||
FFX_DNSR_Reflections_StoreRadianceReprojected(dispatch_thread_id, FfxFloat32x3(0.0f, 0.0f, 0.0f));
|
||||
FFX_DNSR_Reflections_StoreVariance(dispatch_thread_id, FfxFloat32(1.0f));
|
||||
FFX_DNSR_Reflections_StoreNumSamples(dispatch_thread_id, FfxFloat32(1.0f));
|
||||
} else {
|
||||
FfxFloat32 variance_mix = ffxLerp(new_variance, prev_variance, FfxFloat32(1.0f / num_samples));
|
||||
FFX_DNSR_Reflections_StoreRadianceReprojected(dispatch_thread_id, reprojection);
|
||||
FFX_DNSR_Reflections_StoreVariance(dispatch_thread_id, variance_mix);
|
||||
FFX_DNSR_Reflections_StoreNumSamples(dispatch_thread_id, num_samples);
|
||||
// Mix in reprojection for radiance mip computation
|
||||
radiance = ffxLerp(radiance, reprojection, FfxFloat32(0.3f));
|
||||
}
|
||||
} else {
|
||||
FFX_DNSR_Reflections_StoreRadianceReprojected(dispatch_thread_id, FfxFloat32x3(0.0f, 0.0f, 0.0f));
|
||||
FFX_DNSR_Reflections_StoreVariance(dispatch_thread_id, FfxFloat32(1.0f));
|
||||
FFX_DNSR_Reflections_StoreNumSamples(dispatch_thread_id, FfxFloat32(1.0f));
|
||||
}
|
||||
}
|
||||
|
||||
// Downsample 8x8 -> 1 radiance using FFX_GROUPSHARED memory
|
||||
// Initialize FFX_GROUPSHARED array for downsampling
|
||||
FfxFloat32 weight = FFX_DNSR_Reflections_GetLuminanceWeight(radiance.xyz);
|
||||
radiance.xyz *= weight;
|
||||
if ( (dispatch_thread_id.x >= screen_size.x) || (dispatch_thread_id.y >= screen_size.y) || any(isinf(radiance)) || any(isnan(radiance)) || (weight > FfxFloat32(1.0e3))) {
|
||||
radiance = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
weight = FfxFloat32(0.0f);
|
||||
}
|
||||
|
||||
group_thread_id -= 4; // Center threads in FFX_GROUPSHARED memory
|
||||
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id, FfxFloat32x4(radiance.xyz, weight));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
for (FfxInt32 i = 2; i <= 8; i = i * 2) {
|
||||
FfxInt32 ox = group_thread_id.x * i;
|
||||
FfxInt32 oy = group_thread_id.y * i;
|
||||
FfxInt32 ix = group_thread_id.x * i + i / 2;
|
||||
FfxInt32 iy = group_thread_id.y * i + i / 2;
|
||||
if (ix < 8 && iy < 8) {
|
||||
FfxFloat32x4 rad_weight00 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ox, oy));
|
||||
FfxFloat32x4 rad_weight10 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ox, iy));
|
||||
FfxFloat32x4 rad_weight01 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ix, oy));
|
||||
FfxFloat32x4 rad_weight11 = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(ix, iy));
|
||||
FfxFloat32x4 sum = rad_weight00 + rad_weight01 + rad_weight10 + rad_weight11;
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2(ox, oy), sum);
|
||||
}
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
}
|
||||
|
||||
if ((group_thread_id.x == 0) && (group_thread_id.y == 0)) {
|
||||
FfxFloat32x4 sum = FFX_DNSR_Reflections_LoadFromGroupSharedMemoryRaw(FfxInt32x2(0, 0));
|
||||
FfxFloat32 weight_acc = max(sum.w, FfxFloat32(1.0e-3));
|
||||
FfxFloat32x3 radiance_avg = sum.xyz / weight_acc;
|
||||
FFX_DNSR_Reflections_StoreAverageRadiance(dispatch_thread_id.xy / 8, FfxFloat32x3(radiance_avg));
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if FFX_HALF
|
||||
|
||||
void Reproject(FfxUInt32 group_index, FfxUInt32 group_id, FfxUInt32x2 group_thread_id) {
|
||||
FfxUInt32 packed_coords = GetDenoiserTile(group_id);
|
||||
FfxInt32x2 dispatch_thread_id = FfxInt32x2(packed_coords & 0xffffu, (packed_coords >> 16) & 0xffffu) + FfxInt32x2(group_thread_id);
|
||||
FfxInt32x2 dispatch_group_id = dispatch_thread_id / 8;
|
||||
FfxInt32x2 remapped_group_thread_id = FfxInt32x2(ffxRemapForWaveReduction(group_index));
|
||||
FfxInt32x2 remapped_dispatch_thread_id = dispatch_group_id * 8 + remapped_group_thread_id;
|
||||
|
||||
FFX_DNSR_Reflections_Reproject(remapped_dispatch_thread_id, remapped_group_thread_id, RenderSize(), TemporalStabilityFactor(), 32);
|
||||
}
|
||||
|
||||
#endif // FFX_DNSR_REFLECTIONS_REPROJECT
|
||||
298
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_resolve_temporal.h
vendored
Normal file
298
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_reflections_resolve_temporal.h
vendored
Normal file
@@ -0,0 +1,298 @@
|
||||
// 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_DNSR_REFLECTIONS_RESOLVE_TEMPORAL
|
||||
#define FFX_DNSR_REFLECTIONS_RESOLVE_TEMPORAL
|
||||
|
||||
#define RADIANCE_THRESHOLD 0.0001
|
||||
|
||||
#define FFX_DNSR_REFLECTIONS_ESTIMATES_LOCAL_NEIGHBORHOOD
|
||||
#include "ffx_denoiser_reflections_common.h"
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_0[16][16];
|
||||
FFX_GROUPSHARED FfxUInt32 g_ffx_dnsr_shared_1[16][16];
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
struct FFX_DNSR_Reflections_NeighborhoodSample {
|
||||
FfxFloat16x3 radiance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample FFX_DNSR_Reflections_LoadFromGroupSharedMemory(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
FfxFloat16x3 unpacked_radiance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance).xyz;
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighborSample;
|
||||
neighborSample.radiance = unpacked_radiance;
|
||||
return neighborSample;
|
||||
}
|
||||
|
||||
struct FFX_DNSR_Reflections_Moments {
|
||||
FfxFloat16x3 mean;
|
||||
FfxFloat16x3 variance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_Moments FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(FfxInt32x2 group_thread_id) {
|
||||
FFX_DNSR_Reflections_Moments estimate;
|
||||
estimate.mean = FfxFloat16x3(0.0f, 0.0f, 0.0f);
|
||||
estimate.variance = FfxFloat16x3(0.0f, 0.0f, 0.0f);
|
||||
FfxFloat16 accumulated_weight = FfxFloat16(0.0f);
|
||||
for (FfxInt32 j = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; j <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++j) {
|
||||
for (FfxInt32 i = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; i <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++i) {
|
||||
FfxInt32x2 new_idx = group_thread_id + FfxInt32x2(i, j);
|
||||
FfxFloat16x3 radiance = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(new_idx).radiance;
|
||||
FfxFloat16 weight = FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat16(i)) * FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat16(j));
|
||||
accumulated_weight += weight;
|
||||
estimate.mean += radiance * weight;
|
||||
estimate.variance += radiance * radiance * weight;
|
||||
}
|
||||
}
|
||||
estimate.mean /= accumulated_weight;
|
||||
estimate.variance /= accumulated_weight;
|
||||
|
||||
estimate.variance = abs(estimate.variance - estimate.mean * estimate.mean);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat16x3 radiance) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.zz);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_LoadNeighborhood(FfxInt32x2 pixel_coordinate, out FfxFloat16x3 radiance) { radiance = FFX_DNSR_Reflections_LoadRadiance(pixel_coordinate); }
|
||||
|
||||
void FFX_DNSR_Reflections_InitializeGroupSharedMemory(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxInt32x2 screen_size) {
|
||||
// Load 16x16 region into shared memory using 4 8x8 blocks.
|
||||
FfxInt32x2 offset[4] = {FfxInt32x2(0, 0), FfxInt32x2(8, 0), FfxInt32x2(0, 8), FfxInt32x2(8, 8)};
|
||||
|
||||
// Intermediate storage registers to cache the result of all loads
|
||||
FfxFloat16x3 radiance[4];
|
||||
|
||||
// Start in the upper left corner of the 16x16 region.
|
||||
dispatch_thread_id -= 4;
|
||||
|
||||
// First store all loads in registers
|
||||
for (FfxInt32 i = 0; i < 4; ++i) {
|
||||
FFX_DNSR_Reflections_LoadNeighborhood(dispatch_thread_id + offset[i], radiance[i]);
|
||||
}
|
||||
|
||||
// Then move all registers to FFX_GROUPSHARED memory
|
||||
for (FfxInt32 j = 0; j < 4; ++j) {
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id + offset[j], radiance[j]);
|
||||
}
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_ResolveTemporal(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxUInt32x2 screen_size, FfxFloat32x2 inv_screen_size, FfxFloat32 history_clip_weight) {
|
||||
FFX_DNSR_Reflections_InitializeGroupSharedMemory(dispatch_thread_id, group_thread_id, FfxInt32x2(screen_size));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
group_thread_id += 4; // Center threads in FFX_GROUPSHARED memory
|
||||
|
||||
FfxFloat16x3 radiance = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(group_thread_id).radiance;
|
||||
FfxFloat32 radianceSum = radiance.x + radiance.y + radiance.z;
|
||||
if (radianceSum < RADIANCE_THRESHOLD)
|
||||
{
|
||||
FFX_DNSR_Reflections_StoreTemporalAccumulation(dispatch_thread_id, FfxFloat16x3(0.0f, 0.0f, 0.0f), FfxFloat16(0.0f));
|
||||
return;
|
||||
}
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample center = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(group_thread_id);
|
||||
FfxFloat16x3 new_signal = center.radiance;
|
||||
FfxFloat16 roughness = FFX_DNSR_Reflections_LoadRoughness(dispatch_thread_id);
|
||||
FfxFloat16 new_variance = FFX_DNSR_Reflections_LoadVariance(dispatch_thread_id);
|
||||
|
||||
if (FFX_DNSR_Reflections_IsGlossyReflection(roughness)) {
|
||||
FfxFloat16 num_samples = FFX_DNSR_Reflections_LoadNumSamples(dispatch_thread_id);
|
||||
FfxFloat32x2 uv8 = (FfxFloat32x2(dispatch_thread_id.xy) + (0.5).xx) / FFX_DNSR_Reflections_RoundUp8(screen_size);
|
||||
FfxFloat16x3 avg_radiance = FFX_DNSR_Reflections_SampleAverageRadiance(uv8);
|
||||
|
||||
FfxFloat16x3 old_signal = FFX_DNSR_Reflections_LoadRadianceReprojected(dispatch_thread_id);
|
||||
FFX_DNSR_Reflections_Moments local_neighborhood = FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(group_thread_id);
|
||||
// Clip history based on the curren local statistics
|
||||
FfxFloat16x3 color_std = FfxFloat16x3((sqrt(local_neighborhood.variance.xyz) + length(local_neighborhood.mean.xyz - avg_radiance)) * history_clip_weight * 1.4f);
|
||||
local_neighborhood.mean.xyz = ffxLerp(local_neighborhood.mean.xyz, avg_radiance, FfxFloat16x3(0.2f, 0.2f, 0.2f));
|
||||
FfxFloat16x3 radiance_min = local_neighborhood.mean.xyz - color_std;
|
||||
FfxFloat16x3 radiance_max = local_neighborhood.mean.xyz + color_std;
|
||||
FfxFloat16x3 clipped_old_signal = FFX_DNSR_Reflections_ClipAABB(radiance_min, radiance_max, old_signal.xyz);
|
||||
FfxFloat16 accumulation_speed = FfxFloat16(1.0f) / max(num_samples, FfxFloat16(1.0f));
|
||||
FfxFloat16 weight = (FfxFloat16(1.0f) - accumulation_speed);
|
||||
// Blend with average for small sample count
|
||||
new_signal.xyz = ffxLerp(new_signal.xyz, avg_radiance, FfxFloat16(1.0f) / max(num_samples + FfxFloat16(1.0f), FfxFloat16(1.0f)));
|
||||
// Clip outliers
|
||||
{
|
||||
FfxFloat16x3 radiance_min = avg_radiance.xyz - color_std * FfxFloat16x3(1.0f, 1.0f, 1.0f);
|
||||
FfxFloat16x3 radiance_max = avg_radiance.xyz + color_std * FfxFloat16x3(1.0f, 1.0f, 1.0f);
|
||||
new_signal.xyz = FFX_DNSR_Reflections_ClipAABB(radiance_min, radiance_max, new_signal.xyz);
|
||||
}
|
||||
// Blend with history
|
||||
#ifdef FFX_GLSL
|
||||
new_signal = (FfxFloat16(1.0) - weight) * new_signal + weight * clipped_old_signal;
|
||||
#else
|
||||
new_signal = ffxLerp(new_signal, clipped_old_signal, weight);
|
||||
#endif
|
||||
new_variance = ffxLerp(FFX_DNSR_Reflections_ComputeTemporalVariance(new_signal.xyz, clipped_old_signal.xyz), new_variance, weight);
|
||||
if (any(isinf(new_signal)) || any(isnan(new_signal)) || isinf(new_variance) || isnan(new_variance)) {
|
||||
new_signal = FfxFloat16x3(0.0f, 0.0f, 0.0f);
|
||||
new_variance = FfxFloat16(0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
FFX_DNSR_Reflections_StoreTemporalAccumulation(dispatch_thread_id, new_signal, new_variance);
|
||||
}
|
||||
|
||||
#else // #if FFX_HALF
|
||||
|
||||
struct FFX_DNSR_Reflections_NeighborhoodSample {
|
||||
FfxFloat32x3 radiance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample FFX_DNSR_Reflections_LoadFromGroupSharedMemory(FfxInt32x2 idx) {
|
||||
FfxUInt32x2 packed_radiance = FfxUInt32x2(g_ffx_dnsr_shared_0[idx.y][idx.x], g_ffx_dnsr_shared_1[idx.y][idx.x]);
|
||||
FfxFloat32x3 unpacked_radiance = FFX_DNSR_Reflections_UnpackFloat16_4(packed_radiance).xyz;
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample neighborSample;
|
||||
neighborSample.radiance = unpacked_radiance;
|
||||
return neighborSample;
|
||||
}
|
||||
|
||||
struct FFX_DNSR_Reflections_Moments {
|
||||
FfxFloat32x3 mean;
|
||||
FfxFloat32x3 variance;
|
||||
};
|
||||
|
||||
FFX_DNSR_Reflections_Moments FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(FfxInt32x2 group_thread_id) {
|
||||
FFX_DNSR_Reflections_Moments estimate;
|
||||
estimate.mean = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
estimate.variance = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
FfxFloat32 accumulated_weight = FfxFloat32(0.0f);
|
||||
for (FfxInt32 j = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; j <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++j) {
|
||||
for (FfxInt32 i = -FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; i <= FFX_DNSR_REFLECTIONS_LOCAL_NEIGHBORHOOD_RADIUS; ++i) {
|
||||
FfxInt32x2 new_idx = group_thread_id + FfxInt32x2(i, j);
|
||||
FfxFloat32x3 radiance = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(new_idx).radiance;
|
||||
FfxFloat32 weight = FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat32(i)) * FFX_DNSR_Reflections_LocalNeighborhoodKernelWeight(FfxFloat32(j));
|
||||
accumulated_weight += weight;
|
||||
estimate.mean += radiance * weight;
|
||||
estimate.variance += radiance * radiance * weight;
|
||||
}
|
||||
}
|
||||
estimate.mean /= accumulated_weight;
|
||||
estimate.variance /= accumulated_weight;
|
||||
|
||||
estimate.variance = abs(estimate.variance - estimate.mean * estimate.mean);
|
||||
return estimate;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_StoreInGroupSharedMemory(FfxInt32x2 group_thread_id, FfxFloat32x3 radiance) {
|
||||
g_ffx_dnsr_shared_0[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.xy);
|
||||
g_ffx_dnsr_shared_1[group_thread_id.y][group_thread_id.x] = FFX_DNSR_Reflections_PackFloat16(radiance.zz);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_LoadNeighborhood(FfxInt32x2 pixel_coordinate, out FfxFloat32x3 radiance) { radiance = FFX_DNSR_Reflections_LoadRadiance(pixel_coordinate); }
|
||||
|
||||
void FFX_DNSR_Reflections_InitializeGroupSharedMemory(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxInt32x2 screen_size) {
|
||||
// Load 16x16 region into shared memory using 4 8x8 blocks.
|
||||
FfxInt32x2 offset[4] = {FfxInt32x2(0, 0), FfxInt32x2(8, 0), FfxInt32x2(0, 8), FfxInt32x2(8, 8)};
|
||||
|
||||
// Intermediate storage registers to cache the result of all loads
|
||||
FfxFloat32x3 radiance[4];
|
||||
|
||||
// Start in the upper left corner of the 16x16 region.
|
||||
dispatch_thread_id -= 4;
|
||||
|
||||
// First store all loads in registers
|
||||
for (FfxInt32 i = 0; i < 4; ++i) {
|
||||
FFX_DNSR_Reflections_LoadNeighborhood(dispatch_thread_id + offset[i], radiance[i]);
|
||||
}
|
||||
|
||||
// Then move all registers to FFX_GROUPSHARED memory
|
||||
for (FfxInt32 j = 0; j < 4; ++j) {
|
||||
FFX_DNSR_Reflections_StoreInGroupSharedMemory(group_thread_id + offset[j], radiance[j]);
|
||||
}
|
||||
}
|
||||
|
||||
void FFX_DNSR_Reflections_ResolveTemporal(FfxInt32x2 dispatch_thread_id, FfxInt32x2 group_thread_id, FfxUInt32x2 screen_size, FfxFloat32x2 inv_screen_size, FfxFloat32 history_clip_weight) {
|
||||
FFX_DNSR_Reflections_InitializeGroupSharedMemory(dispatch_thread_id, group_thread_id, FfxInt32x2(screen_size));
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
group_thread_id += 4; // Center threads in FFX_GROUPSHARED memory
|
||||
|
||||
FfxFloat32x3 radiance = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(group_thread_id).radiance;
|
||||
FfxFloat32 radianceSum = radiance.x + radiance.y + radiance.z;
|
||||
if (radianceSum < RADIANCE_THRESHOLD)
|
||||
{
|
||||
FFX_DNSR_Reflections_StoreTemporalAccumulation(dispatch_thread_id, FfxFloat32x3(0.0f, 0.0f, 0.0f), FfxFloat32(0.0f));
|
||||
return;
|
||||
}
|
||||
|
||||
FFX_DNSR_Reflections_NeighborhoodSample center = FFX_DNSR_Reflections_LoadFromGroupSharedMemory(group_thread_id);
|
||||
FfxFloat32x3 new_signal = center.radiance;
|
||||
FfxFloat32 roughness = FFX_DNSR_Reflections_LoadRoughness(dispatch_thread_id);
|
||||
FfxFloat32 new_variance = FFX_DNSR_Reflections_LoadVariance(dispatch_thread_id);
|
||||
|
||||
if (FFX_DNSR_Reflections_IsGlossyReflection(roughness)) {
|
||||
FfxFloat32 num_samples = FFX_DNSR_Reflections_LoadNumSamples(dispatch_thread_id);
|
||||
FfxFloat32x2 uv8 = (FfxFloat32x2(dispatch_thread_id.xy) + (0.5).xx) / FFX_DNSR_Reflections_RoundUp8(screen_size);
|
||||
FfxFloat32x3 avg_radiance = FFX_DNSR_Reflections_SampleAverageRadiance(uv8);
|
||||
|
||||
FfxFloat32x3 old_signal = FFX_DNSR_Reflections_LoadRadianceReprojected(dispatch_thread_id);
|
||||
FFX_DNSR_Reflections_Moments local_neighborhood = FFX_DNSR_Reflections_EstimateLocalNeighborhoodInGroup(group_thread_id);
|
||||
// Clip history based on the curren local statistics
|
||||
FfxFloat32x3 color_std = FfxFloat32x3((sqrt(local_neighborhood.variance.xyz) + length(local_neighborhood.mean.xyz - avg_radiance)) * history_clip_weight * 1.4f);
|
||||
local_neighborhood.mean.xyz = ffxLerp(local_neighborhood.mean.xyz, avg_radiance, FfxFloat32x3(0.2f, 0.2f, 0.2f));
|
||||
FfxFloat32x3 radiance_min = local_neighborhood.mean.xyz - color_std;
|
||||
FfxFloat32x3 radiance_max = local_neighborhood.mean.xyz + color_std;
|
||||
FfxFloat32x3 clipped_old_signal = FFX_DNSR_Reflections_ClipAABB(radiance_min, radiance_max, old_signal.xyz);
|
||||
FfxFloat32 accumulation_speed = FfxFloat32(1.0f) / max(num_samples, FfxFloat32(1.0f));
|
||||
FfxFloat32 weight = (FfxFloat32(1.0f) - accumulation_speed);
|
||||
// Blend with average for small sample count
|
||||
new_signal.xyz = ffxLerp(new_signal.xyz, avg_radiance, FfxFloat32(1.0f) / max(num_samples + FfxFloat32(1.0f), FfxFloat32(1.0f)));
|
||||
// Clip outliers
|
||||
{
|
||||
FfxFloat32x3 radiance_min = avg_radiance.xyz - color_std * FfxFloat32x3(1.0f, 1.0f, 1.0f);
|
||||
FfxFloat32x3 radiance_max = avg_radiance.xyz + color_std * FfxFloat32x3(1.0f, 1.0f, 1.0f);
|
||||
new_signal.xyz = FFX_DNSR_Reflections_ClipAABB(radiance_min, radiance_max, new_signal.xyz);
|
||||
}
|
||||
// Blend with history
|
||||
new_signal = ffxLerp(new_signal, clipped_old_signal, weight);
|
||||
new_variance = ffxLerp(FFX_DNSR_Reflections_ComputeTemporalVariance(new_signal.xyz, clipped_old_signal.xyz), new_variance, weight);
|
||||
if (any(isinf(new_signal)) || any(isnan(new_signal)) || isinf(new_variance) || isnan(new_variance)) {
|
||||
new_signal = FfxFloat32x3(0.0f, 0.0f, 0.0f);
|
||||
new_variance = FfxFloat32(0.0f);
|
||||
}
|
||||
|
||||
}
|
||||
FFX_DNSR_Reflections_StoreTemporalAccumulation(dispatch_thread_id, new_signal, new_variance);
|
||||
}
|
||||
|
||||
#endif // #if FFX_HALF
|
||||
|
||||
void ResolveTemporal(FfxUInt32 group_index, FfxUInt32 group_id, FfxUInt32x2 group_thread_id) {
|
||||
FfxUInt32 packed_coords = GetDenoiserTile(group_id);
|
||||
FfxInt32x2 dispatch_thread_id = FfxInt32x2(packed_coords & 0xffffu, (packed_coords >> 16) & 0xffffu) + FfxInt32x2(group_thread_id);
|
||||
FfxInt32x2 dispatch_group_id = dispatch_thread_id / 8;
|
||||
FfxInt32x2 remapped_group_thread_id = FfxInt32x2(ffxRemapForWaveReduction(group_index));
|
||||
FfxInt32x2 remapped_dispatch_thread_id = dispatch_group_id * 8 + remapped_group_thread_id;
|
||||
|
||||
FFX_DNSR_Reflections_ResolveTemporal(remapped_dispatch_thread_id, remapped_group_thread_id, RenderSize(), InverseRenderSize(), TemporalStabilityFactor());
|
||||
}
|
||||
|
||||
#endif // FFX_DNSR_REFLECTIONS_RESOLVE_TEMPORAL
|
||||
94
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_resources.h
vendored
Normal file
94
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_resources.h
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
// 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_SHADOWS_DENOISER_RESOURCES_H
|
||||
#define FFX_SHADOWS_DENOISER_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_HIT_MASK_RESULTS 1
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_TILE_BUFFER 2
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_SHADOW_MASK 3
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_RAYTRACER_RESULT 4
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_DEPTH 5
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_VELOCITY 6
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_NORMAL 7
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_NORMAL_FP16 8 //same resource as NORMAL
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_PREVIOUS_DEPTH 9
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_TILE_META_DATA 10
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_MOMENTS0 11
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_MOMENTS1 12
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_PREVIOUS_MOMENTS 13 //same resource as MOMENT0 & MOMENT1
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_CURRENT_MOMENTS 14 //same resource as MOMENT0 & MOMENT1
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_SCRATCH0 15
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_SCRATCH1 16
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_HISTORY 17 //same resource as SCRATCH1
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_REPROJECTION_RESULTS 18 //same resource as SCRATCH0
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_FILTER_INPUT 19 //same resource as SCRATCH0 & SCRATCH1
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_FILTER_OUTPUT 20
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_INPUT_DEPTH_HIERARCHY 21
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_INPUT_MOTION_VECTORS 22
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_INPUT_NORMAL 23
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_OUTPUT 24
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_RADIANCE 25
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_RADIANCE_HISTORY 26
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_VARIANCE 27
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_SAMPLE_COUNT 28
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_AVERAGE_RADIANCE 29
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_DENOISER_TILE_LIST 10
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_EXTRACTED_ROUGHNESS 31
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_DEPTH_HISTORY 32
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_NORMAL_HISTORY 33
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_ROUGHNESS_HISTORY 34
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_RADIANCE_0 35
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_RADIANCE_1 36
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_VARIANCE_0 37
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_VARIANCE_1 38
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_SAMPLE_COUNT_0 39
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_SAMPLE_COUNT_1 40
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_AVERAGE_RADIANCE_0 41
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_AVERAGE_RADIANCE_1 42
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_REPROJECTED_RADIANCE 43
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_INDIRECT_ARGS 44
|
||||
|
||||
#define FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT 45
|
||||
|
||||
// CBV resource definitions
|
||||
#define FFX_DENOISER_SHADOWS_CONSTANTBUFFER_IDENTIFIER_DENOISER_SHADOWS0 0
|
||||
#define FFX_DENOISER_SHADOWS_CONSTANTBUFFER_IDENTIFIER_DENOISER_SHADOWS1 1
|
||||
#define FFX_DENOISER_SHADOWS_CONSTANTBUFFER_IDENTIFIER_DENOISER_SHADOWS2 2
|
||||
#define FFX_DENOISER_SHADOWS_CONSTANTBUFFER_IDENTIFIER_DENOISER_SHADOWS_COUNT 3
|
||||
|
||||
// CBV resource definitions
|
||||
#define FFX_DENOISER_REFLECTIONS_CONSTANTBUFFER_IDENTIFIER 0
|
||||
#define FFX_DENOISER_REFLECTIONS_CONSTANTBUFFER_IDENTIFIER_COUNT 1
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif // FFX_SHADOWS_DENOISER_RESOURCES_H
|
||||
378
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_callbacks_glsl.h
vendored
Normal file
378
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
// 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_denoiser_resources.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core.h"
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB0_DENOISER_SHADOWS)
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_CB0_DENOISER_SHADOWS, std140) uniform cb0DenoiserShadows_t
|
||||
{
|
||||
FfxInt32x2 iBufferDimensions;
|
||||
} cb0DenoiserShadows;
|
||||
#endif
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS, std140) uniform cb1DenoiserShadows_t
|
||||
{
|
||||
FfxFloat32x3 fEye;
|
||||
FfxInt32 iFirstFrame;
|
||||
FfxInt32x2 iBufferDimensions;
|
||||
FfxFloat32x2 fInvBufferDimensions;
|
||||
FfxFloat32x2 fMotionVectorScale;
|
||||
FfxFloat32x2 normalsUnpackMul_unpackAdd;
|
||||
FfxFloat32Mat4 fProjectionInverse;
|
||||
FfxFloat32Mat4 fReprojectionMatrix;
|
||||
FfxFloat32Mat4 fViewProjectionInverse;
|
||||
} cb1DenoiserShadows;
|
||||
#endif
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS, std140) uniform cb2DenoiserShadows_t
|
||||
{
|
||||
FfxFloat32Mat4 fProjectionInverse;
|
||||
FfxFloat32x2 fInvBufferDimensions;
|
||||
FfxFloat32x2 normalsUnpackMul_unpackAdd;
|
||||
FfxInt32x2 iBufferDimensions;
|
||||
FfxFloat32 fDepthSimilaritySigma;
|
||||
} cb2DenoiserShadows;
|
||||
#endif
|
||||
|
||||
FfxInt32x2 BufferDimensions()
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB0_DENOISER_SHADOWS)
|
||||
return cb0DenoiserShadows.iBufferDimensions;
|
||||
#elif defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
return cb1DenoiserShadows.iBufferDimensions;
|
||||
#elif defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
return cb2DenoiserShadows.iBufferDimensions;
|
||||
#endif
|
||||
|
||||
return FfxInt32x2(0, 0);
|
||||
}
|
||||
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
return cb1DenoiserShadows.fMotionVectorScale;
|
||||
#endif
|
||||
return FfxFloat32x2(0, 0);
|
||||
}
|
||||
|
||||
// SRVs
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS)
|
||||
uniform utexture2D r_hit_mask_results;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_DEPTH
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_DEPTH)
|
||||
uniform texture2D r_depth;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_VELOCITY
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_VELOCITY)
|
||||
uniform texture2D r_velocity;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_NORMAL
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_NORMAL)
|
||||
uniform texture2D r_normal;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_HISTORY
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_HISTORY)
|
||||
uniform texture2D r_history;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH)
|
||||
uniform texture2D r_previous_depth;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS)
|
||||
uniform texture2D r_previous_moments;
|
||||
#endif
|
||||
#if FFX_HALF
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT)
|
||||
uniform texture2D r_filter_input;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// UAV declarations
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK, std430) buffer rw_shadow_mask_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_shadow_mask;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT, std430) buffer rw_raytracer_result_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_raytracer_result;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_TILE_METADATA
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_UAV_TILE_METADATA, std430) buffer rw_tile_metadata_t
|
||||
{
|
||||
FfxUInt32 data[];
|
||||
} rw_tile_metadata;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS, rg32f)
|
||||
uniform image2D rw_reprojection_results;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS, rgba32f)
|
||||
uniform image2D rw_current_moments;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_HISTORY
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_UAV_HISTORY, rg32f)
|
||||
uniform image2D rw_history;
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT
|
||||
layout (set = 0, binding = DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT) writeonly
|
||||
uniform image2D rw_filter_output;
|
||||
#endif
|
||||
|
||||
#define TILE_SIZE_X 8
|
||||
#define TILE_SIZE_Y 4
|
||||
|
||||
FfxUInt32 LaneIdToBitShift(FfxUInt32x2 localID)
|
||||
{
|
||||
return localID.y * TILE_SIZE_X + localID.x;
|
||||
}
|
||||
|
||||
FfxBoolean WaveMaskToBool(FfxUInt32 mask, FfxUInt32x2 localID)
|
||||
{
|
||||
return FfxBoolean((FfxUInt32(1) << LaneIdToBitShift(localID.xy)) & mask);
|
||||
}
|
||||
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS)
|
||||
FfxBoolean HitsLight(FfxUInt32x2 did, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
FfxUInt32 mask = texelFetch(r_hit_mask_results, ivec2(gid), 0).r;
|
||||
return !WaveMaskToBool(mask, gtid);
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS)
|
||||
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
return cb1DenoiserShadows.normalsUnpackMul_unpackAdd[0];
|
||||
#endif
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
return cb2DenoiserShadows.normalsUnpackMul_unpackAdd[0];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
return cb1DenoiserShadows.normalsUnpackMul_unpackAdd[1];
|
||||
#endif
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
return cb2DenoiserShadows.normalsUnpackMul_unpackAdd[1];
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK)
|
||||
void StoreShadowMask(FfxUInt32 offset, FfxUInt32 value)
|
||||
{
|
||||
rw_shadow_mask.data[offset] = value;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxFloat32Mat4 ViewProjectionInverse()
|
||||
{
|
||||
return cb1DenoiserShadows.fViewProjectionInverse;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxFloat32Mat4 ReprojectionMatrix()
|
||||
{
|
||||
return cb1DenoiserShadows.fReprojectionMatrix;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
FfxFloat32Mat4 ProjectionInverse()
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
return cb1DenoiserShadows.fProjectionInverse;
|
||||
#endif
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
return cb2DenoiserShadows.fProjectionInverse;
|
||||
#else
|
||||
return FfxFloat32Mat4(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
FfxFloat32x2 InvBufferDimensions()
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
return cb1DenoiserShadows.fInvBufferDimensions;
|
||||
#elif defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
return cb2DenoiserShadows.fInvBufferDimensions;
|
||||
#else
|
||||
return FfxFloat32x2(0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxInt32 IsFirstFrame()
|
||||
{
|
||||
return cb1DenoiserShadows.iFirstFrame;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxFloat32x3 Eye()
|
||||
{
|
||||
return cb1DenoiserShadows.fEye;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
FfxFloat32 LoadDepth(FfxInt32x2 p)
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_DEPTH)
|
||||
return texelFetch(r_depth, ivec2(p), 0).x;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH)
|
||||
FfxFloat32 LoadPreviousDepth(FfxInt32x2 p)
|
||||
{
|
||||
return texelFetch(r_previous_depth, ivec2(p), 0).x;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_NORMAL)
|
||||
FfxFloat32x3 LoadNormals(FfxUInt32x2 p)
|
||||
{
|
||||
FfxFloat32x3 normal = texelFetch(r_normal, ivec2(p), 0).xyz;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
return normalize(normal);
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_NORMAL)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_VELOCITY)
|
||||
FfxFloat32x2 LoadVelocity(FfxInt32x2 p)
|
||||
{
|
||||
FfxFloat32x2 velocity = texelFetch(r_velocity, ivec2(p), 0).rg;
|
||||
return velocity * MotionVectorScale();
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_VELOCITY)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_HISTORY)
|
||||
layout (set = 0, binding = 1000) uniform sampler s_trilinerClamp;
|
||||
FfxFloat32 LoadHistory(FfxFloat32x2 p)
|
||||
{
|
||||
return FfxFloat32(textureLod(sampler2D(r_history, s_trilinerClamp), p, 0.0f).x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS)
|
||||
FfxFloat32x3 LoadPreviousMomentsBuffer(FfxInt32x2 p)
|
||||
{
|
||||
return texelFetch(r_previous_moments, ivec2(p), 0).xyz;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT)
|
||||
FfxUInt32 LoadRaytracedShadowMask(FfxUInt32 p)
|
||||
{
|
||||
return rw_raytracer_result.data[p];
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
void StoreMetadata(FfxUInt32 p, FfxUInt32 val)
|
||||
{
|
||||
rw_tile_metadata.data[p] = val;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS)
|
||||
void StoreMoments(FfxUInt32x2 p, FfxFloat32x3 val)
|
||||
{
|
||||
imageStore(rw_current_moments, ivec2(p), FfxFloat32x4(val, 0));
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS)
|
||||
void StoreReprojectionResults(FfxUInt32x2 p, FfxFloat32x2 val)
|
||||
{
|
||||
imageStore(rw_reprojection_results, ivec2(p), FfxFloat32x4(val, 0, 0));
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
FfxFloat32 DepthSimilaritySigma()
|
||||
{
|
||||
return cb2DenoiserShadows.fDepthSimilaritySigma;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT)
|
||||
FfxFloat16x2 LoadFilterInput(FfxUInt32x2 p)
|
||||
{
|
||||
return FfxFloat16x2(texelFetch(r_filter_input, ivec2(p), 0).xy);
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT)
|
||||
|
||||
#endif // #if FFX_HALF
|
||||
|
||||
FfxBoolean IsShadowReciever(FfxUInt32x2 p)
|
||||
{
|
||||
FfxFloat32 depth = LoadDepth(FfxInt32x2(p));
|
||||
return (depth > 0.0f) && (depth < 1.0f);
|
||||
}
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
FfxUInt32 LoadTileMetaData(FfxUInt32 p)
|
||||
{
|
||||
return rw_tile_metadata.data[p];
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
|
||||
void StoreHistory(FfxUInt32x2 p, FfxFloat32x2 val)
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_HISTORY)
|
||||
imageStore(rw_history, ivec2(p), FfxFloat32x4(val, 0, 0));
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_HISTORY)
|
||||
}
|
||||
|
||||
void StoreFilterOutput(FfxUInt32x2 p, FfxFloat32 val)
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT)
|
||||
imageStore(rw_filter_output, ivec2(p), FfxFloat32x4(val, 0, 0, 0));
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT)
|
||||
}
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
392
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_callbacks_hlsl.h
vendored
Normal file
392
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,392 @@
|
||||
// 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_denoiser_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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#pragma warning(disable: 3205) // conversion from larger type to smaller
|
||||
|
||||
#define FFX_DECLARE_SRV_REGISTER(regIndex) t##regIndex
|
||||
#define FFX_DECLARE_UAV_REGISTER(regIndex) u##regIndex
|
||||
#define FFX_DECLARE_CB_REGISTER(regIndex) b##regIndex
|
||||
#define FFX_DENOISER_SHADOWS_DECLARE_SRV(regIndex) register(FFX_DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_DENOISER_SHADOWS_DECLARE_UAV(regIndex) register(FFX_DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_DENOISER_SHADOWS_DECLARE_CB(regIndex) register(FFX_DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB0_DENOISER_SHADOWS)
|
||||
cbuffer cb0DenoiserShadows : FFX_DENOISER_SHADOWS_DECLARE_CB(DENOISER_SHADOWS_BIND_CB0_DENOISER_SHADOWS)
|
||||
{
|
||||
FfxInt32x2 iBufferDimensions;
|
||||
#define FFX_DENOISER_SHADOWS_CONSTANT_BUFFER_0_SIZE 2
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
cbuffer cb1DenoiserShadows : FFX_DENOISER_SHADOWS_DECLARE_CB(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
{
|
||||
FfxFloat32x3 fEye;
|
||||
FfxInt32 iFirstFrame;
|
||||
FfxInt32x2 iBufferDimensions;
|
||||
FfxFloat32x2 fInvBufferDimensions;
|
||||
FfxFloat32x2 fMotionVectorScale;
|
||||
FfxFloat32x2 normalsUnpackMul_unpackAdd;
|
||||
FfxFloat32Mat4 fProjectionInverse;
|
||||
FfxFloat32Mat4 fReprojectionMatrix;
|
||||
FfxFloat32Mat4 fViewProjectionInverse;
|
||||
#define FFX_DENOISER_SHADOWS_CONSTANT_BUFFER_1_SIZE 56
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
cbuffer cb2DenoiserShadows : FFX_DENOISER_SHADOWS_DECLARE_CB(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
{
|
||||
FfxFloat32Mat4 fProjectionInverse;
|
||||
FfxFloat32x2 fInvBufferDimensions;
|
||||
FfxFloat32x2 normalsUnpackMul_unpackAdd;
|
||||
FfxInt32x2 iBufferDimensions;
|
||||
FfxFloat32 fDepthSimilaritySigma;
|
||||
#define FFX_DENOISER_SHADOWS_CONSTANT_BUFFER_2_SIZE 24
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#define FFX_DENOISER_SHADOWS_ROOTSIG_STRINGIFY(p) FFX_DENOISER_SHADOWS_ROOTSIG_STR(p)
|
||||
#define FFX_DENOISER_SHADOWS_ROOTSIG_STR(p) #p
|
||||
#define FFX_DENOISER_SHADOWS_PREPARE_SHADOW_MASK_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_DENOISER_SHADOWS_ROOTSIG_STRINGIFY(FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_DENOISER_SHADOWS_ROOTSIG_STRINGIFY(FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0)")]
|
||||
|
||||
#define FFX_DENOISER_SHADOWS_TILE_CLASSIFICATION_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_DENOISER_SHADOWS_ROOTSIG_STRINGIFY(FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_DENOISER_SHADOWS_ROOTSIG_STRINGIFY(FFX_DENOISER_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, " \
|
||||
"MinLOD = 0, " \
|
||||
"MaxLOD = 3.402823466e+38f, " \
|
||||
"mipLODBias = 0, " \
|
||||
"comparisonFunc = COMPARISON_LESS_EQUAL, " \
|
||||
"maxAnisotropy = 16, " \
|
||||
"borderColor = STATIC_BORDER_COLOR_OPAQUE_WHITE)")]
|
||||
|
||||
#define FFX_DENOISER_SHADOWS_FILTER_SOFT_SHADOWS_ROOTSIG [RootSignature( "DescriptorTable(UAV(u0, numDescriptors = " FFX_DENOISER_SHADOWS_ROOTSIG_STRINGIFY(FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_DENOISER_SHADOWS_ROOTSIG_STRINGIFY(FFX_DENOISER_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"CBV(b0)")]
|
||||
|
||||
#if defined(FFX_DENOISER_SHADOWS_EMBED_ROOTSIG)
|
||||
#define FFX_DENOISER_SHADOWS_EMBED_PREPARE_SHADOW_MASK_ROOTSIG_CONTENT FFX_DENOISER_SHADOWS_PREPARE_SHADOW_MASK_ROOTSIG
|
||||
#define FFX_DENOISER_SHADOWS_EMBED_TILE_CLASSIFICATION_ROOTSIG_CONTENT FFX_DENOISER_SHADOWS_TILE_CLASSIFICATION_ROOTSIG
|
||||
#define FFX_DENOISER_SHADOWS_EMBED_FILTER_SOFT_SHADOWS_ROOTSIG_CONTENT FFX_DENOISER_SHADOWS_FILTER_SOFT_SHADOWS_ROOTSIG
|
||||
#else
|
||||
#define FFX_DENOISER_SHADOWS_EMBED_PREPARE_SHADOW_MASK_ROOTSIG_CONTENT
|
||||
#define FFX_DENOISER_SHADOWS_EMBED_TILE_CLASSIFICATION_ROOTSIG_CONTENT
|
||||
#define FFX_DENOISER_SHADOWS_EMBED_FILTER_SOFT_SHADOWS_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_DENOISER_SHADOWS_EMBED_ROOTSIG
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
// Sampler
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_HISTORY)
|
||||
SamplerState s_trilinerClamp : register(s0);
|
||||
#endif
|
||||
|
||||
// SRVs
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS
|
||||
Texture2D<FfxUInt32> r_hit_mask_results : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_DEPTH
|
||||
Texture2D<FfxFloat32> r_depth : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_DEPTH);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_VELOCITY
|
||||
Texture2D<FfxFloat32x2> r_velocity : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_VELOCITY);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_NORMAL
|
||||
Texture2D<FfxFloat32x3> r_normal : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_NORMAL);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_HISTORY
|
||||
Texture2D<FfxFloat32x2> r_history : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_HISTORY);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH
|
||||
Texture2D<FfxFloat32> r_previous_depth : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS
|
||||
Texture2D<FfxFloat32x3> r_previous_moments : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS);
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
#if defined DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT
|
||||
Texture2D<FfxFloat16x2> r_filter_input : FFX_DENOISER_SHADOWS_DECLARE_SRV(DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// UAV declarations
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK
|
||||
RWStructuredBuffer<FfxUInt32> rw_shadow_mask : FFX_DENOISER_SHADOWS_DECLARE_UAV(DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT
|
||||
RWStructuredBuffer<FfxUInt32> rw_raytracer_result : FFX_DENOISER_SHADOWS_DECLARE_UAV(DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_TILE_METADATA
|
||||
RWStructuredBuffer<FfxUInt32> rw_tile_metadata : FFX_DENOISER_SHADOWS_DECLARE_UAV(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS
|
||||
RWTexture2D<FfxFloat32x2> rw_reprojection_results : FFX_DENOISER_SHADOWS_DECLARE_UAV(DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS
|
||||
RWTexture2D<FfxFloat32x3> rw_current_moments : FFX_DENOISER_SHADOWS_DECLARE_UAV(DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_HISTORY
|
||||
RWTexture2D<FfxFloat32x2> rw_history : FFX_DENOISER_SHADOWS_DECLARE_UAV(DENOISER_SHADOWS_BIND_UAV_HISTORY);
|
||||
#endif
|
||||
#if defined DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT
|
||||
RWTexture2D<unorm FfxFloat32x4> rw_filter_output : FFX_DENOISER_SHADOWS_DECLARE_UAV(DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT);
|
||||
#endif
|
||||
|
||||
#define TILE_SIZE_X 8
|
||||
#define TILE_SIZE_Y 4
|
||||
|
||||
FfxUInt32 LaneIdToBitShift(FfxUInt32x2 localID)
|
||||
{
|
||||
return localID.y * TILE_SIZE_X + localID.x;
|
||||
}
|
||||
|
||||
FfxBoolean WaveMaskToBool(FfxUInt32 mask, FfxUInt32x2 localID)
|
||||
{
|
||||
return (1 << LaneIdToBitShift(localID.xy)) & mask;
|
||||
}
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB0_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
FfxInt32x2 BufferDimensions()
|
||||
{
|
||||
return iBufferDimensions;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB0_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS)
|
||||
FfxBoolean HitsLight(FfxUInt32x2 did, FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
return !WaveMaskToBool(r_hit_mask_results[gid], gtid);
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_INPUT_HIT_MASK_RESULTS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
FfxFloat32 NormalsUnpackMul()
|
||||
{
|
||||
return normalsUnpackMul_unpackAdd[0];
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
FfxFloat32 NormalsUnpackAdd()
|
||||
{
|
||||
return normalsUnpackMul_unpackAdd[1];
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK)
|
||||
void StoreShadowMask(FfxUInt32 offset, FfxUInt32 value)
|
||||
{
|
||||
rw_shadow_mask[offset] = value;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_SHADOW_MASK)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxFloat32Mat4 ViewProjectionInverse()
|
||||
{
|
||||
return fViewProjectionInverse;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxFloat32Mat4 ReprojectionMatrix()
|
||||
{
|
||||
return fReprojectionMatrix;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
FfxFloat32Mat4 ProjectionInverse()
|
||||
{
|
||||
return fProjectionInverse;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
FfxFloat32x2 InvBufferDimensions()
|
||||
{
|
||||
return fInvBufferDimensions;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS) || defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxFloat32x2 MotionVectorScale()
|
||||
{
|
||||
return fMotionVectorScale;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxInt32 IsFirstFrame()
|
||||
{
|
||||
return iFirstFrame;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
FfxFloat32x3 Eye()
|
||||
{
|
||||
return fEye;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB1_DENOISER_SHADOWS)
|
||||
|
||||
FfxFloat32 LoadDepth(FfxInt32x2 p)
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_DEPTH)
|
||||
return r_depth.Load(FfxInt32x3(p, 0)).x;
|
||||
#else
|
||||
return 0.f;
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_DEPTH)
|
||||
}
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH)
|
||||
FfxFloat32 LoadPreviousDepth(FfxInt32x2 p)
|
||||
{
|
||||
return r_previous_depth.Load(FfxInt32x3(p, 0)).x;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_DEPTH)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_NORMAL)
|
||||
FfxFloat32x3 LoadNormals(FfxInt32x2 p)
|
||||
{
|
||||
FfxFloat32x3 normal = r_normal.Load(FfxInt32x3(p, 0)).xyz;
|
||||
normal = normal * NormalsUnpackMul().xxx + NormalsUnpackAdd().xxx;
|
||||
return normalize(normal);
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_NORMAL)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_VELOCITY)
|
||||
FfxFloat32x2 LoadVelocity(FfxInt32x2 p)
|
||||
{
|
||||
FfxFloat32x2 velocity = r_velocity.Load(FfxInt32x3(p, 0)).rg;
|
||||
return velocity * MotionVectorScale();
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_VELOCITY)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_HISTORY)
|
||||
FfxFloat32 LoadHistory(FfxFloat32x2 p)
|
||||
{
|
||||
return r_history.SampleLevel(s_trilinerClamp, p, 0).x;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_HISTORY)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS)
|
||||
FfxFloat32x3 LoadPreviousMomentsBuffer(FfxInt32x2 p)
|
||||
{
|
||||
return r_previous_moments.Load(FfxInt32x3(p, 0)).xyz;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_PREVIOUS_MOMENTS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT)
|
||||
FfxUInt32 LoadRaytracedShadowMask(FfxUInt32 p)
|
||||
{
|
||||
return rw_raytracer_result[p];
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_RAYTRACER_RESULT)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
void StoreMetadata(FfxUInt32 p, FfxUInt32 val)
|
||||
{
|
||||
rw_tile_metadata[p] = val;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS)
|
||||
void StoreMoments(FfxUInt32x2 p, FfxFloat32x3 val)
|
||||
{
|
||||
rw_current_moments[p] = val;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_CURRENT_MOMENTS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS)
|
||||
void StoreReprojectionResults(FfxUInt32x2 p, FfxFloat32x2 val)
|
||||
{
|
||||
rw_reprojection_results[p] = val;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_REPROJECTION_RESULTS)
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
FfxFloat32 DepthSimilaritySigma()
|
||||
{
|
||||
return fDepthSimilaritySigma;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_CB2_DENOISER_SHADOWS)
|
||||
|
||||
#if FFX_HALF
|
||||
#if defined(DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT)
|
||||
FfxFloat16x2 LoadFilterInput(FfxUInt32x2 p)
|
||||
{
|
||||
return (FfxFloat16x2)r_filter_input.Load(FfxInt32x3(p, 0)).xy;
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_SRV_FILTER_INPUT)
|
||||
#endif
|
||||
|
||||
FfxBoolean IsShadowReciever(FfxUInt32x2 p)
|
||||
{
|
||||
FfxFloat32 depth = LoadDepth(p);
|
||||
return (depth > 0.0f) && (depth < 1.0f);
|
||||
}
|
||||
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
FfxUInt32 LoadTileMetaData(FfxUInt32 p)
|
||||
{
|
||||
return rw_tile_metadata[p];
|
||||
}
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_TILE_METADATA)
|
||||
|
||||
void StoreHistory(FfxUInt32x2 p, FfxFloat32x2 val)
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_HISTORY)
|
||||
rw_history[p] = val;
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_HISTORY)
|
||||
}
|
||||
|
||||
void StoreFilterOutput(FfxUInt32x2 p, FfxFloat32 val)
|
||||
{
|
||||
#if defined(DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT)
|
||||
rw_filter_output[p].x = val;
|
||||
#endif // #if defined(DENOISER_SHADOWS_BIND_UAV_FILTER_OUTPUT)
|
||||
}
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
331
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_filter.h
vendored
Normal file
331
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_filter.h
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
// 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_DNSR_SHADOWS_FILTER_HLSL
|
||||
#define FFX_DNSR_SHADOWS_FILTER_HLSL
|
||||
|
||||
#include "ffx_denoiser_shadows_util.h"
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 g_FFX_DNSR_Shadows_shared_input[16][16];
|
||||
FFX_GROUPSHARED FfxFloat32 g_FFX_DNSR_Shadows_shared_depth[16][16];
|
||||
FFX_GROUPSHARED FfxUInt32 g_FFX_DNSR_Shadows_shared_normals_xy[16][16];
|
||||
FFX_GROUPSHARED FfxUInt32 g_FFX_DNSR_Shadows_shared_normals_zw[16][16];
|
||||
|
||||
#if FFX_HALF
|
||||
FfxUInt32 FFX_DNSR_Shadows_PackFloat16(FfxFloat16x2 v)
|
||||
{
|
||||
return ffxPackHalf2x16(FfxFloat32x2(v));
|
||||
}
|
||||
|
||||
FfxFloat16x2 FFX_DNSR_Shadows_UnpackFloat16(FfxUInt32 a)
|
||||
{
|
||||
return ffxUnpackF16(a);
|
||||
}
|
||||
|
||||
FfxFloat16x2 FFX_DNSR_Shadows_LoadInputFromGroupSharedMemory(FfxInt32x2 idx)
|
||||
{
|
||||
return FFX_DNSR_Shadows_UnpackFloat16(g_FFX_DNSR_Shadows_shared_input[idx.y][idx.x]);
|
||||
}
|
||||
#endif
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_LoadDepthFromGroupSharedMemory(FfxInt32x2 idx)
|
||||
{
|
||||
return g_FFX_DNSR_Shadows_shared_depth[idx.y][idx.x];
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16x3 FFX_DNSR_Shadows_LoadNormalsFromGroupSharedMemory(FfxInt32x2 idx)
|
||||
{
|
||||
FfxFloat16x3 normals;
|
||||
normals.xy = FFX_DNSR_Shadows_UnpackFloat16(g_FFX_DNSR_Shadows_shared_normals_xy[idx.y][idx.x]);
|
||||
normals.z = FFX_DNSR_Shadows_UnpackFloat16(g_FFX_DNSR_Shadows_shared_normals_zw[idx.y][idx.x]).x;
|
||||
return normals;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_StoreInGroupSharedMemory(FfxInt32x2 idx, FfxFloat16x3 normals, FfxFloat16x2 inp, FfxFloat32 depth)
|
||||
{
|
||||
g_FFX_DNSR_Shadows_shared_input[idx.y][idx.x] = FFX_DNSR_Shadows_PackFloat16(inp);
|
||||
g_FFX_DNSR_Shadows_shared_depth[idx.y][idx.x] = depth;
|
||||
g_FFX_DNSR_Shadows_shared_normals_xy[idx.y][idx.x] = FFX_DNSR_Shadows_PackFloat16(normals.xy);
|
||||
g_FFX_DNSR_Shadows_shared_normals_zw[idx.y][idx.x] = FFX_DNSR_Shadows_PackFloat16(FfxFloat16x2(normals.z, 0));
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_LoadWithOffset(FfxInt32x2 did, FfxInt32x2 offset, out FfxFloat16x3 normals, out FfxFloat16x2 inp, out FfxFloat32 depth)
|
||||
{
|
||||
did += offset;
|
||||
|
||||
const FfxInt32x2 p = clamp(did, FfxInt32x2(0, 0), BufferDimensions() - 1);
|
||||
normals = FfxFloat16x3(LoadNormals(p));
|
||||
inp = LoadFilterInput(p);
|
||||
depth = LoadDepth(p);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_StoreWithOffset(FfxInt32x2 gtid, FfxInt32x2 offset, FfxFloat16x3 normals, FfxFloat16x2 inp, FfxFloat32 depth)
|
||||
{
|
||||
gtid += offset;
|
||||
FFX_DNSR_Shadows_StoreInGroupSharedMemory(gtid, normals, inp, depth);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_InitializeGroupSharedMemory(FfxInt32x2 did, FfxInt32x2 gtid)
|
||||
{
|
||||
FfxInt32x2 offset_0 = FfxInt32x2(0, 0);
|
||||
FfxInt32x2 offset_1 = FfxInt32x2(8, 0);
|
||||
FfxInt32x2 offset_2 = FfxInt32x2(0, 8);
|
||||
FfxInt32x2 offset_3 = FfxInt32x2(8, 8);
|
||||
|
||||
FfxFloat16x3 normals_0;
|
||||
FfxFloat16x2 input_0;
|
||||
FfxFloat32 depth_0;
|
||||
|
||||
FfxFloat16x3 normals_1;
|
||||
FfxFloat16x2 input_1;
|
||||
FfxFloat32 depth_1;
|
||||
|
||||
FfxFloat16x3 normals_2;
|
||||
FfxFloat16x2 input_2;
|
||||
FfxFloat32 depth_2;
|
||||
|
||||
FfxFloat16x3 normals_3;
|
||||
FfxFloat16x2 input_3;
|
||||
FfxFloat32 depth_3;
|
||||
|
||||
/// XA
|
||||
/// BC
|
||||
|
||||
did -= 4;
|
||||
FFX_DNSR_Shadows_LoadWithOffset(did, offset_0, normals_0, input_0, depth_0); // X
|
||||
FFX_DNSR_Shadows_LoadWithOffset(did, offset_1, normals_1, input_1, depth_1); // A
|
||||
FFX_DNSR_Shadows_LoadWithOffset(did, offset_2, normals_2, input_2, depth_2); // B
|
||||
FFX_DNSR_Shadows_LoadWithOffset(did, offset_3, normals_3, input_3, depth_3); // C
|
||||
|
||||
FFX_DNSR_Shadows_StoreWithOffset(gtid, offset_0, normals_0, input_0, depth_0); // X
|
||||
FFX_DNSR_Shadows_StoreWithOffset(gtid, offset_1, normals_1, input_1, depth_1); // A
|
||||
FFX_DNSR_Shadows_StoreWithOffset(gtid, offset_2, normals_2, input_2, depth_2); // B
|
||||
FFX_DNSR_Shadows_StoreWithOffset(gtid, offset_3, normals_3, input_3, depth_3); // C
|
||||
}
|
||||
#else
|
||||
// Not used, defined to make sure f32 path compiles
|
||||
FfxUInt32 FFX_DNSR_Shadows_PackFloat16(FfxFloat32x2 v){return 0;}
|
||||
FfxFloat32x2 FFX_DNSR_Shadows_UnpackFloat16(FfxUInt32 a){return FfxFloat32x2(0,0);}
|
||||
FfxFloat32x2 FFX_DNSR_Shadows_LoadInputFromGroupSharedMemory(FfxInt32x2 idx){return FfxFloat32x2(0,0);}
|
||||
FfxFloat32x3 FFX_DNSR_Shadows_LoadNormalsFromGroupSharedMemory(FfxInt32x2 idx){return FfxFloat32x3(0,0,0);}
|
||||
void FFX_DNSR_Shadows_StoreInGroupSharedMemory(FfxInt32x2 idx, FfxFloat32x3 normals, FfxFloat32x2 inp, FfxFloat32 depth){}
|
||||
void FFX_DNSR_Shadows_LoadWithOffset(FfxInt32x2 did, FfxInt32x2 offset, out FfxFloat32x3 normals, out FfxFloat32x2 inp, out FfxFloat32 depth){depth = 0;}
|
||||
void FFX_DNSR_Shadows_StoreWithOffset(FfxInt32x2 gtid, FfxInt32x2 offset, FfxFloat32x3 normals, FfxFloat32x2 inp, FfxFloat32 depth){}
|
||||
void FFX_DNSR_Shadows_InitializeGroupSharedMemory(FfxInt32x2 did, FfxInt32x2 gtid){}
|
||||
#endif
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_GetShadowSimilarity(FfxFloat32 x1, FfxFloat32 x2, FfxFloat32 sigma)
|
||||
{
|
||||
return exp(-abs(x1 - x2) / sigma);
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_GetDepthSimilarity(FfxFloat32 x1, FfxFloat32 x2, FfxFloat32 sigma)
|
||||
{
|
||||
return exp(-abs(x1 - x2) / sigma);
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_GetNormalSimilarity(FfxFloat32x3 x1, FfxFloat32x3 x2)
|
||||
{
|
||||
return ffxPow(ffxSaturate(dot(x1, x2)), 32.0f);
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_GetLinearDepth(FfxUInt32x2 did, FfxFloat32 depth)
|
||||
{
|
||||
const FfxFloat32x2 uv = (did + 0.5f) * InvBufferDimensions();
|
||||
const FfxFloat32x2 ndc = 2.0f * FfxFloat32x2(uv.x, 1.0f - uv.y) - 1.0f;
|
||||
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(ProjectionInverse(), FfxFloat32x4(ndc, depth, 1));
|
||||
|
||||
return abs(projected.z / projected.w);
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_FetchFilteredVarianceFromGroupSharedMemory(FfxInt32x2 pos)
|
||||
{
|
||||
const FfxInt32 k = 1;
|
||||
FfxFloat32 variance = 0.0f;
|
||||
const FfxFloat32 kernel[2][2] =
|
||||
{
|
||||
{ 1.0f / 4.0f, 1.0f / 8.0f },
|
||||
{ 1.0f / 8.0f, 1.0f / 16.0f }
|
||||
};
|
||||
for (FfxInt32 y = -k; y <= k; ++y)
|
||||
{
|
||||
for (FfxInt32 x = -k; x <= k; ++x)
|
||||
{
|
||||
const FfxFloat32 w = kernel[abs(x)][abs(y)];
|
||||
variance += w * FFX_DNSR_Shadows_LoadInputFromGroupSharedMemory(pos + FfxInt32x2(x, y)).y;
|
||||
}
|
||||
}
|
||||
return variance;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_DenoiseFromGroupSharedMemory(FfxUInt32x2 did, FfxUInt32x2 gtid, inout FfxFloat32 weight_sum, inout FfxFloat32x2 shadow_sum, FfxFloat32 depth, FfxUInt32 stepsize)
|
||||
{
|
||||
// Load our center sample
|
||||
const FfxFloat32x2 shadow_center = FFX_DNSR_Shadows_LoadInputFromGroupSharedMemory(FfxInt32x2(gtid));
|
||||
const FfxFloat32x3 normal_center = FFX_DNSR_Shadows_LoadNormalsFromGroupSharedMemory(FfxInt32x2(gtid));
|
||||
|
||||
weight_sum = 1.0f;
|
||||
shadow_sum = shadow_center;
|
||||
|
||||
const FfxFloat32 variance = FFX_DNSR_Shadows_FetchFilteredVarianceFromGroupSharedMemory(FfxInt32x2(gtid));
|
||||
const FfxFloat32 std_deviation = sqrt(max(variance + 1e-9f, 0.0f));
|
||||
const FfxFloat32 depth_center = FFX_DNSR_Shadows_GetLinearDepth(did, depth); // linearize the depth value
|
||||
|
||||
// Iterate filter kernel
|
||||
const FfxInt32 k = 1;
|
||||
const FfxFloat32 kernel[3] = { 1.0f, 2.0f / 3.0f, 1.0f / 6.0f };
|
||||
|
||||
for (FfxInt32 y = -k; y <= k; ++y)
|
||||
{
|
||||
for (FfxInt32 x = -k; x <= k; ++x)
|
||||
{
|
||||
// Should we process this sample?
|
||||
const FfxInt32x2 step = FfxInt32x2(x, y) * FfxInt32x2(stepsize, stepsize);
|
||||
const FfxInt32x2 gtid_idx = FfxInt32x2(gtid) + step;
|
||||
const FfxInt32x2 did_idx = FfxInt32x2(did) + step;
|
||||
|
||||
FfxFloat32 depth_neigh = FFX_DNSR_Shadows_LoadDepthFromGroupSharedMemory(gtid_idx);
|
||||
FfxFloat32x3 normal_neigh = FFX_DNSR_Shadows_LoadNormalsFromGroupSharedMemory(gtid_idx);
|
||||
FfxFloat32x2 shadow_neigh = FFX_DNSR_Shadows_LoadInputFromGroupSharedMemory(gtid_idx);
|
||||
|
||||
FfxFloat32 sky_pixel_multiplier = ((x == 0 && y == 0) || depth_neigh >= 1.0f || depth_neigh <= 0.0f) ? 0 : 1; // Zero weight for sky pixels
|
||||
|
||||
// Fetch our filtering values
|
||||
depth_neigh = FFX_DNSR_Shadows_GetLinearDepth(did_idx, depth_neigh);
|
||||
|
||||
// Evaluate the edge-stopping function
|
||||
FfxFloat32 w = kernel[abs(x)] * kernel[abs(y)]; // kernel weight
|
||||
w *= FFX_DNSR_Shadows_GetShadowSimilarity(shadow_center.x, shadow_neigh.x, std_deviation);
|
||||
w *= FFX_DNSR_Shadows_GetDepthSimilarity(depth_center, depth_neigh, DepthSimilaritySigma());
|
||||
w *= FFX_DNSR_Shadows_GetNormalSimilarity(normal_center, normal_neigh);
|
||||
w *= sky_pixel_multiplier;
|
||||
|
||||
// Accumulate the filtered sample
|
||||
shadow_sum += FfxFloat32x2(w, w * w) * shadow_neigh;
|
||||
weight_sum += w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Shadows_ApplyFilterWithPrecache(FfxUInt32x2 did, FfxUInt32x2 gtid, FfxUInt32 stepsize)
|
||||
{
|
||||
FfxFloat32 weight_sum = 1.0;
|
||||
FfxFloat32x2 shadow_sum = FfxFloat32x2(0, 0);
|
||||
|
||||
FFX_DNSR_Shadows_InitializeGroupSharedMemory(FfxInt32x2(did), FfxInt32x2(gtid));
|
||||
FfxBoolean needs_denoiser = IsShadowReciever(did);
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
if (needs_denoiser)
|
||||
{
|
||||
FfxFloat32 depth = LoadDepth(FfxInt32x2(did));
|
||||
gtid += 4; // Center threads in groupshared memory
|
||||
FFX_DNSR_Shadows_DenoiseFromGroupSharedMemory(did, gtid, weight_sum, shadow_sum, depth, stepsize);
|
||||
}
|
||||
|
||||
FfxFloat32 mean = shadow_sum.x / weight_sum;
|
||||
FfxFloat32 variance = shadow_sum.y / (weight_sum * weight_sum);
|
||||
return FfxFloat32x2(mean, variance);
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_ReadTileMetaData(FfxUInt32x2 gid, out FfxBoolean is_cleared, out FfxBoolean all_in_light)
|
||||
{
|
||||
FfxUInt32 meta_data = LoadTileMetaData(gid.y * FFX_DNSR_Shadows_RoundedDivide(BufferDimensions().x, 8) + gid.x);
|
||||
is_cleared = FfxBoolean(meta_data & FfxUInt32(TILE_META_DATA_CLEAR_MASK));
|
||||
all_in_light = FfxBoolean(meta_data & FfxUInt32(TILE_META_DATA_LIGHT_MASK));
|
||||
}
|
||||
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Shadows_FilterSoftShadowsPass(FfxUInt32x2 gid, FfxUInt32x2 gtid, FfxUInt32x2 did, out FfxBoolean bWriteResults, const FfxUInt32 pass, const FfxUInt32 stepsize)
|
||||
{
|
||||
FfxBoolean is_cleared;
|
||||
FfxBoolean all_in_light;
|
||||
FFX_DNSR_Shadows_ReadTileMetaData(gid, is_cleared, all_in_light);
|
||||
|
||||
bWriteResults = FFX_FALSE;
|
||||
FfxFloat32x2 results = FfxFloat32x2(0, 0);
|
||||
|
||||
if (is_cleared)
|
||||
{
|
||||
if (pass != 1)
|
||||
{
|
||||
results.x = all_in_light ? 1.0 : 0.0;
|
||||
bWriteResults = FFX_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
results = FFX_DNSR_Shadows_ApplyFilterWithPrecache(did, gtid, stepsize);
|
||||
bWriteResults = FFX_TRUE;
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
void DenoiserShadowsFilterPass0(FfxUInt32x2 gid, FfxUInt32x2 gtid, FfxUInt32x2 did)
|
||||
{
|
||||
const uint PASS_INDEX = 0;
|
||||
const uint STEP_SIZE = 1;
|
||||
|
||||
FfxBoolean bWriteOutput = FFX_FALSE;
|
||||
const FfxFloat32x2 results = FFX_DNSR_Shadows_FilterSoftShadowsPass(gid, gtid, did, bWriteOutput, PASS_INDEX, STEP_SIZE);
|
||||
|
||||
if (bWriteOutput)
|
||||
{
|
||||
StoreHistory(did, results);
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserShadowsFilterPass1(FfxUInt32x2 gid, FfxUInt32x2 gtid, FfxUInt32x2 did)
|
||||
{
|
||||
const uint PASS_INDEX = 1;
|
||||
const uint STEP_SIZE = 2;
|
||||
|
||||
FfxBoolean bWriteOutput = FFX_FALSE;
|
||||
const FfxFloat32x2 results = FFX_DNSR_Shadows_FilterSoftShadowsPass(gid, gtid, did, bWriteOutput, PASS_INDEX, STEP_SIZE);
|
||||
|
||||
if (bWriteOutput)
|
||||
{
|
||||
StoreHistory(did, results);
|
||||
}
|
||||
}
|
||||
|
||||
void DenoiserShadowsFilterPass2(FfxUInt32x2 gid, FfxUInt32x2 gtid, FfxUInt32x2 did)
|
||||
{
|
||||
const uint PASS_INDEX = 2;
|
||||
const uint STEP_SIZE = 4;
|
||||
|
||||
FfxBoolean bWriteOutput = FFX_FALSE;
|
||||
const FfxFloat32x2 results = FFX_DNSR_Shadows_FilterSoftShadowsPass(gid, gtid, did, bWriteOutput, PASS_INDEX, STEP_SIZE);
|
||||
|
||||
// Recover some of the contrast lost during denoising
|
||||
const FfxFloat32 shadow_remap = max(1.2f - results.y, 1.0f);
|
||||
const FfxFloat32 mean = pow(abs(results.x), shadow_remap);
|
||||
|
||||
if (bWriteOutput)
|
||||
{
|
||||
StoreFilterOutput(did, mean);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
53
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_prepare.h
vendored
Normal file
53
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_prepare.h
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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_DNSR_SHADOWS_PREPARESHADOWMASK_HLSL
|
||||
#define FFX_DNSR_SHADOWS_PREPARESHADOWMASK_HLSL
|
||||
|
||||
#include "ffx_denoiser_shadows_util.h"
|
||||
|
||||
void FFX_DNSR_Shadows_CopyResult(FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
const FfxUInt32x2 did = gid * FfxUInt32x2(8, 4) + gtid;
|
||||
const FfxUInt32 linear_tile_index = FFX_DNSR_Shadows_LinearTileIndex(gid, BufferDimensions().x);
|
||||
const FfxBoolean hit_light = HitsLight(did, gtid, gid);
|
||||
const FfxUInt32 lane_mask = hit_light ? FFX_DNSR_Shadows_GetBitMaskFromPixelPosition(did) : 0;
|
||||
StoreShadowMask(linear_tile_index, ffxWaveOr(lane_mask));
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_PrepareShadowMask(FfxUInt32x2 gtid, FfxUInt32x2 gid)
|
||||
{
|
||||
gid *= 4;
|
||||
FfxUInt32x2 tile_dimensions = (BufferDimensions() + FfxUInt32x2(7, 3)) / FfxUInt32x2(8, 4);
|
||||
|
||||
for (FfxInt32 i = 0; i < 4; ++i)
|
||||
{
|
||||
for (FfxInt32 j = 0; j < 4; ++j)
|
||||
{
|
||||
FfxUInt32x2 tile_id = FfxUInt32x2(gid.x + i, gid.y + j);
|
||||
tile_id = clamp(tile_id, FfxUInt32x2(0, 0), tile_dimensions - FfxUInt32x2(1,1));
|
||||
FFX_DNSR_Shadows_CopyResult(gtid, tile_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
430
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_tileclassification.h
vendored
Normal file
430
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_tileclassification.h
vendored
Normal file
@@ -0,0 +1,430 @@
|
||||
// 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_DNSR_SHADOWS_TILECLASSIFICATION_HLSL
|
||||
#define FFX_DNSR_SHADOWS_TILECLASSIFICATION_HLSL
|
||||
|
||||
#include "ffx_denoiser_shadows_util.h"
|
||||
|
||||
FFX_GROUPSHARED FfxInt32 g_FFX_DNSR_Shadows_false_count;
|
||||
FfxBoolean FFX_DNSR_Shadows_ThreadGroupAllTrue(FfxBoolean val)
|
||||
{
|
||||
const FfxUInt32 lane_count_in_thread_group = 64;
|
||||
if (ffxWaveLaneCount() == lane_count_in_thread_group)
|
||||
{
|
||||
return ffxWaveAllTrue(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
g_FFX_DNSR_Shadows_false_count = 0;
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
if (!val) g_FFX_DNSR_Shadows_false_count = 1;
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
return g_FFX_DNSR_Shadows_false_count == 0;
|
||||
}
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_SearchSpatialRegion(FfxUInt32x2 gid, out FfxBoolean all_in_light, out FfxBoolean all_in_shadow)
|
||||
{
|
||||
// The spatial passes can reach a total region of 1+2+4 = 7x7 around each block.
|
||||
// The masks are 8x4, so we need a larger vertical stride
|
||||
|
||||
// Visualization - each x represents a 4x4 block, xx is one entire 8x4 mask as read from the raytracer result
|
||||
// Same for yy, these are the ones we are working on right now
|
||||
|
||||
// xx xx xx
|
||||
// xx xx xx
|
||||
// xx yy xx <-- yy here is the base_tile below
|
||||
// xx yy xx
|
||||
// xx xx xx
|
||||
// xx xx xx
|
||||
|
||||
// All of this should result in scalar ops
|
||||
FfxUInt32x2 base_tile = FFX_DNSR_Shadows_GetTileIndexFromPixelPosition(gid * FfxInt32x2(8, 8));
|
||||
|
||||
// Load the entire region of masks in a scalar fashion
|
||||
FfxUInt32 combined_or_mask = 0;
|
||||
FfxUInt32 combined_and_mask = 0xFFFFFFFF;
|
||||
for (FfxInt32 j = -2; j <= 3; ++j)
|
||||
{
|
||||
for (FfxInt32 i = -1; i <= 1; ++i)
|
||||
{
|
||||
FfxInt32x2 tile_index = FfxInt32x2(base_tile) + FfxInt32x2(i, j);
|
||||
tile_index = clamp(tile_index, FfxInt32x2(0,0), FfxInt32x2(FFX_DNSR_Shadows_RoundedDivide(BufferDimensions().x, 8), FFX_DNSR_Shadows_RoundedDivide(BufferDimensions().y, 4)) - 1);
|
||||
const FfxUInt32 linear_tile_index = FFX_DNSR_Shadows_LinearTileIndex(tile_index, BufferDimensions().x);
|
||||
const FfxUInt32 shadow_mask = LoadRaytracedShadowMask(linear_tile_index);
|
||||
|
||||
combined_or_mask = combined_or_mask | shadow_mask;
|
||||
combined_and_mask = combined_and_mask & shadow_mask;
|
||||
}
|
||||
}
|
||||
|
||||
all_in_light = combined_and_mask == 0xFFFFFFFFu;
|
||||
all_in_shadow = combined_or_mask == 0u;
|
||||
}
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_GetLinearDepth(FfxUInt32x2 did, FfxFloat32 depth)
|
||||
{
|
||||
const FfxFloat32x2 uv = (did + 0.5f) * InvBufferDimensions();
|
||||
const FfxFloat32x2 ndc = 2.0f * FfxFloat32x2(uv.x, 1.0f - uv.y) - 1.0f;
|
||||
|
||||
FfxFloat32x4 projected = FFX_MATRIX_MULTIPLY(ProjectionInverse(), FfxFloat32x4(ndc, depth, 1));
|
||||
|
||||
return abs(projected.z / projected.w);
|
||||
}
|
||||
|
||||
FfxBoolean FFX_DNSR_Shadows_IsDisoccluded(FfxUInt32x2 did, FfxFloat32 depth, FfxFloat32x2 velocity)
|
||||
{
|
||||
const FfxInt32x2 dims = BufferDimensions();
|
||||
const FfxFloat32x2 texel_size = InvBufferDimensions();
|
||||
const FfxFloat32x2 uv = (did + 0.5f) * texel_size;
|
||||
const FfxFloat32x2 ndc = (2.0f * uv - 1.0f) * FfxFloat32x2(1.0f, -1.0f);
|
||||
const FfxFloat32x2 previous_uv = uv + velocity;
|
||||
|
||||
FfxBoolean is_disoccluded = FFX_TRUE;
|
||||
|
||||
if (all(FFX_GREATER_THAN(previous_uv, FfxFloat32x2(0,0))) && all(FFX_LESS_THAN(previous_uv, FfxFloat32x2(1,1))))
|
||||
{
|
||||
// Read the center values
|
||||
FfxFloat32x3 normal = LoadNormals(did);
|
||||
|
||||
FfxFloat32x4 clip_space = FFX_MATRIX_MULTIPLY(ReprojectionMatrix(), FfxFloat32x4(ndc, depth, 1.0f));
|
||||
|
||||
clip_space.z /= clip_space.w; // perspective divide
|
||||
|
||||
// How aligned with the view vector? (the more Z aligned, the higher the depth errors)
|
||||
const FfxFloat32x4 homogeneous = FFX_MATRIX_MULTIPLY(ViewProjectionInverse(), FfxFloat32x4(ndc, depth, 1.0f));
|
||||
const FfxFloat32x3 world_position = FfxFloat32x3(homogeneous.xyz / homogeneous.w); // perspective divide
|
||||
const FfxFloat32x3 view_direction = normalize(Eye().xyz - world_position);
|
||||
FfxFloat32 z_alignment = 1.0f - dot(view_direction, normal);
|
||||
z_alignment = pow(z_alignment, 8);
|
||||
|
||||
// Calculate the depth difference
|
||||
FfxFloat32 linear_depth = FFX_DNSR_Shadows_GetLinearDepth(did, clip_space.z); // get linear depth
|
||||
|
||||
FfxInt32x2 idx = FfxInt32x2(previous_uv * FfxFloat32x2(dims));
|
||||
const FfxFloat32 previous_depth = FFX_DNSR_Shadows_GetLinearDepth(idx, LoadPreviousDepth(idx));
|
||||
const FfxFloat32 depth_difference = abs(previous_depth - linear_depth) / linear_depth;
|
||||
|
||||
// Resolve into the disocclusion mask
|
||||
const FfxFloat32 depth_tolerance = ffxLerp(1e-2f, 1e-1f, z_alignment);
|
||||
is_disoccluded = depth_difference >= depth_tolerance;
|
||||
}
|
||||
|
||||
return is_disoccluded;
|
||||
}
|
||||
|
||||
FfxFloat32x2 FFX_DNSR_Shadows_GetClosestVelocity(FfxInt32x2 did, FfxFloat32 depth)
|
||||
{
|
||||
FfxFloat32x2 closest_velocity = LoadVelocity(did);
|
||||
FfxFloat32 closest_depth = depth;
|
||||
|
||||
FfxFloat32 new_depth = ffxQuadReadX(closest_depth);
|
||||
FfxFloat32x2 new_velocity = ffxQuadReadX(closest_velocity);
|
||||
|
||||
#if FFX_DENOISER_OPTION_INVERTED_DEPTH
|
||||
if (new_depth > closest_depth)
|
||||
#else
|
||||
if (new_depth < closest_depth)
|
||||
#endif
|
||||
{
|
||||
closest_depth = new_depth;
|
||||
closest_velocity = new_velocity;
|
||||
}
|
||||
|
||||
new_depth = ffxQuadReadY(closest_depth);
|
||||
new_velocity = ffxQuadReadY(closest_velocity);
|
||||
|
||||
#if FFX_DENOISER_OPTION_INVERTED_DEPTH
|
||||
if (new_depth > closest_depth)
|
||||
#else
|
||||
if (new_depth < closest_depth)
|
||||
#endif
|
||||
{
|
||||
closest_depth = new_depth;
|
||||
closest_velocity = new_velocity;
|
||||
}
|
||||
|
||||
return closest_velocity;
|
||||
}
|
||||
|
||||
#define KERNEL_RADIUS 8
|
||||
FfxFloat32 FFX_DNSR_Shadows_KernelWeight(FfxFloat32 i)
|
||||
{
|
||||
#define KERNEL_WEIGHT(i) (exp(-3.0 * FfxFloat32(i * i) / ((KERNEL_RADIUS + 1.0) * (KERNEL_RADIUS + 1.0))))
|
||||
|
||||
// Statically initialize kernel_weights_sum
|
||||
FfxFloat32 kernel_weights_sum = 0;
|
||||
kernel_weights_sum += KERNEL_WEIGHT(0);
|
||||
for (FfxInt32 c = 1; c <= KERNEL_RADIUS; ++c)
|
||||
{
|
||||
kernel_weights_sum += 2 * KERNEL_WEIGHT(c); // Add other half of the kernel to the sum
|
||||
}
|
||||
FfxFloat32 inv_kernel_weights_sum = ffxReciprocal(kernel_weights_sum);
|
||||
|
||||
// The only runtime code in this function
|
||||
return KERNEL_WEIGHT(i) * inv_kernel_weights_sum;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_AccumulateMoments(FfxFloat32 value, FfxFloat32 weight, inout FfxFloat32 moments)
|
||||
{
|
||||
// We get value from the horizontal neighborhood calculations. Thus, it's both mean and variance due to using one sample per pixel
|
||||
moments += value * weight;
|
||||
}
|
||||
|
||||
// The horizontal part of a 17x17 local neighborhood kernel
|
||||
FfxFloat32 FFX_DNSR_Shadows_HorizontalNeighborhood(FfxInt32x2 did)
|
||||
{
|
||||
const FfxInt32x2 base_did = did;
|
||||
|
||||
// Prevent vertical out of bounds access
|
||||
if ((base_did.y < 0) || (base_did.y >= BufferDimensions().y)) return 0;
|
||||
|
||||
const FfxUInt32x2 tile_index = FFX_DNSR_Shadows_GetTileIndexFromPixelPosition(base_did);
|
||||
const FfxUInt32 linear_tile_index = FFX_DNSR_Shadows_LinearTileIndex(tile_index, BufferDimensions().x);
|
||||
|
||||
const FfxUInt32 left_tile_index = linear_tile_index - 1;
|
||||
const FfxUInt32 center_tile_index = linear_tile_index;
|
||||
const FfxUInt32 right_tile_index = linear_tile_index + 1;
|
||||
|
||||
FfxBoolean is_first_tile_in_row = tile_index.x == 0;
|
||||
FfxBoolean is_last_tile_in_row = tile_index.x == (FFX_DNSR_Shadows_RoundedDivide(BufferDimensions().x, 8) - 1);
|
||||
|
||||
FfxUInt32 left_tile = 0;
|
||||
if (!is_first_tile_in_row) left_tile = LoadRaytracedShadowMask(left_tile_index);
|
||||
FfxUInt32 center_tile = LoadRaytracedShadowMask(center_tile_index);
|
||||
FfxUInt32 right_tile = 0;
|
||||
if (!is_last_tile_in_row) right_tile = LoadRaytracedShadowMask(right_tile_index);
|
||||
|
||||
// Construct a single FfxUInt32 with the lowest 17bits containing the horizontal part of the local neighborhood.
|
||||
|
||||
// First extract the 8 bits of our row in each of the neighboring tiles
|
||||
const FfxUInt32 row_base_index = (did.y % 4) * 8;
|
||||
const FfxUInt32 left = (left_tile >> row_base_index) & 0xFF;
|
||||
const FfxUInt32 center = (center_tile >> row_base_index) & 0xFF;
|
||||
const FfxUInt32 right = (right_tile >> row_base_index) & 0xFF;
|
||||
|
||||
// Combine them into a single mask containting [left, center, right] from least significant to most significant bit
|
||||
FfxUInt32 neighborhood = left | (center << 8) | (right << 16);
|
||||
|
||||
// Make sure our pixel is at bit position 9 to get the highest contribution from the filter kernel
|
||||
const FfxUInt32 bit_index_in_row = (did.x % 8);
|
||||
neighborhood = neighborhood >> bit_index_in_row; // Shift out bits to the right, so the center bit ends up at bit 9.
|
||||
|
||||
FfxFloat32 moment = 0.0; // For one sample per pixel this is both, mean and variance
|
||||
|
||||
// First 8 bits up to the center pixel
|
||||
FfxUInt32 mask;
|
||||
FfxInt32 i;
|
||||
for (i = 0; i < 8; ++i)
|
||||
{
|
||||
mask = 1u << i;
|
||||
moment += FfxBoolean(mask & neighborhood) ? FFX_DNSR_Shadows_KernelWeight(8 - i) : 0;
|
||||
}
|
||||
|
||||
// Center pixel
|
||||
mask = 1u << 8;
|
||||
moment += FfxBoolean(mask & neighborhood) ? FFX_DNSR_Shadows_KernelWeight(0) : 0;
|
||||
|
||||
// Last 8 bits
|
||||
for (i = 1; i <= 8; ++i)
|
||||
{
|
||||
mask = 1u << (8 + i);
|
||||
moment += FfxBoolean(mask & neighborhood) ? FFX_DNSR_Shadows_KernelWeight(i) : 0;
|
||||
}
|
||||
|
||||
return moment;
|
||||
}
|
||||
|
||||
FFX_GROUPSHARED FfxFloat32 g_FFX_DNSR_Shadows_neighborhood[8][24];
|
||||
|
||||
FfxFloat32 FFX_DNSR_Shadows_ComputeLocalNeighborhood(FfxInt32x2 did, FfxInt32x2 gtid)
|
||||
{
|
||||
FfxFloat32 local_neighborhood = 0;
|
||||
|
||||
FfxFloat32 upper = FFX_DNSR_Shadows_HorizontalNeighborhood(FfxInt32x2(did.x, did.y - 8));
|
||||
FfxFloat32 center = FFX_DNSR_Shadows_HorizontalNeighborhood(FfxInt32x2(did.x, did.y));
|
||||
FfxFloat32 lower = FFX_DNSR_Shadows_HorizontalNeighborhood(FfxInt32x2(did.x, did.y + 8));
|
||||
|
||||
g_FFX_DNSR_Shadows_neighborhood[gtid.x][gtid.y] = upper;
|
||||
g_FFX_DNSR_Shadows_neighborhood[gtid.x][gtid.y + 8] = center;
|
||||
g_FFX_DNSR_Shadows_neighborhood[gtid.x][gtid.y + 16] = lower;
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// First combine the own values.
|
||||
// KERNEL_RADIUS pixels up is own upper and KERNEL_RADIUS pixels down is own lower value
|
||||
FFX_DNSR_Shadows_AccumulateMoments(center, FFX_DNSR_Shadows_KernelWeight(0), local_neighborhood);
|
||||
FFX_DNSR_Shadows_AccumulateMoments(upper, FFX_DNSR_Shadows_KernelWeight(KERNEL_RADIUS), local_neighborhood);
|
||||
FFX_DNSR_Shadows_AccumulateMoments(lower, FFX_DNSR_Shadows_KernelWeight(KERNEL_RADIUS), local_neighborhood);
|
||||
|
||||
// Then read the neighboring values.
|
||||
for (FfxInt32 i = 1; i < KERNEL_RADIUS; ++i)
|
||||
{
|
||||
FfxFloat32 upper_value = g_FFX_DNSR_Shadows_neighborhood[gtid.x][8 + gtid.y - i];
|
||||
FfxFloat32 lower_value = g_FFX_DNSR_Shadows_neighborhood[gtid.x][8 + gtid.y + i];
|
||||
FfxFloat32 weight = FFX_DNSR_Shadows_KernelWeight(i);
|
||||
FFX_DNSR_Shadows_AccumulateMoments(upper_value, weight, local_neighborhood);
|
||||
FFX_DNSR_Shadows_AccumulateMoments(lower_value, weight, local_neighborhood);
|
||||
}
|
||||
|
||||
return local_neighborhood;
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_WriteTileMetaData(FfxUInt32x2 gid, FfxUInt32x2 gtid, FfxBoolean is_cleared, FfxBoolean all_in_light)
|
||||
{
|
||||
if (all(FFX_EQUAL(gtid, FfxUInt32x2(0,0))))
|
||||
{
|
||||
FfxUInt32 light_mask = all_in_light ? TILE_META_DATA_LIGHT_MASK : 0;
|
||||
FfxUInt32 clear_mask = is_cleared ? TILE_META_DATA_CLEAR_MASK : 0;
|
||||
FfxUInt32 mask = FfxUInt32(light_mask | clear_mask);
|
||||
StoreMetadata(gid.y * FFX_DNSR_Shadows_RoundedDivide(BufferDimensions().x, 8) + gid.x, mask);
|
||||
}
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_ClearTargets(FfxUInt32x2 did, FfxUInt32x2 gtid, FfxUInt32x2 gid, FfxFloat32 shadow_value, FfxBoolean is_shadow_receiver, FfxBoolean all_in_light)
|
||||
{
|
||||
FFX_DNSR_Shadows_WriteTileMetaData(gid, gtid, FFX_TRUE, all_in_light);
|
||||
StoreReprojectionResults(did, FfxFloat32x2(shadow_value, 0)); // mean, variance
|
||||
|
||||
FfxFloat32 temporal_sample_count = is_shadow_receiver ? 1 : 0;
|
||||
StoreMoments(did, FfxFloat32x3(shadow_value, 0, temporal_sample_count));// mean, variance, temporal sample count
|
||||
}
|
||||
|
||||
void FFX_DNSR_Shadows_TileClassification(FfxUInt32 group_index, FfxUInt32x2 gid)
|
||||
{
|
||||
FfxUInt32x2 gtid = ffxRemapForWaveReduction(group_index); // Make sure we can use the QuadReadAcross intrinsics to access a 2x2 region.
|
||||
FfxUInt32x2 did = gid * 8 + gtid;
|
||||
|
||||
FfxBoolean is_shadow_receiver = IsShadowReciever(did);
|
||||
|
||||
FfxBoolean skip_sky = FFX_DNSR_Shadows_ThreadGroupAllTrue(!is_shadow_receiver);
|
||||
if (skip_sky)
|
||||
{
|
||||
// We have to set all resources of the tile we skipped to sensible values as neighboring active denoiser tiles might want to read them.
|
||||
FFX_DNSR_Shadows_ClearTargets(did, gtid, gid, 0, is_shadow_receiver, FFX_FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
FfxBoolean all_in_light = FFX_FALSE;
|
||||
FfxBoolean all_in_shadow = FFX_FALSE;
|
||||
FFX_DNSR_Shadows_SearchSpatialRegion(gid, all_in_light, all_in_shadow);
|
||||
FfxFloat32 shadow_value = all_in_light ? 1 : 0; // Either all_in_light or all_in_shadow must be true, otherwise we would not skip the tile.
|
||||
|
||||
FfxBoolean can_skip = all_in_light || all_in_shadow;
|
||||
// We have to append the entire tile if there is a single lane that we can't skip
|
||||
FfxBoolean skip_tile = FFX_DNSR_Shadows_ThreadGroupAllTrue(can_skip);
|
||||
if (skip_tile)
|
||||
{
|
||||
// We have to set all resources of the tile we skipped to sensible values as neighboring active denoiser tiles might want to read them.
|
||||
FFX_DNSR_Shadows_ClearTargets(did, gtid, gid, shadow_value, is_shadow_receiver, all_in_light);
|
||||
return;
|
||||
}
|
||||
|
||||
FFX_DNSR_Shadows_WriteTileMetaData(gid, gtid, FFX_FALSE, FFX_FALSE);
|
||||
|
||||
FfxFloat32 depth = LoadDepth(FfxInt32x2(did));
|
||||
const FfxFloat32x2 velocity = FFX_DNSR_Shadows_GetClosestVelocity(FfxInt32x2(did), depth); // Must happen before we deactivate lanes
|
||||
const FfxFloat32 local_neighborhood = FFX_DNSR_Shadows_ComputeLocalNeighborhood(FfxInt32x2(did), FfxInt32x2(gtid));
|
||||
|
||||
const FfxFloat32x2 texel_size = InvBufferDimensions();
|
||||
const FfxFloat32x2 uv = (did.xy + 0.5f) * texel_size;
|
||||
const FfxFloat32x2 history_uv = uv + velocity;
|
||||
const FfxInt32x2 history_pos = FfxInt32x2(history_uv * BufferDimensions());
|
||||
|
||||
const FfxUInt32x2 tile_index = FFX_DNSR_Shadows_GetTileIndexFromPixelPosition(FfxInt32x2(did));
|
||||
const FfxUInt32 linear_tile_index = FFX_DNSR_Shadows_LinearTileIndex(tile_index, BufferDimensions().x);
|
||||
|
||||
const FfxUInt32 shadow_tile = LoadRaytracedShadowMask(linear_tile_index);
|
||||
|
||||
FfxFloat32x3 moments_current = FfxFloat32x3(0,0,0);
|
||||
FfxFloat32 variance = 0;
|
||||
FfxFloat32 shadow_clamped = 0;
|
||||
if (is_shadow_receiver) // do not process sky pixels
|
||||
{
|
||||
FfxBoolean hit_light = FfxBoolean(shadow_tile & FFX_DNSR_Shadows_GetBitMaskFromPixelPosition(did));
|
||||
const FfxFloat32 shadow_current = hit_light ? 1.0 : 0.0;
|
||||
|
||||
// Perform moments and variance calculations
|
||||
{
|
||||
FfxBoolean is_disoccluded = FFX_DNSR_Shadows_IsDisoccluded(did, depth, velocity);
|
||||
const FfxFloat32x3 previous_moments = is_disoccluded ? FfxFloat32x3(0.0f, 0.0f, 0.0f) // Can't trust previous moments on disocclusion
|
||||
: LoadPreviousMomentsBuffer(history_pos);
|
||||
|
||||
const FfxFloat32 old_m = previous_moments.x;
|
||||
const FfxFloat32 old_s = previous_moments.y;
|
||||
const FfxFloat32 sample_count = previous_moments.z + 1.0f;
|
||||
const FfxFloat32 new_m = old_m + (shadow_current - old_m) / sample_count;
|
||||
const FfxFloat32 new_s = old_s + (shadow_current - old_m) * (shadow_current - new_m);
|
||||
|
||||
variance = (sample_count > 1.0f ? new_s / (sample_count - 1.0f) : 1.0f);
|
||||
moments_current = FfxFloat32x3(new_m, new_s, sample_count);
|
||||
}
|
||||
|
||||
// Retrieve local neighborhood and reproject
|
||||
{
|
||||
FfxFloat32 mean = local_neighborhood;
|
||||
FfxFloat32 spatial_variance = local_neighborhood;
|
||||
|
||||
spatial_variance = max(spatial_variance - mean * mean, 0.0f);
|
||||
|
||||
// Compute the clamping bounding box
|
||||
const FfxFloat32 std_deviation = sqrt(spatial_variance);
|
||||
const FfxFloat32 nmin = mean - 0.5f * std_deviation;
|
||||
const FfxFloat32 nmax = mean + 0.5f * std_deviation;
|
||||
|
||||
// Clamp reprojected sample to local neighborhood
|
||||
FfxFloat32 shadow_previous = shadow_current;
|
||||
if (IsFirstFrame() == 0)
|
||||
{
|
||||
shadow_previous = LoadHistory(history_uv);
|
||||
}
|
||||
|
||||
shadow_clamped = clamp(shadow_previous, nmin, nmax);
|
||||
|
||||
// Reduce history weighting
|
||||
const FfxFloat32 sigma = 20.0f;
|
||||
const FfxFloat32 temporal_discontinuity = (shadow_previous - mean) / max(0.5f * std_deviation, 0.001f);
|
||||
const FfxFloat32 sample_counter_damper = exp(-temporal_discontinuity * temporal_discontinuity / sigma);
|
||||
moments_current.z *= sample_counter_damper;
|
||||
|
||||
// Boost variance on first frames
|
||||
if (moments_current.z < 16.0f)
|
||||
{
|
||||
const FfxFloat32 variance_boost = max(16.0f - moments_current.z, 1.0f);
|
||||
variance = max(variance, spatial_variance);
|
||||
variance *= variance_boost;
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the temporal blend
|
||||
const FfxFloat32 history_weight = sqrt(max(8.0f - moments_current.z, 0.0f) / 8.0f);
|
||||
shadow_clamped = ffxLerp(shadow_clamped, shadow_current, ffxLerp(0.05f, 1.0f, history_weight));
|
||||
}
|
||||
|
||||
// Output the results of the temporal pass
|
||||
StoreReprojectionResults(did.xy, FfxFloat32x2(shadow_clamped, variance));
|
||||
StoreMoments(did.xy, moments_current);
|
||||
}
|
||||
|
||||
#endif
|
||||
50
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_util.h
vendored
Normal file
50
manul/thirdparty/fsr2/include/FidelityFX/gpu/denoiser/ffx_denoiser_shadows_util.h
vendored
Normal file
@@ -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_DNSR_SHADOWS_UTILS_HLSL
|
||||
#define FFX_DNSR_SHADOWS_UTILS_HLSL
|
||||
|
||||
FfxUInt32 FFX_DNSR_Shadows_RoundedDivide(FfxUInt32 value, FfxUInt32 divisor)
|
||||
{
|
||||
return (value + divisor - 1) / divisor;
|
||||
}
|
||||
|
||||
FfxUInt32x2 FFX_DNSR_Shadows_GetTileIndexFromPixelPosition(FfxUInt32x2 pixel_pos)
|
||||
{
|
||||
return FfxUInt32x2(pixel_pos.x / 8, pixel_pos.y / 4);
|
||||
}
|
||||
|
||||
FfxUInt32 FFX_DNSR_Shadows_LinearTileIndex(FfxUInt32x2 tile_index, FfxUInt32 screen_width)
|
||||
{
|
||||
return tile_index.y * FFX_DNSR_Shadows_RoundedDivide(screen_width, 8) + tile_index.x;
|
||||
}
|
||||
|
||||
FfxUInt32 FFX_DNSR_Shadows_GetBitMaskFromPixelPosition(FfxUInt32x2 pixel_pos)
|
||||
{
|
||||
FfxUInt32 lane_index = (pixel_pos.y % 4) * 8 + (pixel_pos.x % 8);
|
||||
return (1u << lane_index);
|
||||
}
|
||||
|
||||
#define TILE_META_DATA_CLEAR_MASK 1
|
||||
#define TILE_META_DATA_LIGHT_MASK 2
|
||||
|
||||
#endif
|
||||
51
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/CMakeCompileDOFShaders.txt
vendored
Normal file
51
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/CMakeCompileDOFShaders.txt
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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(DOF_BASE_ARGS
|
||||
-reflection -deps=gcc -DFFX_GPU=1)
|
||||
|
||||
set(DOF_PERMUTATION_ARGS
|
||||
-DFFX_DOF_OPTION_MAX_RING_MERGE_LOG={0,1}
|
||||
-DFFX_DOF_OPTION_COMBINE_IN_PLACE={0,1}
|
||||
-DFFX_DOF_OPTION_REVERSE_DEPTH={0,1})
|
||||
|
||||
set(DOF_INCLUDE_ARGS
|
||||
"${FFX_GPU_PATH}"
|
||||
"${FFX_GPU_PATH}/dof")
|
||||
|
||||
if (NOT DOF_SHADER_EXT)
|
||||
set(DOF_SHADER_EXT *)
|
||||
endif()
|
||||
|
||||
file(GLOB DOF_SHADERS
|
||||
"shaders/dof/ffx_dof_downsample_depth_pass.${DOF_SHADER_EXT}"
|
||||
"shaders/dof/ffx_dof_downsample_color_pass.${DOF_SHADER_EXT}"
|
||||
"shaders/dof/ffx_dof_dilate_pass.${DOF_SHADER_EXT}"
|
||||
"shaders/dof/ffx_dof_blur_pass.${DOF_SHADER_EXT}"
|
||||
"shaders/dof/ffx_dof_composite_pass.${DOF_SHADER_EXT}")
|
||||
|
||||
compile_shaders_with_depfile(
|
||||
"${FFX_SC_EXECUTABLE}"
|
||||
"${DOF_BASE_ARGS}" "${DOF_API_BASE_ARGS}" "${DOF_PERMUTATION_ARGS}" "${DOF_INCLUDE_ARGS}"
|
||||
"${DOF_SHADERS}" "${FFX_PASS_SHADER_OUTPUT_PATH}" DOF_PERMUTATION_OUTPUTS)
|
||||
|
||||
add_shader_output("${DOF_PERMUTATION_OUTPUTS}")
|
||||
714
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_blur.h
vendored
Normal file
714
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_blur.h
vendored
Normal file
@@ -0,0 +1,714 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_dof_common.h"
|
||||
|
||||
// Factor applied to a distance value before checking that it is in range of the blur kernel.
|
||||
FFX_STATIC const FfxFloat32 FFX_DOF_RANGE_TOLERANCE_FACTOR = 0.98;
|
||||
|
||||
// Accumulators for one ring. Used for ring occlusion.
|
||||
struct FfxDofBucket
|
||||
{
|
||||
FfxFloat32x4 color; // rgb=color sum, a=weight sum
|
||||
FfxFloat32 ringCovg; // radius of the ring coverage (average of tileCoc/coc with some clamping)
|
||||
FfxFloat32 radius; // radius of the ring center
|
||||
FfxUInt32 sampleCount; // number of samples counted
|
||||
};
|
||||
|
||||
// One sample of the input and related variables
|
||||
struct FfxDofSample
|
||||
{
|
||||
FfxFloat32 coc; // signed circle of confusion in pixels. negative values are far-field.
|
||||
FfxFloat32x3 color; // color value of the sample
|
||||
};
|
||||
|
||||
// Helper struct to contain all input variables
|
||||
struct FfxDofInputState
|
||||
{
|
||||
FfxUInt32x2 imageSize; // input pixel size (half res)
|
||||
FfxFloat32x2 pxCoord; // pixel coordinates of the kernel center
|
||||
FfxFloat32 tileCoc; // coc value bilinearly interpolated from the tile map
|
||||
FfxFloat32 centerCoc; // signed coc value at the kernel center
|
||||
FfxFloat32 ringGap; // undersampling factor. ringGap * nRings = tileCoc.
|
||||
FfxUInt32 mipLevel; // mip level to use based on coc and MAX_RINGS
|
||||
FfxBoolean nearField; // whether the center pixel is in the near field
|
||||
FfxUInt32 nSamples, // number of actual samples taken
|
||||
nRings; // number of rings to sample (<= MAX_RINGS)
|
||||
FfxFloat32 covgFactor, covgBias; // coverage parameters
|
||||
};
|
||||
|
||||
// Helper struct to contain accumulation variables
|
||||
struct FfxDofAccumulators
|
||||
{
|
||||
FfxDofBucket prevBucket, currBucket;
|
||||
FfxFloat32x4 ringColor;
|
||||
FfxFloat32 ringCovg;
|
||||
FfxFloat32x4 nearColor, fillColor;
|
||||
};
|
||||
|
||||
// Merges currBucket into prevBucket. Opacity is ratio of hit/total samples in current ring.
|
||||
void FfxDofMergeBuckets(inout FfxDofAccumulators acc, FfxFloat32 opacity)
|
||||
{
|
||||
// averaging
|
||||
FfxFloat32 prevRC = ffxSaturate(acc.prevBucket.ringCovg / acc.prevBucket.sampleCount);
|
||||
FfxFloat32 currRC = ffxSaturate(acc.currBucket.ringCovg / acc.currBucket.sampleCount);
|
||||
|
||||
// occlusion term is calculated as the ratio of the area of intersection of both buckets
|
||||
// (being viewed as rings with a radius (centered on the samples) and ring width (=avg coverage))
|
||||
// divided by the area of the previous bucket ring.
|
||||
FfxFloat32 prevOuter = ffxSaturate(acc.prevBucket.radius + prevRC);
|
||||
FfxFloat32 prevInner = (acc.prevBucket.radius - prevRC);
|
||||
FfxFloat32 currOuter = ffxSaturate(acc.currBucket.radius + currRC);
|
||||
FfxFloat32 currInner = (acc.currBucket.radius - currRC);
|
||||
// intersection is between min(outer) and max(inner)
|
||||
FfxFloat32 insOuter = min(prevOuter, currOuter);
|
||||
FfxFloat32 insInner = max(prevInner, currInner);
|
||||
// intersection area formula.
|
||||
// ffxSaturate here fixes edge case where prev area = 0 -> ffxSaturate(0/0)=ffxSaturate(nan) = 0
|
||||
// The value does not matter in that case, since the previous values will be all zero, but it must be finite.
|
||||
FfxFloat32 occlusion = insOuter < insInner ? 0 : ffxSaturate((insOuter * insOuter - sign(insInner) * insInner * insInner) / (prevOuter * prevOuter - sign(prevInner) * prevInner * prevInner));
|
||||
|
||||
FfxFloat32 factor = 1 - opacity * occlusion;
|
||||
acc.prevBucket.color = acc.prevBucket.color * factor + acc.currBucket.color;
|
||||
// select new radius so that (roughly) covers both rings, so in the middle of the combined ring
|
||||
FfxFloat32 newRadius = 0.5 * (max(prevOuter, currOuter) + min(prevInner, currInner));
|
||||
// the new coverage should then be the difference between the radius and either bound
|
||||
FfxFloat32 newCovg = 0.5 * (max(prevOuter, currOuter) - min(prevInner, currInner));
|
||||
acc.prevBucket.sampleCount = FfxUInt32(acc.prevBucket.sampleCount * factor) + acc.currBucket.sampleCount;
|
||||
acc.prevBucket.ringCovg = acc.prevBucket.sampleCount * newCovg;
|
||||
acc.prevBucket.radius = newRadius;
|
||||
}
|
||||
|
||||
FfxFloat32 FfxDofWeight(FfxDofInputState ins, FfxFloat32 coc)
|
||||
{
|
||||
// Weight is inverse coc area (1 / pi*r^2). Use pi~=4 for perf reasons.
|
||||
// Saturate to avoid explosion of weight close to zero. If coc < 0.5, the coc is contained
|
||||
// within this pixel and the weight should be 1.
|
||||
FfxFloat32 invRad = 1.0 / coc;
|
||||
return ffxSaturate(invRad * invRad / 4);
|
||||
}
|
||||
|
||||
FfxFloat32 FfxDofCoverage(FfxDofInputState ins, FfxFloat32 coc)
|
||||
{
|
||||
// Coverage is essentially the radius of the sample's projection to the lens aperture.
|
||||
// The radius is normalized to the tile CoC and kernel diameter in samples.
|
||||
// Add a small bias to account for gaps between sample rings.
|
||||
// Clamped to avoid infinity near zero.
|
||||
return ffxSaturate(ins.covgFactor / coc + ins.covgBias);
|
||||
}
|
||||
|
||||
#ifdef FFX_DOF_CUSTOM_SAMPLES
|
||||
|
||||
// declarations only
|
||||
|
||||
// *MUST DEFINE* own struct SampleStreamState ! See below #else for example.
|
||||
|
||||
/// Callback for custom blur kernels. Gets the sample offset and advances the iterator.
|
||||
/// @param state Mutable state for the sample stream.
|
||||
/// @return The sample location in normalized uv coordinates. The default implementation approximates a circle using a combination of rotation and translation in an affine transform.
|
||||
/// @ingroup FfxGPUDof
|
||||
FfxFloat32x2 FfxDofAdvanceSampleStream(inout SampleStreamState state);
|
||||
|
||||
/// Callback for custom blur kernels. Gets the number of samples in a ring and initalizes iteration state.
|
||||
/// @param state Mutable state for the sample stream.
|
||||
/// @param ins Input parameters for the blur kernel. Contains the full number of rings.
|
||||
/// @param ri Index of the current ring. If rings are being merged, this is the center of the indices.
|
||||
/// @param mergeRingsCount The number of rings being merged. 1 if the current ring is not merged with any other.
|
||||
/// @return The number of samples in the ring, assuming no merging. This is divided by the mergeRingsCount to get the actual number of samples.
|
||||
/// @ingroup FfxGPUDof
|
||||
FfxUInt32 FfxDofInitSampleStream(out SampleStreamState state, FfxDofInputState ins, FfxFloat32 ri, FfxUInt32 mergeRingsCount);
|
||||
|
||||
#else
|
||||
|
||||
struct SampleStreamState {
|
||||
// represents an affine 2d transform to go from one sample position to the next.
|
||||
FfxFloat32 cosTheta; // top-left and bottom-right element of rotation matrix
|
||||
FfxFloat32 sinThetaXAspect; // bottom-left element of rotation matrix
|
||||
FfxFloat32 mSinThetaXrAspect; // top-right element of rotation matrix
|
||||
FfxFloat32x2 translation; // additive part of affine transform
|
||||
FfxFloat32x2 position; // next sample position
|
||||
};
|
||||
|
||||
FfxFloat32x2 FfxDofAdvanceSampleStream(inout SampleStreamState state)
|
||||
{
|
||||
FfxFloat32x2 pos = state.position;
|
||||
// affine transformation.
|
||||
FfxFloat32 x = state.cosTheta * pos.x + state.mSinThetaXrAspect * pos.y;
|
||||
FfxFloat32 y = state.sinThetaXAspect * pos.x + state.cosTheta * pos.y;
|
||||
state.position = FfxFloat32x2(x, y) + state.translation;
|
||||
return pos;
|
||||
}
|
||||
|
||||
FfxUInt32 FfxDofInitSampleStream(out SampleStreamState state, FfxDofInputState ins, FfxFloat32 ri, FfxUInt32 merge)
|
||||
{
|
||||
#if FFX_DOF_MAX_RING_MERGE > 1
|
||||
FfxUInt32 n = FfxUInt32(6.25 * (ins.nRings - ri)); // approx. pi/asin(1/(2*(nR-ri)))
|
||||
#else
|
||||
// using fixed-point version of above allows scalar alu to do the same operation. Equivalent if merge == 1 (=> ri is integer).
|
||||
FfxUInt32 n = (27 * FfxUInt32(ins.nRings - ri)) >> 2;
|
||||
#endif
|
||||
FfxFloat32 r = ins.tileCoc * ffxReciprocal(ins.nRings) * FfxFloat32(ins.nRings - ri);
|
||||
state.position = InputSizeHalfRcp() * (ins.pxCoord + FfxFloat32x2(r, 0));
|
||||
FfxFloat32 theta = 6.2831853 * ffxReciprocal(n) * merge;
|
||||
FfxFloat32 s = sin(theta), c = cos(theta);
|
||||
FfxFloat32x2 aspect = InputSizeHalf() * InputSizeHalfRcp().yx;
|
||||
|
||||
state.cosTheta = c;
|
||||
state.sinThetaXAspect = s * aspect.x;
|
||||
state.mSinThetaXrAspect = -s * aspect.y;
|
||||
state.translation = InputSizeHalfRcp() * (ins.pxCoord - ins.pxCoord.x * FfxFloat32x2(c, s) - ins.pxCoord.y * FfxFloat32x2(-s, c));
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif // #ifdef FFX_DOF_CUSTOM_SAMPLES
|
||||
|
||||
struct FfxDofRingParams {
|
||||
FfxFloat32 distance; // distance to center in pixels / radius of ring
|
||||
FfxFloat32 bucketBorder; // (far field) border between curr/prev bucket
|
||||
FfxFloat32 rangeThreshNear; // threshold for in-range determination in near field
|
||||
FfxFloat32 rangeThreshFar; // same for far field
|
||||
FfxFloat32 rangeThreshFill; // threshold for main or fallback fill selection
|
||||
FfxFloat32 fillQuality; // bg-fill contribution quality
|
||||
};
|
||||
|
||||
FfxDofSample FfxDofFetchSample(FfxDofInputState ins, inout SampleStreamState streamState, FfxUInt32 mipBias)
|
||||
{
|
||||
FfxFloat32x2 samplePos = FfxDofAdvanceSampleStream(streamState);
|
||||
FfxUInt32 mipLevel = ins.mipLevel + mipBias;
|
||||
FfxFloat32x4 texval = FfxDofSampleInput(samplePos, mipLevel);
|
||||
FfxDofSample result;
|
||||
result.coc = texval.a;
|
||||
result.color = texval.rgb;
|
||||
return result;
|
||||
}
|
||||
|
||||
void FfxDofProcessNearSample(FfxDofInputState ins, FfxDofSample s, inout FfxDofAccumulators acc, FfxDofRingParams ring)
|
||||
{
|
||||
// feather the range slightly (1px)
|
||||
FfxFloat32 inRangeWeight = ffxSaturate(s.coc - ring.rangeThreshNear);
|
||||
FfxFloat32 weight = FfxDofWeight(ins, abs(s.coc));
|
||||
|
||||
// fill background behind center using farther away samples.
|
||||
if (ins.nearField)
|
||||
{
|
||||
// Try to reject same-surface samples using using a slope of 1px radius per px distance.
|
||||
// But use the rejected pixels if no others are available.
|
||||
FfxFloat32 rejectionWeight = (s.coc < ring.rangeThreshFill) ? 1.0 : (1.0/2048.0);
|
||||
// prefer nearest (in image space) samples
|
||||
// Contribution decreases quadratically with sample distance.
|
||||
acc.fillColor += FfxFloat32x4(s.color, 1) * weight * ring.fillQuality * rejectionWeight;
|
||||
}
|
||||
|
||||
acc.nearColor += FfxFloat32x4(s.color, 1) * weight * inRangeWeight;
|
||||
}
|
||||
|
||||
void FfxDofProcessFarSample(FfxDofInputState ins, FfxDofSample s, inout FfxDofAccumulators acc, FfxDofRingParams ring)
|
||||
{
|
||||
FfxFloat32 clampedFarCoc = max(0, -s.coc);
|
||||
FfxFloat32 inRangeWeight = ffxSaturate(-s.coc - ring.rangeThreshFar);
|
||||
|
||||
FfxFloat32 covg = FfxDofCoverage(ins, abs(s.coc));
|
||||
FfxFloat32x4 color = FfxFloat32x4(s.color, 1) * FfxDofWeight(ins, abs(s.coc)) * inRangeWeight;
|
||||
|
||||
if (-s.coc >= ring.bucketBorder)
|
||||
{
|
||||
acc.prevBucket.ringCovg += covg;
|
||||
acc.prevBucket.color += color;
|
||||
acc.prevBucket.sampleCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
acc.currBucket.ringCovg += covg;
|
||||
acc.currBucket.color += color;
|
||||
acc.currBucket.sampleCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void FfxDofProcessNearFar(FfxDofInputState ins, inout FfxDofAccumulators acc)
|
||||
{
|
||||
// base case: both near and far-field are processed.
|
||||
// scan outside-in for far-field occlusion
|
||||
for (FfxUInt32 ri = 0; ri < ins.nRings; ri++)
|
||||
{
|
||||
acc.currBucket.color = FFX_BROADCAST_FLOAT32X4(0);
|
||||
acc.currBucket.ringCovg = 0;
|
||||
acc.currBucket.radius = ffxReciprocal(ins.nRings) * FfxFloat32(ins.nRings - ri);
|
||||
acc.currBucket.sampleCount = 0;
|
||||
|
||||
SampleStreamState streamState;
|
||||
FfxUInt32 ringSamples = FfxDofInitSampleStream(streamState, ins, ri, 1);
|
||||
FfxDofRingParams ring;
|
||||
ring.distance = ins.tileCoc * ffxReciprocal(ins.nRings) * FfxFloat32(ins.nRings - ri);
|
||||
ring.bucketBorder = (ins.nRings - 1 - ri + 2.5) * ins.tileCoc * ffxReciprocal(0.5 + ins.nRings);
|
||||
ring.rangeThreshNear = max(0, ring.distance - ins.ringGap - 0.5);
|
||||
ring.rangeThreshFar = max(0, ring.distance - ins.ringGap);
|
||||
ring.rangeThreshFill = ins.centerCoc - ring.distance;
|
||||
ring.fillQuality = (1 / ring.distance) * (1 / ring.distance);
|
||||
|
||||
// partially unrolled loop
|
||||
const FfxUInt32 UNROLL_CNT = 2;
|
||||
FfxUInt32 iunr = 0;
|
||||
for (iunr = 0; iunr + UNROLL_CNT <= ringSamples; iunr += UNROLL_CNT)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < UNROLL_CNT; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, 0);
|
||||
FfxDofProcessFarSample(ins, s, acc, ring);
|
||||
FfxDofProcessNearSample(ins, s, acc, ring);
|
||||
}
|
||||
}
|
||||
for (FfxUInt32 i = iunr; i < ringSamples; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, 0);
|
||||
FfxDofProcessFarSample(ins, s, acc, ring);
|
||||
FfxDofProcessNearSample(ins, s, acc, ring);
|
||||
}
|
||||
|
||||
FfxFloat32 opacity = FfxFloat32(acc.currBucket.sampleCount) / FfxFloat32(ringSamples);
|
||||
FfxDofMergeBuckets(acc, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxDofProcessNearOnly(FfxDofInputState ins, inout FfxDofAccumulators acc)
|
||||
{
|
||||
// variant with the assumption that all samples are near field
|
||||
for (FfxUInt32 ri = 0; ri < ins.nRings; ri++)
|
||||
{
|
||||
SampleStreamState streamState;
|
||||
FfxUInt32 ringSamples = FfxDofInitSampleStream(streamState, ins, ri, 1);
|
||||
FfxDofRingParams ring;
|
||||
ring.distance = ins.tileCoc * ffxReciprocal(ins.nRings) * FfxFloat32(ins.nRings - ri);
|
||||
ring.rangeThreshNear = max(0, ring.distance - ins.ringGap - 0.5);
|
||||
ring.rangeThreshFill = ins.centerCoc - ring.distance;
|
||||
ring.fillQuality = (1 / ring.distance) * (1 / ring.distance);
|
||||
|
||||
// partially unrolled loop
|
||||
const FfxUInt32 UNROLL_CNT = 4;
|
||||
FfxUInt32 iunr = 0;
|
||||
for (iunr = 0; iunr + UNROLL_CNT <= ringSamples; iunr += UNROLL_CNT)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < UNROLL_CNT; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, 0);
|
||||
FfxDofProcessNearSample(ins, s, acc, ring);
|
||||
}
|
||||
}
|
||||
for (FfxUInt32 i = iunr; i < ringSamples; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, 0);
|
||||
FfxDofProcessNearSample(ins, s, acc, ring);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FfxDofProcessFarOnly(FfxDofInputState ins, inout FfxDofAccumulators acc)
|
||||
{
|
||||
// variant with the assumption that all samples are far field
|
||||
// scan outside-in for far-field occlusion
|
||||
for (FfxUInt32 ri = 0; ri < ins.nRings; ri++)
|
||||
{
|
||||
acc.currBucket.color = FFX_BROADCAST_FLOAT32X4(0);
|
||||
acc.currBucket.ringCovg = 0;
|
||||
acc.currBucket.radius = ffxReciprocal(ins.nRings) * FfxFloat32(ins.nRings - ri);
|
||||
acc.currBucket.sampleCount = 0;
|
||||
|
||||
SampleStreamState streamState;
|
||||
FfxUInt32 ringSamples = FfxDofInitSampleStream(streamState, ins, ri, 1);
|
||||
FfxDofRingParams ring;
|
||||
ring.distance = ins.tileCoc * ffxReciprocal(ins.nRings) * FfxFloat32(ins.nRings - ri);
|
||||
ring.bucketBorder = (ins.nRings - 1 - ri + 2.5) * ins.tileCoc * ffxReciprocal(0.5 + ins.nRings);
|
||||
ring.rangeThreshFar = max(0, ring.distance - ins.ringGap);
|
||||
|
||||
// partially unrolled loop
|
||||
const FfxUInt32 UNROLL_CNT = 3;
|
||||
FfxUInt32 iunr = 0;
|
||||
for (iunr = 0; iunr + UNROLL_CNT <= ringSamples; iunr += UNROLL_CNT)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < UNROLL_CNT; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, 0);
|
||||
FfxDofProcessFarSample(ins, s, acc, ring);
|
||||
}
|
||||
}
|
||||
for (FfxUInt32 i = iunr; i < ringSamples; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, 0);
|
||||
FfxDofProcessFarSample(ins, s, acc, ring);
|
||||
}
|
||||
|
||||
FfxFloat32 opacity = FfxFloat32(acc.currBucket.sampleCount) / FfxFloat32(ringSamples);
|
||||
FfxDofMergeBuckets(acc, opacity);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxDofProcessNearColorOnly(FfxDofInputState ins, inout FfxDofAccumulators acc)
|
||||
{
|
||||
// variant with the assumption that all samples are near and equally weighed
|
||||
for (FfxUInt32 ri = 0; ri < ins.nRings;)
|
||||
{
|
||||
// merge inner rings if possible
|
||||
FfxUInt32 merge = min(min(1 << ri, FFX_DOF_MAX_RING_MERGE), ins.nRings - ri);
|
||||
FfxFloat32 rif = ri + 0.5 * merge - 0.5;
|
||||
FfxUInt32 weight = merge * merge;
|
||||
SampleStreamState streamState;
|
||||
FfxUInt32 ringSamples = FfxDofInitSampleStream(streamState, ins, rif, merge) / merge;
|
||||
FfxUInt32 mipBias = 2 * FfxUInt32(log2(merge));
|
||||
FfxFloat32 sampleDist = ins.tileCoc * ffxReciprocal(ins.nRings) * (FfxFloat32(ins.nRings) - rif);
|
||||
FfxHalfOpt rangeThresh = FfxHalfOpt(max(0, sampleDist - ins.ringGap - 0.5));
|
||||
|
||||
FfxHalfOpt3 nearColorAcc = FfxHalfOpt3(0, 0, 0);
|
||||
FfxHalfOpt weightSum = FfxHalfOpt(0);
|
||||
// We presume that all samples are in range
|
||||
// partially unrolled loop (x6)
|
||||
const FfxUInt32 UNROLL_CNT = 6;
|
||||
FfxUInt32 iunr = 0;
|
||||
for (iunr = 0; iunr + UNROLL_CNT <= ringSamples; iunr += UNROLL_CNT)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < UNROLL_CNT; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
FfxHalfOpt rangeWeight = ffxSaturate(FfxHalfOpt(s.coc) - rangeThresh);
|
||||
nearColorAcc += FfxHalfOpt3(s.color) * rangeWeight;
|
||||
weightSum += rangeWeight;
|
||||
}
|
||||
}
|
||||
for (FfxUInt32 i = iunr; i < ringSamples; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
FfxHalfOpt rangeWeight = ffxSaturate(FfxHalfOpt(s.coc) - rangeThresh);
|
||||
nearColorAcc += FfxHalfOpt3(s.color) * rangeWeight;
|
||||
weightSum += rangeWeight;
|
||||
}
|
||||
acc.nearColor.rgb += nearColorAcc * FfxHalfOpt(weight);
|
||||
acc.nearColor.a += weightSum * FfxHalfOpt(weight);
|
||||
ri += merge;
|
||||
}
|
||||
}
|
||||
|
||||
void FfxDofProcessFarColorOnly(FfxDofInputState ins, inout FfxDofAccumulators acc)
|
||||
{
|
||||
FfxFloat32 nSamples = 0;
|
||||
FfxUInt32 ri = 0;
|
||||
// peel first iteration
|
||||
if (ri < ins.nRings)
|
||||
{
|
||||
// merge inner rings if possible
|
||||
FfxUInt32 merge = min(min(1 << ri, FFX_DOF_MAX_RING_MERGE), ins.nRings - ri);
|
||||
FfxFloat32 rif = ri + 0.5 * merge - 0.5;
|
||||
FfxUInt32 weight = merge * merge;
|
||||
SampleStreamState streamState;
|
||||
FfxUInt32 ringSamples = FfxDofInitSampleStream(streamState, ins, rif, merge) / merge;
|
||||
FfxUInt32 mipBias = 2 * FfxUInt32(log2(merge));
|
||||
FfxFloat32 sampleDist = ins.tileCoc * ffxReciprocal(ins.nRings) * (FfxFloat32(ins.nRings) - rif);
|
||||
FfxHalfOpt rangeThresh = FfxHalfOpt(max(0, sampleDist - ins.ringGap));
|
||||
|
||||
FfxHalfOpt3 colorAcc = FfxHalfOpt3(0, 0, 0);
|
||||
FfxHalfOpt weightSum = FfxHalfOpt(0);
|
||||
// partially unrolled loop (x8, then x4)
|
||||
FfxUInt32 iunr = 0;
|
||||
for (; iunr + 8 <= ringSamples; iunr += 8)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < 8; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
FfxHalfOpt rangeWeight = ffxSaturate(FfxHalfOpt(-s.coc) - rangeThresh);
|
||||
colorAcc += FfxHalfOpt3(s.color) * rangeWeight;
|
||||
weightSum += rangeWeight;
|
||||
}
|
||||
}
|
||||
for (; iunr + 4 <= ringSamples; iunr += 4)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < 4; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
FfxHalfOpt rangeWeight = ffxSaturate(FfxHalfOpt(-s.coc) - rangeThresh);
|
||||
colorAcc += FfxHalfOpt3(s.color) * rangeWeight;
|
||||
weightSum += rangeWeight;
|
||||
}
|
||||
}
|
||||
for (FfxUInt32 i = iunr; i < ringSamples; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
FfxHalfOpt rangeWeight = ffxSaturate(FfxHalfOpt(-s.coc) - rangeThresh);
|
||||
colorAcc += FfxHalfOpt3(s.color) * rangeWeight;
|
||||
weightSum += rangeWeight;
|
||||
}
|
||||
acc.prevBucket.color.rgb += colorAcc * FfxHalfOpt(weight);
|
||||
nSamples += weightSum * FfxHalfOpt(weight);
|
||||
ri += merge;
|
||||
}
|
||||
while (ri < ins.nRings)
|
||||
{
|
||||
// merge inner rings if possible
|
||||
FfxUInt32 merge = min(min(1 << ri, FFX_DOF_MAX_RING_MERGE), ins.nRings - ri);
|
||||
FfxFloat32 rif = ri + 0.5 * merge - 0.5;
|
||||
FfxUInt32 weight = merge * merge;
|
||||
SampleStreamState streamState;
|
||||
FfxUInt32 ringSamples = FfxDofInitSampleStream(streamState, ins, rif, merge) / merge;
|
||||
FfxUInt32 mipBias = 2 * FfxUInt32(log2(merge));
|
||||
|
||||
FfxHalfOpt3 colorAcc = FfxHalfOpt3(0, 0, 0);
|
||||
// partially unrolled loop (x12, then x4)
|
||||
FfxUInt32 iunr = 0;
|
||||
for (; iunr + 12 <= ringSamples; iunr += 12)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < 12; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
// Max difference between sample coc and tile coc is 0.5px (see PrepareTile).
|
||||
// Max radius of any ring after first (ri>0) is 1 less than tile coc.
|
||||
// rangeWeight = 1
|
||||
colorAcc += FfxHalfOpt3(s.color);
|
||||
}
|
||||
}
|
||||
for (; iunr + 4 <= ringSamples; iunr += 4)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 i = 0; i < 4; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
colorAcc += FfxHalfOpt3(s.color);
|
||||
}
|
||||
}
|
||||
for (FfxUInt32 i = iunr; i < ringSamples; i++)
|
||||
{
|
||||
FfxDofSample s = FfxDofFetchSample(ins, streamState, mipBias);
|
||||
colorAcc += FfxHalfOpt3(s.color);
|
||||
}
|
||||
acc.prevBucket.color.rgb += colorAcc * FfxHalfOpt(weight);
|
||||
nSamples += ringSamples * weight;
|
||||
ri += merge;
|
||||
}
|
||||
acc.prevBucket.color.a = nSamples;
|
||||
acc.prevBucket.ringCovg = nSamples;
|
||||
acc.prevBucket.sampleCount = FfxUInt32(nSamples);
|
||||
}
|
||||
|
||||
struct FfxDofTileClass
|
||||
{
|
||||
FfxBoolean colorOnly, needsNear, needsFar;
|
||||
};
|
||||
|
||||
// prepare values for the tile. Return classification.
|
||||
FfxDofTileClass FfxDofPrepareTile(FfxUInt32x2 id, out FfxDofInputState ins)
|
||||
{
|
||||
FfxDofTileClass tileClass;
|
||||
FfxFloat32x2 dilatedCocSigned = FfxDofSampleDilatedRadius(id);
|
||||
FfxFloat32x2 dilatedCoc = abs(dilatedCocSigned);
|
||||
FfxFloat32 tileRad = max(dilatedCoc.x, dilatedCoc.y);
|
||||
|
||||
// check if copying the tile is good enough
|
||||
#if FFX_HLSL
|
||||
if (WaveActiveAllTrue(tileRad < 0.5))
|
||||
#elif FFX_GLSL
|
||||
if (subgroupAll(tileRad < 0.5))
|
||||
#endif
|
||||
{
|
||||
tileClass.needsNear = false;
|
||||
tileClass.needsFar = false;
|
||||
tileClass.colorOnly = false;
|
||||
return tileClass;
|
||||
}
|
||||
|
||||
FfxFloat32 idealRingCount = // kernel radius in pixels -> one sample per pixel
|
||||
#if FFX_HLSL
|
||||
WaveActiveMax(ceil(tileRad));
|
||||
#elif FFX_GLSL
|
||||
subgroupMax(ceil(tileRad));
|
||||
#endif
|
||||
ins.nRings = FfxUInt32(idealRingCount);
|
||||
ins.mipLevel = 0;
|
||||
if (idealRingCount > MaxRings())
|
||||
{
|
||||
ins.nRings = MaxRings();
|
||||
// use a higher mip to cover the missing rings.
|
||||
// for every factor 2 decrease of the rings, increase mips by 1.
|
||||
ins.mipLevel = FfxUInt32(log2(idealRingCount * ffxReciprocal(MaxRings())));
|
||||
}
|
||||
// Gap = number of pixels between rings that are not sampled.
|
||||
ins.ringGap = idealRingCount / ins.nRings - 1.0;
|
||||
ins.tileCoc = tileRad;
|
||||
|
||||
FfxFloat32x2 texcoord = FfxFloat32x2(id) + FfxFloat32x2(0.25, 0.25); // shift to center of top-left pixel in quad
|
||||
// Add noise to reduce banding (if too noisy, this could be disabled)
|
||||
{
|
||||
/* hash22 adapted from https://www.shadertoy.com/view/4djSRW
|
||||
Copyright (c)2014 David Hoskins.
|
||||
|
||||
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.*/
|
||||
FfxFloat32x3 p3 = ffxFract(texcoord.xyx * FfxFloat32x3(0.1031, 0.1030, 0.0973));
|
||||
p3 += dot(p3, p3.yzx + 33.33);
|
||||
texcoord += ffxFract((p3.xx+p3.yz)*p3.zy) * 0.5 - 0.25;
|
||||
}
|
||||
ins.pxCoord = texcoord;
|
||||
|
||||
FfxFloat32 centerCoc = FfxDofLoadInput(id).a;
|
||||
ins.nearField = centerCoc > 0;
|
||||
ins.centerCoc = abs(centerCoc);
|
||||
|
||||
ins.nSamples = 0;
|
||||
#ifdef FFX_DOF_CUSTOM_SAMPLES
|
||||
for (FfxUInt32 ri = 0; ri < ins.nRings; ri++)
|
||||
{
|
||||
SampleStreamState streamState;
|
||||
ins.nSamples += FfxDofInitSampleStream(streamState, ins, ri, 1);
|
||||
}
|
||||
#else
|
||||
// due to rounding this will likely over-approximate, but that should be okay.
|
||||
ins.nSamples = FfxUInt32(6.25 * 0.5 * (ins.nRings * (ins.nRings + 1)));
|
||||
#endif
|
||||
|
||||
// read first lane to force using a scalar register.
|
||||
ins.covgFactor = ffxWaveReadLaneFirst(0.5 * ffxReciprocal(ins.nRings) * ins.tileCoc);
|
||||
ins.covgBias = ffxWaveReadLaneFirst(0.5 * ffxReciprocal(ins.nRings));
|
||||
|
||||
#if FFX_HLSL
|
||||
// simple check: is there even any near/far that we would sample?
|
||||
// See ProcessNearSample: No relevant code is executed if the center is not near and no sample is near
|
||||
// (use the CoC of the dilated tile minimum depth as the proxy for any sample)
|
||||
tileClass.needsNear = WaveActiveAnyTrue(dilatedCocSigned.x > -1);
|
||||
// See ProcessFarSample: All weights will be 0 if no sample is in the far field.
|
||||
// (use the CoC of dilated tile max depth as proxy)
|
||||
tileClass.needsFar = WaveActiveAnyTrue(dilatedCocSigned.y < 1);
|
||||
|
||||
tileClass.colorOnly = WaveActiveAllTrue(dilatedCocSigned.x - dilatedCocSigned.y < 0.5);
|
||||
#elif FFX_GLSL
|
||||
// as above
|
||||
tileClass.needsNear = subgroupAny(dilatedCocSigned.x > -1);
|
||||
tileClass.needsFar = subgroupAny(dilatedCocSigned.y < 1);
|
||||
tileClass.colorOnly = subgroupAll(dilatedCocSigned.x - dilatedCocSigned.y < 0.5);
|
||||
#endif
|
||||
|
||||
return tileClass;
|
||||
}
|
||||
|
||||
/// Blur pass entry point. Runs in 8x8x1 thread groups and computes transient near and far outputs.
|
||||
///
|
||||
/// @param pixel Coordinate of the pixel (SV_DispatchThreadID)
|
||||
/// @param halfImageSize Resolution of the source image (half resolution) in pixels
|
||||
/// @ingroup FfxGPUDof
|
||||
void FfxDofBlur(FfxUInt32x2 pixel, FfxUInt32x2 halfImageSize)
|
||||
{
|
||||
FfxDofResetMaxTileRadius();
|
||||
|
||||
FfxDofInputState ins;
|
||||
FfxDofTileClass tileClass = FfxDofPrepareTile(pixel, ins);
|
||||
ins.imageSize = halfImageSize;
|
||||
|
||||
// initialize accumulators
|
||||
FfxDofAccumulators acc;
|
||||
acc.prevBucket.color = FfxFloat32x4(0, 0, 0, 0);
|
||||
acc.prevBucket.ringCovg = 0;
|
||||
acc.prevBucket.radius = 0;
|
||||
acc.prevBucket.sampleCount = 0;
|
||||
|
||||
FfxFloat32 centerWeight = FfxDofWeight(ins, ins.centerCoc);
|
||||
FfxFloat32 centerCovg = FfxDofCoverage(ins, ins.centerCoc);
|
||||
|
||||
FfxFloat32x4 centerColor = FfxFloat32x4(FfxDofLoadInput(pixel).rgb, 1);
|
||||
acc.nearColor = FfxFloat32x4(0, 0, 0, 0);
|
||||
acc.fillColor = FfxFloat32x4(0, 0, 0, 0);
|
||||
|
||||
if (ins.nearField)
|
||||
{
|
||||
// for near field: adjust center weight to cover everything beyond innermost ring
|
||||
// radius of innermost ring:
|
||||
FfxFloat32 innerRingRad = max(1, ins.tileCoc * ffxReciprocal(ins.nRings) - pow(2, ins.mipLevel));
|
||||
FfxFloat32 nearCenterWeight = innerRingRad * innerRingRad;
|
||||
|
||||
// if center radius < 1px, split the center color between near and fill
|
||||
FfxFloat32 nearPart = ffxSaturate(ins.centerCoc), fillPart = 1 - nearPart;
|
||||
acc.nearColor = centerColor * centerWeight * nearCenterWeight * nearPart;
|
||||
acc.fillColor = centerColor * fillPart;
|
||||
}
|
||||
|
||||
if (tileClass.needsNear && tileClass.needsFar)
|
||||
{
|
||||
FfxDofProcessNearFar(ins, acc);
|
||||
}
|
||||
else if (tileClass.needsNear)
|
||||
{
|
||||
if (tileClass.colorOnly)
|
||||
FfxDofProcessNearColorOnly(ins, acc);
|
||||
else
|
||||
FfxDofProcessNearOnly(ins, acc);
|
||||
}
|
||||
else if (tileClass.needsFar)
|
||||
{
|
||||
if (tileClass.colorOnly)
|
||||
FfxDofProcessFarColorOnly(ins, acc);
|
||||
else
|
||||
FfxDofProcessFarOnly(ins, acc);
|
||||
}
|
||||
else // if (!tileClass.needsFar && !tileClass.needsNear)
|
||||
{
|
||||
FfxDofStoreFar(pixel, FfxHalfOpt4(FfxDofLoadInput(pixel).rgb, 1));
|
||||
FfxDofStoreNear(pixel, FfxHalfOpt4(0, 0, 0, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
// process center
|
||||
acc.currBucket.ringCovg = ins.nearField ? 0 : centerCovg;
|
||||
acc.currBucket.color = ins.nearField ? FfxFloat32x4(0, 0, 0, 0) : centerColor * centerWeight;
|
||||
acc.currBucket.radius = 0;
|
||||
acc.currBucket.sampleCount = 1;
|
||||
FfxDofMergeBuckets(acc, 1);
|
||||
|
||||
if (ins.nearField)
|
||||
{
|
||||
acc.prevBucket.color += acc.fillColor;
|
||||
}
|
||||
FfxFloat32 fgOpacity = (!tileClass.needsFar && tileClass.colorOnly) ? 1.0 :
|
||||
ffxSaturate(acc.nearColor.a / (FfxDofWeight(ins, ins.tileCoc) * ins.nSamples));
|
||||
|
||||
FfxFloat32x4 ffTarget = acc.prevBucket.color / acc.prevBucket.color.a;
|
||||
FfxFloat32x4 ffOutput = !any(isnan(ffTarget)) ? ffTarget : FfxFloat32x4(0, 0, 0, 0);
|
||||
FfxFloat32x3 nfTarget = acc.nearColor.rgb / acc.nearColor.a;
|
||||
FfxFloat32x4 nfOutput = FfxFloat32x4(!any(isnan(nfTarget)) ? nfTarget : FfxFloat32x3(0, 0, 0), fgOpacity);
|
||||
|
||||
FfxDofStoreFar(pixel, FfxHalfOpt4(ffOutput));
|
||||
FfxDofStoreNear(pixel, FfxHalfOpt4(nfOutput));
|
||||
}
|
||||
282
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_callbacks_glsl.h
vendored
Normal file
282
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_callbacks_glsl.h
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
// 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_dof_resources.h"
|
||||
#include "ffx_core.h"
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#if defined(FFX_DOF_BIND_CB_DOF)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_CB_DOF, std140) uniform cbDOF_t
|
||||
{
|
||||
FfxFloat32 cocScale;
|
||||
FfxFloat32 cocBias;
|
||||
FfxUInt32x2 inputSizeHalf;
|
||||
FfxUInt32x2 inputSize;
|
||||
FfxFloat32x2 inputSizeHalfRcp;
|
||||
FfxFloat32 cocLimit;
|
||||
FfxUInt32 maxRings;
|
||||
#define FFX_DOF_CONSTANT_BUFFER_1_SIZE 10 // Number of 32-bit values. This must be kept in sync with the cbDOF size.
|
||||
} cbDOF;
|
||||
#endif
|
||||
|
||||
FfxFloat32 CocScale()
|
||||
{
|
||||
return cbDOF.cocScale;
|
||||
}
|
||||
|
||||
FfxFloat32 CocBias()
|
||||
{
|
||||
return cbDOF.cocBias;
|
||||
}
|
||||
|
||||
FfxUInt32x2 InputSizeHalf()
|
||||
{
|
||||
return cbDOF.inputSizeHalf;
|
||||
}
|
||||
|
||||
FfxUInt32x2 InputSize()
|
||||
{
|
||||
return cbDOF.inputSize;
|
||||
}
|
||||
|
||||
FfxFloat32x2 InputSizeHalfRcp()
|
||||
{
|
||||
return cbDOF.inputSizeHalfRcp;
|
||||
}
|
||||
|
||||
FfxFloat32 CocLimit()
|
||||
{
|
||||
return cbDOF.cocLimit;
|
||||
}
|
||||
|
||||
FfxUInt32 MaxRings()
|
||||
{
|
||||
return cbDOF.maxRings;
|
||||
}
|
||||
|
||||
layout (set = 0, binding = 1000)
|
||||
uniform sampler LinearSampler;
|
||||
layout (set = 0, binding = 1001)
|
||||
uniform sampler PointSampler;
|
||||
|
||||
#if FFX_HALF
|
||||
#define FFX_DOF_HALF_OPT_LAYOUT rgba16f
|
||||
#else // #if FFX_HALF
|
||||
#define FFX_DOF_HALF_OPT_LAYOUT rgba32f
|
||||
#endif // #if FFX_HALF #else
|
||||
|
||||
// SRVs
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
uniform texture2D r_input_depth;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
uniform texture2D r_input_color;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
uniform texture2D r_internal_bilat_color;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
uniform texture2D r_internal_dilated_radius;
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR, FFX_DOF_HALF_OPT_LAYOUT)
|
||||
uniform image2D rw_internal_bilat_color[4];
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_UAV_INTERNAL_RADIUS, rg32f)
|
||||
uniform image2D rw_internal_radius;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS, rg32f)
|
||||
uniform image2D rw_internal_dilated_radius;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_UAV_INTERNAL_NEAR, FFX_DOF_HALF_OPT_LAYOUT)
|
||||
uniform image2D rw_internal_near;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_UAV_INTERNAL_FAR, FFX_DOF_HALF_OPT_LAYOUT)
|
||||
uniform image2D rw_internal_far;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_UAV_OUTPUT_COLOR, rgba32f)
|
||||
uniform image2D rw_output_color;
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
layout (set = 0, binding = FFX_DOF_BIND_UAV_INTERNAL_GLOBALS, std430)
|
||||
coherent buffer DofGlobalVars_t { uint maxTileRad; } rw_internal_globals;
|
||||
#endif
|
||||
|
||||
#include "ffx_dof_common.h"
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
FfxHalfOpt4 FfxDofLoadSource(FfxInt32x2 tex)
|
||||
{
|
||||
return FfxHalfOpt4(texelFetch(sampler2D(r_input_color, LinearSampler), tex, 0));
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR)
|
||||
void FfxDofStoreBilatMip(FfxUInt32 mip, FfxInt32x2 tex, FfxHalfOpt4 value)
|
||||
{
|
||||
imageStore(rw_internal_bilat_color[mip], tex, value);
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_CB_DOF)
|
||||
FfxFloat32 FfxDofGetCoc(FfxFloat32 depth)
|
||||
{
|
||||
// clamped for perf reasons
|
||||
return clamp(CocScale() * depth + CocBias(), -CocLimit(), CocLimit());
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_CB_DOF)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS)
|
||||
void FfxDofStoreDilatedRadius(FfxUInt32x2 coord, FfxFloat32x2 dilatedMinMax)
|
||||
{
|
||||
imageStore(rw_internal_dilated_radius, ivec2(coord), vec4(dilatedMinMax, 0, 0));
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
#if defined(FFX_DOF_BIND_CB_DOF)
|
||||
FfxFloat32x2 FfxDofSampleDilatedRadius(FfxUInt32x2 coord)
|
||||
{
|
||||
return textureLod(sampler2D(r_internal_dilated_radius, LinearSampler), vec2(coord) * InputSizeHalfRcp(), 0).rg;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_CB_DOF)
|
||||
|
||||
FfxFloat32x2 FfxDofLoadDilatedRadius(FfxUInt32x2 coord)
|
||||
{
|
||||
return texelFetch(sampler2D(r_internal_dilated_radius, LinearSampler), ivec2(coord), 0).rg;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
FfxHalfOpt4 FfxDofLoadInput(FfxUInt32x2 coord)
|
||||
{
|
||||
return FfxHalfOpt4(texelFetch(sampler2D(r_internal_bilat_color, LinearSampler), ivec2(coord), 0));
|
||||
}
|
||||
|
||||
#if defined(FFX_DOF_BIND_CB_DOF)
|
||||
FfxHalfOpt4 FfxDofSampleInput(FfxFloat32x2 coord, FfxUInt32 mip)
|
||||
{
|
||||
return FfxHalfOpt4(textureLod(sampler2D(r_internal_bilat_color, PointSampler), coord, mip));
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_CB_DOF)
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
FfxFloat32x4 FfxDofGatherDepth(FfxFloat32x2 coord)
|
||||
{
|
||||
return textureGather(sampler2D(r_input_depth, LinearSampler), coord);
|
||||
}
|
||||
|
||||
FfxFloat32 FfxDofLoadFullDepth(FfxUInt32x2 coord)
|
||||
{
|
||||
return texelFetch(sampler2D(r_input_depth, LinearSampler), ivec2(coord), 0).r;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
void FfxDofStoreNear(FfxUInt32x2 coord, FfxHalfOpt4 color)
|
||||
{
|
||||
imageStore(rw_internal_near, ivec2(coord), color);
|
||||
}
|
||||
|
||||
FfxHalfOpt4 FfxDofLoadNear(FfxUInt32x2 coord)
|
||||
{
|
||||
return FfxHalfOpt4(imageLoad(rw_internal_near, ivec2(coord)));
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
void FfxDofStoreFar(FfxUInt32x2 coord, FfxHalfOpt4 color)
|
||||
{
|
||||
imageStore(rw_internal_far, ivec2(coord), color);
|
||||
}
|
||||
|
||||
FfxHalfOpt4 FfxDofLoadFar(FfxUInt32x2 coord)
|
||||
{
|
||||
return FfxHalfOpt4(imageLoad(rw_internal_far, ivec2(coord)));
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
void FfxDofAccumMaxTileRadius(FfxUInt32 radius)
|
||||
{
|
||||
atomicMax(rw_internal_globals.maxTileRad, radius);
|
||||
}
|
||||
|
||||
FfxUInt32 FfxDofGetMaxTileRadius()
|
||||
{
|
||||
return rw_internal_globals.maxTileRad;
|
||||
}
|
||||
|
||||
void FfxDofResetMaxTileRadius()
|
||||
{
|
||||
rw_internal_globals.maxTileRad = 0;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
void FfxDofStoreTileRadius(FfxUInt32x2 tile, FfxFloat32x2 radius)
|
||||
{
|
||||
imageStore(rw_internal_radius, ivec2(tile), vec4(radius, 0, 0));
|
||||
}
|
||||
|
||||
FfxFloat32x2 FfxDofLoadTileRadius(FfxUInt32x2 tile)
|
||||
{
|
||||
return imageLoad(rw_internal_radius, ivec2(tile)).rg;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
FfxFloat32x4 FfxDofLoadFullInput(FfxUInt32x2 coord)
|
||||
{
|
||||
return texelFetch(sampler2D(r_input_color, LinearSampler), ivec2(coord), 0);
|
||||
}
|
||||
#elif (defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)) && FFX_DOF_OPTION_COMBINE_IN_PLACE
|
||||
FfxFloat32x4 FfxDofLoadFullInput(FfxUInt32x2 coord)
|
||||
{
|
||||
return imageLoad(rw_output_color, ivec2(coord));
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)
|
||||
void FfxDofStoreOutput(FfxUInt32x2 coord, FfxFloat32x4 color)
|
||||
{
|
||||
imageStore(rw_output_color, ivec2(coord), color);
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
322
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_callbacks_hlsl.h
vendored
Normal file
322
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_callbacks_hlsl.h
vendored
Normal file
@@ -0,0 +1,322 @@
|
||||
// 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_dof_resources.h"
|
||||
#include "ffx_core.h"
|
||||
#include "ffx_dof_common.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
|
||||
|
||||
#ifndef FFX_PREFER_WAVE64
|
||||
#define FFX_PREFER_WAVE64
|
||||
#endif // #ifndef FFX_PREFER_WAVE64
|
||||
|
||||
#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_DOF_DECLARE_SRV(regIndex) register(DECLARE_SRV_REGISTER(regIndex))
|
||||
#define FFX_DOF_DECLARE_UAV(regIndex) register(DECLARE_UAV_REGISTER(regIndex))
|
||||
#define FFX_DOF_DECLARE_CB(regIndex) register(DECLARE_CB_REGISTER(regIndex))
|
||||
|
||||
#if defined(FFX_DOF_BIND_CB_DOF)
|
||||
cbuffer cbDOF : FFX_DOF_DECLARE_CB(FFX_DOF_BIND_CB_DOF)
|
||||
{
|
||||
FfxFloat32 cocScale;
|
||||
FfxFloat32 cocBias;
|
||||
FfxUInt32x2 inputSizeHalf;
|
||||
FfxUInt32x2 inputSize;
|
||||
FfxFloat32x2 inputSizeHalfRcp;
|
||||
FfxFloat32 cocLimit;
|
||||
FfxUInt32 maxRings;
|
||||
#define FFX_DOF_CONSTANT_BUFFER_1_SIZE 10 // Number of 32-bit values. This must be kept in sync with the cbDOF size.
|
||||
};
|
||||
#else
|
||||
#define cocScale 0
|
||||
#define cocBias 0
|
||||
#define inputSizeHalf 0
|
||||
#define inputSize 0
|
||||
#define inputSizeHalfRcp 0
|
||||
#define cocLimit 0
|
||||
#define maxRings 0
|
||||
#endif
|
||||
|
||||
#define FFX_DOF_ROOTSIG_STRINGIFY(p) FFX_DOF_ROOTSIG_STR(p)
|
||||
#define FFX_DOF_ROOTSIG_STR(p) #p
|
||||
#define FFX_DOF_ROOTSIG [RootSignature("DescriptorTable(UAV(u0, numDescriptors = " FFX_DOF_ROOTSIG_STRINGIFY(FFX_DOF_RESOURCE_IDENTIFIER_COUNT) ")), " \
|
||||
"DescriptorTable(SRV(t0, numDescriptors = " FFX_DOF_ROOTSIG_STRINGIFY(FFX_DOF_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), " \
|
||||
"StaticSampler(s1, 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)" )]
|
||||
|
||||
#if defined(FFX_DOF_EMBED_ROOTSIG)
|
||||
#define FFX_DOF_EMBED_ROOTSIG_CONTENT FFX_DOF_ROOTSIG
|
||||
#else
|
||||
#define FFX_DOF_EMBED_ROOTSIG_CONTENT
|
||||
#endif // #if FFX_SPD_EMBED_ROOTSIG
|
||||
|
||||
FfxFloat32 CocScale()
|
||||
{
|
||||
return cocScale;
|
||||
}
|
||||
|
||||
FfxFloat32 CocBias()
|
||||
{
|
||||
return cocBias;
|
||||
}
|
||||
|
||||
FfxUInt32x2 InputSizeHalf()
|
||||
{
|
||||
return inputSizeHalf;
|
||||
}
|
||||
|
||||
FfxUInt32x2 InputSize()
|
||||
{
|
||||
return inputSize;
|
||||
}
|
||||
|
||||
FfxFloat32x2 InputSizeHalfRcp()
|
||||
{
|
||||
return inputSizeHalfRcp;
|
||||
}
|
||||
|
||||
FfxFloat32 CocLimit()
|
||||
{
|
||||
return cocLimit;
|
||||
}
|
||||
|
||||
FfxUInt32 MaxRings()
|
||||
{
|
||||
return maxRings;
|
||||
}
|
||||
|
||||
SamplerState LinearSampler : register(s0);
|
||||
SamplerState PointSampler : register(s1);
|
||||
|
||||
// SRVs
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
Texture2D<FfxFloat32> r_input_depth : FFX_DOF_DECLARE_SRV(FFX_DOF_BIND_SRV_INPUT_DEPTH);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
Texture2D<FfxFloat32x4> r_input_color : FFX_DOF_DECLARE_SRV(FFX_DOF_BIND_SRV_INPUT_COLOR);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
Texture2D<FfxHalfOpt4> r_internal_bilat_color : FFX_DOF_DECLARE_SRV(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
Texture2D<FfxFloat32x2> r_internal_dilated_radius : FFX_DOF_DECLARE_SRV(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS);
|
||||
#endif
|
||||
|
||||
// UAVs
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR)
|
||||
RWTexture2D<FfxHalfOpt4> rw_internal_bilat_color[4] : FFX_DOF_DECLARE_UAV(FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
RWTexture2D<FfxFloat32x2> rw_internal_radius : FFX_DOF_DECLARE_UAV(FFX_DOF_BIND_UAV_INTERNAL_RADIUS);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS)
|
||||
RWTexture2D<FfxFloat32x2> rw_internal_dilated_radius : FFX_DOF_DECLARE_UAV(FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
RWTexture2D<FfxHalfOpt4> rw_internal_near : FFX_DOF_DECLARE_UAV(FFX_DOF_BIND_UAV_INTERNAL_NEAR);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
RWTexture2D<FfxHalfOpt4> rw_internal_far : FFX_DOF_DECLARE_UAV(FFX_DOF_BIND_UAV_INTERNAL_FAR);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)
|
||||
RWTexture2D<FfxFloat32x4> rw_output_color : FFX_DOF_DECLARE_UAV(FFX_DOF_BIND_UAV_OUTPUT_COLOR);
|
||||
#endif
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
struct DofGlobalVars { uint maxTileRad; };
|
||||
globallycoherent RWStructuredBuffer<DofGlobalVars> rw_internal_globals : FFX_DOF_DECLARE_UAV(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS);
|
||||
#endif
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
FfxHalfOpt4 FfxDofLoadSource(FfxInt32x2 tex)
|
||||
{
|
||||
return FfxHalfOpt4(r_input_color[tex]);
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR)
|
||||
void FfxDofStoreBilatMip(FfxUInt32 mip, FfxInt32x2 tex, FfxHalfOpt4 value)
|
||||
{
|
||||
rw_internal_bilat_color[mip][tex] = value;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_BILAT_COLOR)
|
||||
|
||||
FfxFloat32 FfxDofGetCoc(FfxFloat32 depth)
|
||||
{
|
||||
// clamped for perf reasons
|
||||
return clamp(CocScale() * depth + CocBias(), -CocLimit(), CocLimit());
|
||||
}
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS)
|
||||
void FfxDofStoreDilatedRadius(FfxUInt32x2 coord, FfxFloat32x2 dilatedMinMax)
|
||||
{
|
||||
rw_internal_dilated_radius[coord] = dilatedMinMax;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_DILATED_RADIUS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
FfxFloat32x2 FfxDofSampleDilatedRadius(FfxUInt32x2 coord)
|
||||
{
|
||||
return r_internal_dilated_radius.SampleLevel(LinearSampler, float2(coord) * InputSizeHalfRcp(), 0);
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
FfxFloat32x2 FfxDofLoadDilatedRadius(FfxUInt32x2 coord)
|
||||
{
|
||||
return r_internal_dilated_radius[coord];
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INTERNAL_DILATED_RADIUS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
FfxHalfOpt4 FfxDofLoadInput(FfxUInt32x2 coord)
|
||||
{
|
||||
return r_internal_bilat_color[coord];
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
FfxHalfOpt4 FfxDofSampleInput(FfxFloat32x2 coord, FfxUInt32 mip)
|
||||
{
|
||||
return r_internal_bilat_color.SampleLevel(PointSampler, coord, mip);
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INTERNAL_BILAT_COLOR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
FfxFloat32x4 FfxDofGatherDepth(FfxFloat32x2 coord)
|
||||
{
|
||||
return r_input_depth.GatherRed(LinearSampler, coord);
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
FfxFloat32 FfxDofLoadFullDepth(FfxUInt32x2 coord)
|
||||
{
|
||||
return r_input_depth[coord];
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INPUT_DEPTH)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
void FfxDofStoreNear(FfxUInt32x2 coord, FfxHalfOpt4 color)
|
||||
{
|
||||
rw_internal_near[coord] = color;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
FfxHalfOpt4 FfxDofLoadNear(FfxUInt32x2 coord)
|
||||
{
|
||||
return rw_internal_near[coord];
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_NEAR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
void FfxDofStoreFar(FfxUInt32x2 coord, FfxHalfOpt4 color)
|
||||
{
|
||||
rw_internal_far[coord] = color;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
FfxHalfOpt4 FfxDofLoadFar(FfxUInt32x2 coord)
|
||||
{
|
||||
return rw_internal_far[coord];
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_FAR)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
void FfxDofAccumMaxTileRadius(FfxUInt32 radius)
|
||||
{
|
||||
uint dummy;
|
||||
InterlockedMax(rw_internal_globals[0].maxTileRad, radius, dummy);
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
FfxUInt32 FfxDofGetMaxTileRadius()
|
||||
{
|
||||
return rw_internal_globals[0].maxTileRad;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
void FfxDofResetMaxTileRadius()
|
||||
{
|
||||
rw_internal_globals[0].maxTileRad = 0;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_GLOBALS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
void FfxDofStoreTileRadius(FfxUInt32x2 tile, FfxFloat32x2 radius)
|
||||
{
|
||||
rw_internal_radius[tile] = radius;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
FfxFloat32x2 FfxDofLoadTileRadius(FfxUInt32x2 tile)
|
||||
{
|
||||
return rw_internal_radius[tile];
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_INTERNAL_RADIUS)
|
||||
|
||||
FfxFloat32x4 FfxDofLoadFullInput(FfxUInt32x2 coord)
|
||||
{
|
||||
#if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
return r_input_color[coord];
|
||||
#elif (defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)) && FFX_DOF_OPTION_COMBINE_IN_PLACE
|
||||
return rw_output_color[coord];
|
||||
#endif // #if defined(FFX_DOF_BIND_SRV_INPUT_COLOR)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)
|
||||
void FfxDofStoreOutput(FfxUInt32x2 coord, FfxFloat32x4 color)
|
||||
{
|
||||
rw_output_color[coord] = color;
|
||||
}
|
||||
#endif // #if defined(FFX_DOF_BIND_UAV_OUTPUT_COLOR)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
142
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_common.h
vendored
Normal file
142
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_common.h
vendored
Normal file
@@ -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_DOF_COMMON_H
|
||||
#define FFX_DOF_COMMON_H
|
||||
|
||||
/// @defgroup FfxGPUDof FidelityFX DOF
|
||||
/// FidelityFX Depth of Field GPU documentation
|
||||
///
|
||||
/// @ingroup FfxGPUEffects
|
||||
|
||||
// Constants - these are fixed magic numbers. Changes likely require changing code.
|
||||
|
||||
/// The width/height of tiles storing per-tile min and max CoC. The blur pass needs to run
|
||||
/// at a compatible tile size, so that the assumption that min/max CoC is uniform for all threads in
|
||||
/// a thread group holds.
|
||||
///
|
||||
/// @ingroup FfxGPUDof
|
||||
FFX_STATIC const FfxUInt32 FFX_DOF_DEPTH_TILE_SIZE = 8;
|
||||
|
||||
// Default settings
|
||||
#ifndef FFX_DOF_OPTION_MAX_MIP
|
||||
/// The number of mips that should be generated in the color downsample pass
|
||||
///
|
||||
/// @ingroup FfxGPUDof
|
||||
#define FFX_DOF_OPTION_MAX_MIP 4
|
||||
#endif
|
||||
|
||||
#ifndef FFX_DOF_OPTION_MAX_RING_MERGE_LOG
|
||||
/// The base-2 logarithm of the number of blur kernel rings that may be merged, if possible.
|
||||
///
|
||||
/// Setting this to zero disables ring merging.
|
||||
///
|
||||
/// Values above 1 are technically valid, but are known to cause a visible quality drop.
|
||||
///
|
||||
/// @ingroup FfxGPUDof
|
||||
#define FFX_DOF_OPTION_MAX_RING_MERGE_LOG 1
|
||||
#endif
|
||||
|
||||
#define FFX_DOF_MAX_RING_MERGE (1 << FFX_DOF_OPTION_MAX_RING_MERGE_LOG)
|
||||
|
||||
// optional 16-bit types
|
||||
#if FFX_HLSL
|
||||
#if FFX_HALF
|
||||
typedef FfxFloat16 FfxHalfOpt;
|
||||
typedef FfxFloat16x2 FfxHalfOpt2;
|
||||
typedef FfxFloat16x3 FfxHalfOpt3;
|
||||
typedef FfxFloat16x4 FfxHalfOpt4;
|
||||
#else
|
||||
typedef FfxFloat32 FfxHalfOpt;
|
||||
typedef FfxFloat32x2 FfxHalfOpt2;
|
||||
typedef FfxFloat32x3 FfxHalfOpt3;
|
||||
typedef FfxFloat32x4 FfxHalfOpt4;
|
||||
#endif
|
||||
#elif FFX_GLSL
|
||||
#if FFX_HALF
|
||||
#define FfxHalfOpt FfxFloat16
|
||||
#define FfxHalfOpt2 FfxFloat16x2
|
||||
#define FfxHalfOpt3 FfxFloat16x3
|
||||
#define FfxHalfOpt4 FfxFloat16x4
|
||||
#else
|
||||
#define FfxHalfOpt FfxFloat32
|
||||
#define FfxHalfOpt2 FfxFloat32x2
|
||||
#define FfxHalfOpt3 FfxFloat32x3
|
||||
#define FfxHalfOpt4 FfxFloat32x4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// unroll macros with count argument
|
||||
#if FFX_HLSL
|
||||
#define FFX_DOF_UNROLL_N(_n) [unroll(_n)]
|
||||
#define FFX_DOF_UNROLL [unroll]
|
||||
#elif FFX_GLSL // #if FFX_HLSL
|
||||
#define FFX_DOF_UNROLL_N(_n)
|
||||
// enable unrolling loops
|
||||
#extension GL_EXT_control_flow_attributes : enable
|
||||
|
||||
#if GL_EXT_control_flow_attributes
|
||||
#define FFX_DOF_UNROLL [[unroll]]
|
||||
#else
|
||||
#define FFX_DOF_UNROLL
|
||||
#endif // #if GL_EXT_control_flow_attributes
|
||||
#endif // #if FFX_HLSL #elif FFX_GLSL
|
||||
|
||||
// ReadLaneFirst
|
||||
#if FFX_HLSL
|
||||
#define ffxWaveReadLaneFirst WaveReadLaneFirst
|
||||
#elif FFX_GLSL
|
||||
#define ffxWaveReadLaneFirst subgroupBroadcastFirst
|
||||
#endif // #if FFX_GLSL
|
||||
|
||||
// Callback declarations
|
||||
FfxFloat32 FfxDofGetCoc(FfxFloat32 depth); // returns circle of confusion radius in pixels (at half-res). Sign indicates near-field (positive) or far-field (negative).
|
||||
void FfxDofStoreDilatedRadius(FfxUInt32x2 coord, FfxFloat32x2 dilatedMinMax);
|
||||
FfxFloat32x2 FfxDofSampleDilatedRadius(FfxUInt32x2 coord); // returns the dilated min and max depth for a pixel coordinate. Should be bilinearly interpolated!
|
||||
FfxFloat32x2 FfxDofLoadDilatedRadius(FfxUInt32x2 coord); // returns the dilated depth for a *tile* coordinate without interpolation
|
||||
FfxHalfOpt4 FfxDofLoadInput(FfxUInt32x2 coord); // returns input rgb and (in alpha) CoC in pixels from the most detailed mip (which is half-res)
|
||||
FfxHalfOpt4 FfxDofSampleInput(FfxFloat32x2 coord, FfxUInt32 mip); // returns input rgb and (in alpha) CoC in pixels.
|
||||
FfxFloat32x4 FfxDofGatherDepth(FfxFloat32x2 coord); // returns 4 input depth values in a quad, must use sampler with coordinate clamping
|
||||
void FfxDofStoreNear(FfxUInt32x2 coord, FfxHalfOpt4 color); // stores the near color output from the blur pass
|
||||
void FfxDofStoreFar(FfxUInt32x2 coord, FfxHalfOpt4 color); // stores the far color output from the blur pass
|
||||
FfxHalfOpt4 FfxDofLoadNear(FfxUInt32x2 coord); // loads the near color value
|
||||
FfxHalfOpt4 FfxDofLoadFar(FfxUInt32x2 coord); // loads the far color value
|
||||
void FfxDofAccumMaxTileRadius(FfxUInt32 radius); // stores the global maximum dilation radius using an atomic max operation
|
||||
FfxUInt32 FfxDofGetMaxTileRadius(); // gets the global maximum dilation radius
|
||||
void FfxDofResetMaxTileRadius(); // sets max dilation radius back to zero
|
||||
void FfxDofStoreTileRadius(FfxUInt32x2 tile, FfxFloat32x2 radius); // stores the min/max signed radius for a tile in the tile map
|
||||
FfxFloat32x2 FfxDofLoadTileRadius(FfxUInt32x2 tile); // loads the min/max depth for a tile
|
||||
FfxFloat32x4 FfxDofLoadFullInput(FfxUInt32x2 coord); // returns full resultion input rgba (alpha is ignored)
|
||||
FfxFloat32 FfxDofLoadFullDepth(FfxUInt32x2 coord); // returns full resolution depth
|
||||
void FfxDofStoreOutput(FfxUInt32x2 coord, FfxFloat32x4 color); // writes the final output
|
||||
|
||||
// Common helper functions
|
||||
FfxUInt32x2 FfxDofPxRadToTiles(FfxFloat32x2 rPx)
|
||||
{
|
||||
return FfxUInt32x2(ceil(rPx / (FFX_DOF_DEPTH_TILE_SIZE / 2))) + 1; // +1 to handle diagonals & bilinear
|
||||
}
|
||||
|
||||
FfxFloat32x2 FfxDofGetCoc2(FfxFloat32x2 depths)
|
||||
{
|
||||
return FfxFloat32x2(FfxDofGetCoc(depths.x), FfxDofGetCoc(depths.y));
|
||||
}
|
||||
#endif // #ifndef FFX_DOF_COMMON_H
|
||||
629
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_composite.h
vendored
Normal file
629
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_composite.h
vendored
Normal file
@@ -0,0 +1,629 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_dof_common.h"
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16 FfxMed9(FfxFloat16 a, FfxFloat16 b, FfxFloat16 c,
|
||||
FfxFloat16 d, FfxFloat16 e, FfxFloat16 f,
|
||||
FfxFloat16 g, FfxFloat16 h, FfxFloat16 i)
|
||||
{
|
||||
// TODO (perf): compiler does not use med3 at all for these
|
||||
FfxFloat16 hi_lo = ffxMax3Half(ffxMin3Half(a, b, c), ffxMin3Half(d, e, f), ffxMin3Half(g, h, i));
|
||||
FfxFloat16 mi_mi = ffxMed3Half(ffxMed3Half(a, b, c), ffxMed3Half(d, e, f), ffxMed3Half(g, h, i));
|
||||
FfxFloat16 lo_hi = ffxMin3Half(ffxMax3Half(a, b, c), ffxMax3Half(d, e, f), ffxMax3Half(g, h, i));
|
||||
return ffxMed3Half(hi_lo, mi_mi, lo_hi);
|
||||
}
|
||||
#endif
|
||||
|
||||
FfxFloat32 FfxMed9(FfxFloat32 a, FfxFloat32 b, FfxFloat32 c,
|
||||
FfxFloat32 d, FfxFloat32 e, FfxFloat32 f,
|
||||
FfxFloat32 g, FfxFloat32 h, FfxFloat32 i)
|
||||
{
|
||||
// TODO (perf): compiler does not use med3 at all for these
|
||||
FfxFloat32 hi_lo = ffxMax3(ffxMin3(a, b, c), ffxMin3(d, e, f), ffxMin3(g, h, i));
|
||||
FfxFloat32 mi_mi = ffxMed3(ffxMed3(a, b, c), ffxMed3(d, e, f), ffxMed3(g, h, i));
|
||||
FfxFloat32 lo_hi = ffxMin3(ffxMax3(a, b, c), ffxMax3(d, e, f), ffxMax3(g, h, i));
|
||||
return ffxMed3(hi_lo, mi_mi, lo_hi);
|
||||
}
|
||||
|
||||
FfxFloat32 FfxCubicSpline(FfxFloat32 x)
|
||||
{
|
||||
// evaluate cubic spline -2x^3 + 3x^2
|
||||
return x * x * (3 - 2 * x);
|
||||
}
|
||||
|
||||
FFX_STATIC const FfxUInt32 FFX_DOF_COMBINE_TILE_SIZE = 8;
|
||||
FFX_STATIC const FfxUInt32 FFX_DOF_COMBINE_ROW_PITCH = FFX_DOF_COMBINE_TILE_SIZE + 3; // Add +2 for 3x3 filter margin, +1 on one side for bilinear filter.
|
||||
FFX_STATIC const FfxUInt32 FFX_DOF_COMBINE_AREA = FFX_DOF_COMBINE_ROW_PITCH * FFX_DOF_COMBINE_ROW_PITCH;
|
||||
|
||||
#if FFX_HALF
|
||||
FFX_GROUPSHARED FfxUInt32 FfxDofLDSLuma[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxUInt32 FfxDofLDSNearRG[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxUInt32 FfxDofLDSNearBA[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxUInt32 FfxDofLDSFarRG[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxUInt32 FfxDofLDSFarBA[FFX_DOF_COMBINE_AREA];
|
||||
|
||||
FFX_GROUPSHARED FfxUInt32 FfxDofLDSFullColorRG[18*18];
|
||||
FFX_GROUPSHARED FfxFloat16 FfxDofLDSFullColorB[18*18];
|
||||
#else // #if FFX_HALF
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSNearLuma[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFarLuma[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSNearR[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSNearG[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSNearB[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSNearA[FFX_DOF_COMBINE_AREA];
|
||||
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFarR[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFarG[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFarB[FFX_DOF_COMBINE_AREA];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFarA[FFX_DOF_COMBINE_AREA];
|
||||
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFullColorR[18*18];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFullColorG[18*18];
|
||||
FFX_GROUPSHARED FfxFloat32 FfxDofLDSFullColorB[18*18];
|
||||
#endif // #if FFX_HALF #else
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16x4 FfxDofGetIntermediateNearColor(FfxUInt32 idx)
|
||||
{
|
||||
FfxFloat16x2 rg = FFX_UINT32_TO_FLOAT16X2(FfxDofLDSNearRG[idx]);
|
||||
FfxFloat16x2 ba = FFX_UINT32_TO_FLOAT16X2(FfxDofLDSNearBA[idx]);
|
||||
return FfxFloat16x4(rg, ba);
|
||||
}
|
||||
FfxFloat16x4 FfxDofGetIntermediateFarColor(FfxUInt32 idx)
|
||||
{
|
||||
FfxFloat16x2 rg = FFX_UINT32_TO_FLOAT16X2(FfxDofLDSFarRG[idx]);
|
||||
FfxFloat16x2 ba = FFX_UINT32_TO_FLOAT16X2(FfxDofLDSFarBA[idx]);
|
||||
return FfxFloat16x4(rg, ba);
|
||||
}
|
||||
FfxFloat16x3 FfxDofGetIntFullColor(FfxUInt32 idx)
|
||||
{
|
||||
FfxFloat16x2 rg = FFX_UINT32_TO_FLOAT16X2(FfxDofLDSFullColorRG[idx]);
|
||||
FfxFloat16 b = FfxDofLDSFullColorB[idx];
|
||||
return FfxFloat16x3(rg, b);
|
||||
}
|
||||
void FfxDofSetIntNearLuma(FfxUInt32 idx, FfxFloat16 luma)
|
||||
{
|
||||
FfxFloat16x2 unpacked = FFX_UINT32_TO_FLOAT16X2(FfxDofLDSLuma[idx]);
|
||||
unpacked.x = luma;
|
||||
FfxDofLDSLuma[idx] = FFX_FLOAT16X2_TO_UINT32(unpacked);
|
||||
}
|
||||
void FfxDofSetIntFarLuma(FfxUInt32 idx, FfxFloat16 luma)
|
||||
{
|
||||
FfxFloat16x2 unpacked = FFX_UINT32_TO_FLOAT16X2(FfxDofLDSLuma[idx]);
|
||||
unpacked.y = luma;
|
||||
FfxDofLDSLuma[idx] = FFX_FLOAT16X2_TO_UINT32(unpacked);
|
||||
}
|
||||
|
||||
void FfxDofSetIntermediateNearColor(FfxUInt32 idx, FfxFloat16x4 col)
|
||||
{
|
||||
FfxDofLDSNearRG[idx] = FFX_FLOAT16X2_TO_UINT32(col.rg);
|
||||
FfxDofLDSNearBA[idx] = FFX_FLOAT16X2_TO_UINT32(col.ba);
|
||||
}
|
||||
void FfxDofSetIntermediateFarColor(FfxUInt32 idx, FfxFloat16x4 col)
|
||||
{
|
||||
FfxDofLDSFarRG[idx] = FFX_FLOAT16X2_TO_UINT32(col.rg);
|
||||
FfxDofLDSFarBA[idx] = FFX_FLOAT16X2_TO_UINT32(col.ba);
|
||||
}
|
||||
void FfxDofSetIntFullColor(FfxUInt32 idx, FfxFloat16x3 col)
|
||||
{
|
||||
FfxDofLDSFullColorRG[idx] = FFX_FLOAT16X2_TO_UINT32(col.rg);
|
||||
FfxDofLDSFullColorB[idx] = col.b;
|
||||
}
|
||||
FfxFloat16 FfxDofGetIntermediateNearAlpha(FfxUInt32 idx, FfxUInt32 offX, FfxUInt32 offY)
|
||||
{
|
||||
return FfxDofGetIntermediateNearColor(idx + offX + FFX_DOF_COMBINE_ROW_PITCH * offY).a;
|
||||
}
|
||||
FfxFloat16 FfxDofGetIntermediateFarAlpha(FfxUInt32 idx)
|
||||
{
|
||||
return FfxDofGetIntermediateFarColor(idx).a;
|
||||
}
|
||||
#else // #if FFX_HALF
|
||||
FfxFloat32x4 FfxDofGetIntermediateNearColor(FfxUInt32 idx)
|
||||
{
|
||||
return FfxFloat32x4(FfxDofLDSNearR[idx], FfxDofLDSNearG[idx], FfxDofLDSNearB[idx], FfxDofLDSNearA[idx]);
|
||||
}
|
||||
FfxFloat32x4 FfxDofGetIntermediateFarColor(FfxUInt32 idx)
|
||||
{
|
||||
return FfxFloat32x4(FfxDofLDSFarR[idx], FfxDofLDSFarG[idx], FfxDofLDSFarB[idx], FfxDofLDSFarA[idx]);
|
||||
}
|
||||
FfxFloat32x3 FfxDofGetIntFullColor(FfxUInt32 idx)
|
||||
{
|
||||
return FfxFloat32x3(FfxDofLDSFullColorR[idx], FfxDofLDSFullColorG[idx], FfxDofLDSFullColorB[idx]);
|
||||
}
|
||||
void FfxDofSetIntNearLuma(FfxUInt32 idx, FfxFloat32 luma)
|
||||
{
|
||||
FfxDofLDSNearLuma[idx] = luma;
|
||||
}
|
||||
void FfxDofSetIntFarLuma(FfxUInt32 idx, FfxFloat32 luma)
|
||||
{
|
||||
FfxDofLDSFarLuma[idx] = luma;
|
||||
}
|
||||
|
||||
void FfxDofSetIntermediateNearColor(FfxUInt32 idx, FfxFloat32x4 col)
|
||||
{
|
||||
FfxDofLDSNearR[idx] = col.r;
|
||||
FfxDofLDSNearG[idx] = col.g;
|
||||
FfxDofLDSNearB[idx] = col.b;
|
||||
FfxDofLDSNearA[idx] = col.a;
|
||||
}
|
||||
void FfxDofSetIntermediateFarColor(FfxUInt32 idx, FfxFloat32x4 col)
|
||||
{
|
||||
FfxDofLDSFarR[idx] = col.r;
|
||||
FfxDofLDSFarG[idx] = col.g;
|
||||
FfxDofLDSFarB[idx] = col.b;
|
||||
FfxDofLDSFarA[idx] = col.a;
|
||||
}
|
||||
void FfxDofSetIntFullColor(FfxUInt32 idx, FfxFloat32x3 col)
|
||||
{
|
||||
FfxDofLDSFullColorR[idx] = col.r;
|
||||
FfxDofLDSFullColorG[idx] = col.g;
|
||||
FfxDofLDSFullColorB[idx] = col.b;
|
||||
}
|
||||
FfxFloat32 FfxDofGetIntermediateNearAlpha(FfxUInt32 idx, FfxUInt32 offX, FfxUInt32 offY)
|
||||
{
|
||||
return FfxDofGetIntermediateNearColor(idx + offX + FFX_DOF_COMBINE_ROW_PITCH * offY).a;
|
||||
}
|
||||
FfxFloat32 FfxDofGetIntermediateFarAlpha(FfxUInt32 idx)
|
||||
{
|
||||
return FfxDofGetIntermediateFarColor(idx).a;
|
||||
}
|
||||
#endif // #if FFX_HALF #else
|
||||
|
||||
FfxHalfOpt3 FfxDofBlur3x3(FfxUInt32 baseIdx)
|
||||
{
|
||||
// kernel coefficients based on coverage of a circle in a 3x3 grid
|
||||
const FfxHalfOpt CORNER = FfxHalfOpt(0.5453);
|
||||
const FfxHalfOpt SIDE = FfxHalfOpt(0.9717);
|
||||
|
||||
// accumulate convolution
|
||||
const FfxHalfOpt weights_sum = FfxHalfOpt(1) + FfxHalfOpt(4) * CORNER + FfxHalfOpt(4) * SIDE;
|
||||
FfxHalfOpt3 sum = FfxDofGetIntFullColor(baseIdx + 19)
|
||||
+ CORNER * (FfxDofGetIntFullColor(baseIdx) + FfxDofGetIntFullColor(baseIdx + 2) + FfxDofGetIntFullColor(baseIdx + 36) + FfxDofGetIntFullColor(baseIdx + 38))
|
||||
+ SIDE * (FfxDofGetIntFullColor(baseIdx + 1) + FfxDofGetIntFullColor(baseIdx + 18) + FfxDofGetIntFullColor(baseIdx + 20) + FfxDofGetIntFullColor(baseIdx + 37));
|
||||
|
||||
return sum / weights_sum;
|
||||
}
|
||||
|
||||
FfxHalfOpt4 FfxDofFinalCombineColors(FfxUInt32x2 coord, FfxUInt32x2 relCoord, FfxHalfOpt4 bg, FfxHalfOpt4 fg, FfxHalfOpt minFgW)
|
||||
{
|
||||
FfxFloat32 d = FfxDofLoadFullDepth(coord);
|
||||
FfxUInt32 baseIdx = relCoord.x + 18 * relCoord.y;
|
||||
FfxHalfOpt3 full = FfxHalfOpt3(FfxDofGetIntFullColor(baseIdx + 19));
|
||||
FfxHalfOpt3 fixBlurred = FfxHalfOpt3(FfxDofBlur3x3(baseIdx));
|
||||
|
||||
// expand background around edges
|
||||
if (bg.a > FfxHalfOpt(0)) bg.rgb /= bg.a;
|
||||
// if any FG sample has zero weight, the interpolation is invalid.
|
||||
if (minFgW == FfxHalfOpt(0)) fg.a = FfxHalfOpt(0);
|
||||
FfxHalfOpt c = FfxHalfOpt(2) * FfxHalfOpt(abs(FfxDofGetCoc(d))); // double it for full-res pixels
|
||||
FfxHalfOpt c1 = ffxSaturate(c - FfxHalfOpt(0.5)); // lerp factor for full vs. fixed 1.5px blur
|
||||
FfxHalfOpt c2 = ffxSaturate(c - FfxHalfOpt(1.5)); // lerp factor for prev vs. quarter res
|
||||
if (bg.a == FfxHalfOpt(0)) c2 = FfxHalfOpt(0);
|
||||
FfxHalfOpt3 combinedColor = ffxLerp(full, fixBlurred, c1);
|
||||
combinedColor = ffxLerp(combinedColor, bg.rgb, c2);
|
||||
|
||||
combinedColor = ffxLerp(combinedColor, fg.rgb, FfxHalfOpt(FfxCubicSpline(fg.a)));
|
||||
return FfxHalfOpt4(combinedColor, 1);
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
FfxFloat16 FfxDofGetLDSNearLuma(FfxUInt32 idx, FfxUInt32 offX, FfxUInt32 offY)
|
||||
{
|
||||
return FFX_UINT32_TO_FLOAT16X2(FfxDofLDSLuma[idx + offX + FFX_DOF_COMBINE_ROW_PITCH * offY]).x;
|
||||
}
|
||||
FfxFloat16 FfxDofGetLDSFarLuma(FfxUInt32 idx, FfxUInt32 offX, FfxUInt32 offY)
|
||||
{
|
||||
return FFX_UINT32_TO_FLOAT16X2(FfxDofLDSLuma[idx + offX + FFX_DOF_COMBINE_ROW_PITCH * offY]).y;
|
||||
}
|
||||
#else // #if FFX_HALF
|
||||
FfxFloat32 FfxDofGetLDSNearLuma(FfxUInt32 idx, FfxUInt32 offX, FfxUInt32 offY)
|
||||
{
|
||||
return FfxDofLDSNearLuma[idx + offX + FFX_DOF_COMBINE_ROW_PITCH * offY];
|
||||
}
|
||||
FfxFloat32 FfxDofGetLDSFarLuma(FfxUInt32 idx, FfxUInt32 offX, FfxUInt32 offY)
|
||||
{
|
||||
return FfxDofLDSFarLuma[idx + offX + FFX_DOF_COMBINE_ROW_PITCH * offY];
|
||||
}
|
||||
#endif // #if FFX_HALF #else
|
||||
|
||||
FfxHalfOpt4 FfxDofFilterFF(FfxUInt32 baseIdx)
|
||||
{
|
||||
// get the median of the surrounding 3x3 area of luma values
|
||||
FfxHalfOpt med_luma = FfxMed9(
|
||||
FfxDofGetLDSFarLuma(baseIdx, 0, 0), FfxDofGetLDSFarLuma(baseIdx, 1, 0), FfxDofGetLDSFarLuma(baseIdx, 2, 0),
|
||||
FfxDofGetLDSFarLuma(baseIdx, 0, 1), FfxDofGetLDSFarLuma(baseIdx, 1, 1), FfxDofGetLDSFarLuma(baseIdx, 2, 1),
|
||||
FfxDofGetLDSFarLuma(baseIdx, 0, 2), FfxDofGetLDSFarLuma(baseIdx, 1, 2), FfxDofGetLDSFarLuma(baseIdx, 2, 2));
|
||||
|
||||
FfxUInt32 idx = baseIdx + FFX_DOF_COMBINE_ROW_PITCH + 1;
|
||||
FfxHalfOpt3 col = FfxDofGetIntermediateFarColor(idx).rgb;
|
||||
FfxHalfOpt lumaFactor = clamp(med_luma / FfxDofGetLDSFarLuma(idx, 0, 0), FfxHalfOpt(0), FfxHalfOpt(2));
|
||||
// corner fix: if color pixel is on a corner (has 5 black pixels as neighbor), don't reduce color.
|
||||
if (med_luma == FfxHalfOpt(0)) lumaFactor = FfxHalfOpt(1);
|
||||
return FfxHalfOpt4(col * lumaFactor, FfxDofGetIntermediateFarAlpha(idx));
|
||||
}
|
||||
|
||||
FfxHalfOpt4 FfxDofFilterNF(FfxUInt32 baseIdx)
|
||||
{
|
||||
// Get 3x3 median luma
|
||||
FfxHalfOpt med_luma = FfxMed9(
|
||||
FfxDofGetLDSNearLuma(baseIdx, 0, 0), FfxDofGetLDSNearLuma(baseIdx, 1, 0), FfxDofGetLDSNearLuma(baseIdx, 2, 0),
|
||||
FfxDofGetLDSNearLuma(baseIdx, 0, 1), FfxDofGetLDSNearLuma(baseIdx, 1, 1), FfxDofGetLDSNearLuma(baseIdx, 2, 1),
|
||||
FfxDofGetLDSNearLuma(baseIdx, 0, 2), FfxDofGetLDSNearLuma(baseIdx, 1, 2), FfxDofGetLDSNearLuma(baseIdx, 2, 2));
|
||||
FfxHalfOpt avg_alpha = FfxHalfOpt(ffxReciprocal(9.0)) * (
|
||||
FfxDofGetIntermediateNearAlpha(baseIdx, 0, 0) + FfxDofGetIntermediateNearAlpha(baseIdx, 1, 0) + FfxDofGetIntermediateNearAlpha(baseIdx, 2, 0) +
|
||||
FfxDofGetIntermediateNearAlpha(baseIdx, 0, 1) + FfxDofGetIntermediateNearAlpha(baseIdx, 1, 1) + FfxDofGetIntermediateNearAlpha(baseIdx, 2, 1) +
|
||||
FfxDofGetIntermediateNearAlpha(baseIdx, 0, 2) + FfxDofGetIntermediateNearAlpha(baseIdx, 1, 2) + FfxDofGetIntermediateNearAlpha(baseIdx, 2, 2));
|
||||
|
||||
FfxUInt32 idx = baseIdx + FFX_DOF_COMBINE_ROW_PITCH + 1;
|
||||
if (FfxDofGetIntermediateNearAlpha(idx, 0, 0) < 0.01)
|
||||
{
|
||||
// center has zero weight, grab one of the corner colors
|
||||
FfxUInt32 maxIdx = baseIdx;
|
||||
if (FfxDofGetLDSNearLuma(baseIdx, 2, 0) > FfxDofGetLDSNearLuma(maxIdx, 0, 0)) maxIdx = baseIdx + 2;
|
||||
if (FfxDofGetLDSNearLuma(baseIdx, 0, 2) > FfxDofGetLDSNearLuma(maxIdx, 0, 0)) maxIdx = baseIdx + 2 * FFX_DOF_COMBINE_ROW_PITCH;
|
||||
if (FfxDofGetLDSNearLuma(baseIdx, 2, 2) > FfxDofGetLDSNearLuma(maxIdx, 0, 0)) maxIdx = baseIdx + 2 * FFX_DOF_COMBINE_ROW_PITCH + 2;
|
||||
idx = maxIdx;
|
||||
}
|
||||
FfxHalfOpt3 col = FfxDofGetIntermediateNearColor(idx).rgb;
|
||||
FfxHalfOpt lumaFactor = med_luma > FfxHalfOpt(0) ? clamp(med_luma / FfxDofGetLDSNearLuma(idx, 0, 0), FfxHalfOpt(0), FfxHalfOpt(2)) : FfxHalfOpt(1.0);
|
||||
return FfxHalfOpt4(col.rgb * lumaFactor, avg_alpha);
|
||||
}
|
||||
|
||||
FfxFloat32x2 FfxDofGetTileRadius(FfxUInt32x2 group)
|
||||
{
|
||||
// need to read 4 values
|
||||
FfxUInt32x2 tile = group * 2;
|
||||
FfxFloat32x2 a = FfxDofLoadDilatedRadius(tile);
|
||||
FfxFloat32x2 b = FfxDofLoadDilatedRadius(tile + FfxUInt32x2(0, 1));
|
||||
FfxFloat32x2 c = FfxDofLoadDilatedRadius(tile + FfxUInt32x2(1, 0));
|
||||
FfxFloat32x2 d = FfxDofLoadDilatedRadius(tile + FfxUInt32x2(1, 1));
|
||||
FfxFloat32 near = max(a.x, ffxMax3(b.x, c.x, d.x));
|
||||
FfxFloat32 far = min(a.y, ffxMin3(b.y, c.y, d.y));
|
||||
return FfxFloat32x2(near, far);
|
||||
}
|
||||
|
||||
void FfxDofCombineSharpOnly(FfxUInt32x2 group, FfxUInt32x2 thread)
|
||||
{
|
||||
#if !defined(FFX_DOF_OPTION_COMBINE_IN_PLACE) || !FFX_DOF_OPTION_COMBINE_IN_PLACE
|
||||
FfxUInt32x2 base = 16 * group;
|
||||
FfxDofStoreOutput(base + thread + FfxUInt32x2(0, 0), FfxDofLoadFullInput(base + thread + FfxUInt32x2(0, 0)));
|
||||
FfxDofStoreOutput(base + thread + FfxUInt32x2(8, 0), FfxDofLoadFullInput(base + thread + FfxUInt32x2(8, 0)));
|
||||
FfxDofStoreOutput(base + thread + FfxUInt32x2(0, 8), FfxDofLoadFullInput(base + thread + FfxUInt32x2(0, 8)));
|
||||
FfxDofStoreOutput(base + thread + FfxUInt32x2(8, 8), FfxDofLoadFullInput(base + thread + FfxUInt32x2(8, 8)));
|
||||
#endif
|
||||
}
|
||||
|
||||
void FfxDofFetchFullColor(FfxUInt32x2 gid, FfxUInt32 gix, FfxUInt32x2 imageSize)
|
||||
{
|
||||
FFX_DOF_UNROLL
|
||||
for (FfxUInt32 iter = 0; iter < 6; iter++)
|
||||
{
|
||||
FfxUInt32 iFetch = (gix + iter * 64) % (18 * 18);
|
||||
FfxInt32x2 coord = FfxInt32x2(gid * 16) + FfxInt32x2(iFetch % 18 - 1, iFetch / 18 - 1);
|
||||
coord = clamp(coord, FfxInt32x2(0, 0), FfxInt32x2(imageSize) - FfxInt32x2(1, 1));
|
||||
FfxHalfOpt3 color = FfxHalfOpt3(FfxDofLoadFullInput(coord).rgb);
|
||||
FfxDofSetIntFullColor(iFetch, color);
|
||||
}
|
||||
}
|
||||
|
||||
void FfxDofSwizQuad(inout FfxUInt32x2 a, inout FfxUInt32x2 b, inout FfxUInt32x2 c, inout FfxUInt32x2 d)
|
||||
{
|
||||
// Input: four color values in a quad.
|
||||
// Re-orders the output to a swizzled format for better store throughput.
|
||||
// This maps from one quad per lane, stored in four separate registers to
|
||||
// four 16x2 regions (one per register).
|
||||
// This is done in two steps. First, permute the values among the lanes
|
||||
// using WaveReadLaneAt. Second, swap values between registers.
|
||||
|
||||
// This only works for lane counts >= 32, do nothing otherwise for compatibility
|
||||
#if FFX_HLSL
|
||||
if (WaveGetLaneCount() < 32) return;
|
||||
|
||||
FfxUInt32 lane = WaveGetLaneIndex();
|
||||
// index for A, switch bits around 43210 -> 10432.
|
||||
FfxUInt32 idxA = ((lane & 3) << 3) + (lane >> 2);
|
||||
// Adding 8/16/24 for B/C/D makes each variable offset from the previous by one slot.
|
||||
a = WaveReadLaneAt(a, (lane & ~31) + (idxA + 0) % 32);
|
||||
b = WaveReadLaneAt(b, (lane & ~31) + (idxA + 8) % 32);
|
||||
c = WaveReadLaneAt(c, (lane & ~31) + (idxA + 16) % 32);
|
||||
d = WaveReadLaneAt(d, (lane & ~31) + (idxA + 24) % 32);
|
||||
#elif FFX_GLSL
|
||||
if (gl_SubgroupSize < 32) return;
|
||||
|
||||
FfxUInt32 lane = gl_SubgroupInvocationID;
|
||||
FfxUInt32 idxA = ((lane & 3) << 3) + (lane >> 2);
|
||||
a = subgroupShuffle(a, (lane & ~31) + (idxA + 0) % 32);
|
||||
b = subgroupShuffle(b, (lane & ~31) + (idxA + 8) % 32);
|
||||
c = subgroupShuffle(c, (lane & ~31) + (idxA + 16) % 32);
|
||||
d = subgroupShuffle(d, (lane & ~31) + (idxA + 24) % 32);
|
||||
#endif
|
||||
|
||||
// Now, for each lane, a/b/c/d contain one value from each of the four 16x2 lines.
|
||||
// And each group of 4 lanes have values from the same quads.
|
||||
// We just need to shuffle between abcd, so that each set of 4 lanes contains one quad per variable.
|
||||
// General idea: rotate by (lane % 4) variables.
|
||||
if ((lane & 1) != 0)
|
||||
{
|
||||
// rotate A->B->C->D->A
|
||||
FfxUInt32x2 tmp = d;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = tmp;
|
||||
}
|
||||
if ((lane & 2) != 0)
|
||||
{
|
||||
// swap A<->C and B<->D
|
||||
FfxUInt32x2 tmp = a;
|
||||
a = c;
|
||||
c = tmp;
|
||||
tmp = b;
|
||||
b = d;
|
||||
d = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
#if FFX_HALF
|
||||
void FfxDofSwizQuad(inout FfxFloat16x4 a, inout FfxFloat16x4 b, inout FfxFloat16x4 c, inout FfxFloat16x4 d)
|
||||
{
|
||||
// Same as above.
|
||||
FfxUInt32x2 packed_a = FFX_FLOAT16X4_TO_UINT32X2(a);
|
||||
FfxUInt32x2 packed_b = FFX_FLOAT16X4_TO_UINT32X2(b);
|
||||
FfxUInt32x2 packed_c = FFX_FLOAT16X4_TO_UINT32X2(c);
|
||||
FfxUInt32x2 packed_d = FFX_FLOAT16X4_TO_UINT32X2(d);
|
||||
FfxDofSwizQuad(packed_a, packed_b, packed_c, packed_d);
|
||||
a = FFX_UINT32X2_TO_FLOAT16X4(packed_a);
|
||||
b = FFX_UINT32X2_TO_FLOAT16X4(packed_b);
|
||||
c = FFX_UINT32X2_TO_FLOAT16X4(packed_c);
|
||||
d = FFX_UINT32X2_TO_FLOAT16X4(packed_d);
|
||||
}
|
||||
#else // #if FFX_HALF
|
||||
void FfxDofSwizQuad(inout FfxFloat32x4 a, inout FfxFloat32x4 b, inout FfxFloat32x4 c, inout FfxFloat32x4 d)
|
||||
{
|
||||
// Same as above.
|
||||
FfxUInt32x2 a0 = ffxAsUInt32(a.xy);
|
||||
FfxUInt32x2 a1 = ffxAsUInt32(a.zw);
|
||||
FfxUInt32x2 b0 = ffxAsUInt32(b.xy);
|
||||
FfxUInt32x2 b1 = ffxAsUInt32(b.zw);
|
||||
FfxUInt32x2 c0 = ffxAsUInt32(c.xy);
|
||||
FfxUInt32x2 c1 = ffxAsUInt32(c.zw);
|
||||
FfxUInt32x2 d0 = ffxAsUInt32(d.xy);
|
||||
FfxUInt32x2 d1 = ffxAsUInt32(d.zw);
|
||||
FfxDofSwizQuad(a0, b0, c0, d0);
|
||||
FfxDofSwizQuad(a1, b1, c1, d1);
|
||||
a = FfxFloat32x4(ffxAsFloat(a0), ffxAsFloat(a1));
|
||||
b = FfxFloat32x4(ffxAsFloat(b0), ffxAsFloat(b1));
|
||||
c = FfxFloat32x4(ffxAsFloat(c0), ffxAsFloat(c1));
|
||||
d = FfxFloat32x4(ffxAsFloat(d0), ffxAsFloat(d1));
|
||||
}
|
||||
#endif // #if FFX_HALF #else
|
||||
|
||||
void FfxDofCombineFarOnly(FfxUInt32x2 id, FfxUInt32x2 gtID, FfxUInt32x2 gid, FfxUInt32 gix, FfxUInt32x2 imageSize)
|
||||
{
|
||||
// TODO: Is this the best configuration for fetching?
|
||||
FFX_DOF_UNROLL_N(2)
|
||||
for (FfxUInt32 iter = 0; iter < 2; iter++)
|
||||
{
|
||||
// HACK: with the modulo, we will re-fetch some pixels, but might be better than waiting twice (latency-wise)
|
||||
// which is what the compiler would do if it had to possibly branch
|
||||
FfxUInt32 iFetch = (gix + iter * 64) % FFX_DOF_COMBINE_AREA;
|
||||
FfxInt32x2 coord = FfxInt32x2(gid * FFX_DOF_COMBINE_TILE_SIZE) + FfxInt32x2(iFetch % FFX_DOF_COMBINE_ROW_PITCH - 1, iFetch / FFX_DOF_COMBINE_ROW_PITCH - 1);
|
||||
coord = clamp(coord, FfxInt32x2(0, 0), FfxInt32x2(imageSize - 1));
|
||||
FfxHalfOpt4 ffColor = FfxHalfOpt4(FfxDofLoadFar(coord));
|
||||
|
||||
// calculate and store luma for later median calculation
|
||||
FfxHalfOpt ffLuma = FfxHalfOpt(0.2126) * ffColor.r + FfxHalfOpt(0.7152) * ffColor.g + FfxHalfOpt(0.0722) * ffColor.b;
|
||||
FfxDofSetIntFarLuma(iFetch, ffLuma);
|
||||
FfxDofSetIntermediateFarColor(iFetch, ffColor);
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
const FfxUInt32 baseIdx = gtID.x + gtID.y * FFX_DOF_COMBINE_ROW_PITCH;
|
||||
// one extra round of filtering needs to be done around the edge, this index maps to that.
|
||||
// TODO: This is ugly and possibly slow
|
||||
const FfxUInt32 baseIdx2 = (FFX_DOF_COMBINE_TILE_SIZE + FFX_DOF_COMBINE_ROW_PITCH * gix + (gix / (FFX_DOF_COMBINE_TILE_SIZE + 1)) * ((gix - FFX_DOF_COMBINE_TILE_SIZE) * (-FFX_DOF_COMBINE_ROW_PITCH + 1) - (FFX_DOF_COMBINE_TILE_SIZE + 1))) % FFX_DOF_COMBINE_AREA;
|
||||
|
||||
FfxHalfOpt4 ffColor = FfxHalfOpt4(0, 0, 0, 0), ffColor2 = FfxHalfOpt4(0, 0, 0, 0);
|
||||
// far-field post-filter
|
||||
ffColor = FfxDofFilterFF(baseIdx);
|
||||
ffColor2 = gix < (2 * FFX_DOF_COMBINE_TILE_SIZE + 1) ? FfxDofFilterFF(baseIdx2) : FfxHalfOpt4(0, 0, 0, 0);
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// write out colors for interpolation
|
||||
FfxDofSetIntermediateFarColor(baseIdx, ffColor);
|
||||
if (gix < (2 * FFX_DOF_COMBINE_TILE_SIZE + 1))
|
||||
{
|
||||
FfxDofSetIntermediateFarColor(baseIdx2, ffColor2);
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// upscaling
|
||||
FfxHalfOpt4 ffTR = FfxHalfOpt4(0, 0, 0, 0), ffBL = FfxHalfOpt4(0, 0, 0, 0), ffBR = FfxHalfOpt4(0, 0, 0, 0);
|
||||
ffTR = FfxHalfOpt(0.5) * ffColor + FfxHalfOpt(0.5) * FfxDofGetIntermediateFarColor(baseIdx + 1);
|
||||
ffBL = FfxHalfOpt(0.5) * ffColor + FfxHalfOpt(0.5) * FfxDofGetIntermediateFarColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH);
|
||||
ffBR = FfxHalfOpt(0.5) * ffTR + FfxHalfOpt(0.25) * FfxDofGetIntermediateFarColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH) + FfxHalfOpt(0.25) * FfxDofGetIntermediateFarColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH + 1);
|
||||
|
||||
// top-left pixel
|
||||
FfxUInt32x2 coord = 2 * id;
|
||||
FfxUInt32x2 relCoord = 2 * gtID;
|
||||
FfxUInt32x2 coordA = coord;
|
||||
FfxHalfOpt4 colA = FfxDofFinalCombineColors(coord, relCoord, ffColor, FfxHalfOpt4(0, 0, 0, 0), FfxHalfOpt(0));
|
||||
// top-right
|
||||
coord.x++;
|
||||
relCoord.x++;
|
||||
FfxUInt32x2 coordB = coord;
|
||||
FfxHalfOpt4 colB = FfxDofFinalCombineColors(coord, relCoord, ffTR, FfxHalfOpt4(0, 0, 0, 0), FfxHalfOpt(0));
|
||||
// bottom-right
|
||||
coord.y++;
|
||||
relCoord.y++;
|
||||
FfxUInt32x2 coordC = coord;
|
||||
FfxHalfOpt4 colC = FfxDofFinalCombineColors(coord, relCoord, ffBR, FfxHalfOpt4(0, 0, 0, 0), FfxHalfOpt(0));
|
||||
// bottom-left
|
||||
coord.x--;
|
||||
relCoord.x--;
|
||||
FfxUInt32x2 coordD = coord;
|
||||
FfxHalfOpt4 colD = FfxDofFinalCombineColors(coord, relCoord, ffBL, FfxHalfOpt4(0, 0, 0, 0), FfxHalfOpt(0));
|
||||
|
||||
// TODO: Navi3 should make swizzling unnecessary because it supports write-combining clauses
|
||||
FfxDofSwizQuad(colA, colB, colC, colD);
|
||||
FfxDofSwizQuad(coordA, coordB, coordC, coordD);
|
||||
|
||||
FfxDofStoreOutput(coordA, colA);
|
||||
FfxDofStoreOutput(coordB, colB);
|
||||
FfxDofStoreOutput(coordC, colC);
|
||||
FfxDofStoreOutput(coordD, colD);
|
||||
}
|
||||
|
||||
void FfxDofCombineAll(FfxUInt32x2 id, FfxUInt32x2 gtID, FfxUInt32x2 gid, FfxUInt32 gix, FfxUInt32x2 imageSize)
|
||||
{
|
||||
// TODO: Is this the best configuration for fetching?
|
||||
FFX_DOF_UNROLL_N(2)
|
||||
for (FfxUInt32 iter = 0; iter < 2; iter++)
|
||||
{
|
||||
// HACK: with the modulo, we will re-fetch some pixels, but might be better than waiting twice (latency-wise)
|
||||
// which is what the compiler would do if it had to possibly branch
|
||||
FfxUInt32 iFetch = (gix + iter * 64) % FFX_DOF_COMBINE_AREA;
|
||||
FfxInt32x2 coord = FfxInt32x2(gid * FFX_DOF_COMBINE_TILE_SIZE) + FfxInt32x2(iFetch % FFX_DOF_COMBINE_ROW_PITCH - 1, iFetch / FFX_DOF_COMBINE_ROW_PITCH - 1);
|
||||
coord = clamp(coord, FfxInt32x2(0, 0), FfxInt32x2(imageSize - 1));
|
||||
FfxHalfOpt4 ffColor = FfxHalfOpt4(FfxDofLoadFar(coord));
|
||||
FfxHalfOpt4 nfColor = FfxHalfOpt4(FfxDofLoadNear(coord));
|
||||
|
||||
// calculate and store luma for later median calculation
|
||||
FfxHalfOpt ffLuma = FfxHalfOpt(0.2126) * ffColor.r + FfxHalfOpt(0.7152) * ffColor.g + FfxHalfOpt(0.0722) * ffColor.b;
|
||||
FfxHalfOpt nfLuma = FfxHalfOpt(0.2126) * nfColor.r + FfxHalfOpt(0.7152) * nfColor.g + FfxHalfOpt(0.0722) * nfColor.b;
|
||||
FfxDofSetIntFarLuma(iFetch, ffLuma);
|
||||
FfxDofSetIntNearLuma(iFetch, nfLuma);
|
||||
FfxDofSetIntermediateFarColor(iFetch, ffColor);
|
||||
FfxDofSetIntermediateNearColor(iFetch, nfColor);
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
const FfxUInt32 baseIdx = gtID.x + gtID.y * FFX_DOF_COMBINE_ROW_PITCH;
|
||||
// one extra round of filtering needs to be done around the edge, this index maps to that.
|
||||
// TODO: same as above, ugly and slow.
|
||||
const FfxUInt32 baseIdx2 = (FFX_DOF_COMBINE_TILE_SIZE + FFX_DOF_COMBINE_ROW_PITCH * gix + (gix / (FFX_DOF_COMBINE_TILE_SIZE + 1)) * ((gix - FFX_DOF_COMBINE_TILE_SIZE) * (-FFX_DOF_COMBINE_ROW_PITCH + 1) - (FFX_DOF_COMBINE_TILE_SIZE + 1))) % FFX_DOF_COMBINE_AREA;
|
||||
|
||||
FfxHalfOpt4 ffColor = FfxHalfOpt4(0, 0, 0, 0), ffColor2 = FfxHalfOpt4(0, 0, 0, 0), nfColor = FfxHalfOpt4(0, 0, 0, 0), nfColor2 = FfxHalfOpt4(0, 0, 0, 0);
|
||||
// far-field post-filter
|
||||
ffColor = FfxDofFilterFF(baseIdx);
|
||||
ffColor2 = gix < (2 * FFX_DOF_COMBINE_TILE_SIZE + 1) ? FfxDofFilterFF(baseIdx2) : FfxHalfOpt4(0, 0, 0, 0);
|
||||
|
||||
// near-field post-filter
|
||||
nfColor = FfxDofFilterNF(baseIdx);
|
||||
nfColor2 = gix < (2 * FFX_DOF_COMBINE_TILE_SIZE + 1) ? FfxDofFilterNF(baseIdx2) : FfxHalfOpt4(0, 0, 0, 0);
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// write out colors for interpolation
|
||||
FfxDofSetIntermediateNearColor(baseIdx, nfColor);
|
||||
FfxDofSetIntermediateFarColor(baseIdx, ffColor);
|
||||
if (gix < (2 * FFX_DOF_COMBINE_TILE_SIZE + 1))
|
||||
{
|
||||
FfxDofSetIntermediateNearColor(baseIdx2, nfColor2);
|
||||
FfxDofSetIntermediateFarColor(baseIdx2, ffColor2);
|
||||
}
|
||||
|
||||
FFX_GROUP_MEMORY_BARRIER;
|
||||
|
||||
// if any FG sample has zero weight, the interpolation is invalid.
|
||||
// take the min and invalidate if zero (see CombineColors)
|
||||
FfxHalfOpt fgMinW = min(nfColor.a, FfxHalfOpt(ffxMin3(FfxDofGetIntermediateNearAlpha(baseIdx, 1, 0), FfxDofGetIntermediateNearAlpha(baseIdx, 0, 1), FfxDofGetIntermediateNearAlpha(baseIdx, 1, 1))));
|
||||
|
||||
// upscaling
|
||||
FfxHalfOpt4 nfTR = FfxHalfOpt4(0, 0, 0, 0), nfBL = FfxHalfOpt4(0, 0, 0, 0), nfBR = FfxHalfOpt4(0, 0, 0, 0);
|
||||
nfTR = FfxHalfOpt(0.5) * nfColor + FfxHalfOpt(0.5) * FfxDofGetIntermediateNearColor(baseIdx + 1);
|
||||
nfBL = FfxHalfOpt(0.5) * nfColor + FfxHalfOpt(0.5) * FfxDofGetIntermediateNearColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH);
|
||||
nfBR = FfxHalfOpt(0.5) * nfTR + FfxHalfOpt(0.25) * FfxDofGetIntermediateNearColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH) + FfxHalfOpt(0.25) * FfxDofGetIntermediateNearColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH + 1);
|
||||
|
||||
FfxHalfOpt4 ffTR = FfxHalfOpt4(0, 0, 0, 0), ffBL = FfxHalfOpt4(0, 0, 0, 0), ffBR = FfxHalfOpt4(0, 0, 0, 0);
|
||||
ffTR = FfxHalfOpt(0.5) * ffColor + FfxHalfOpt(0.5) * FfxDofGetIntermediateFarColor(baseIdx + 1);
|
||||
ffBL = FfxHalfOpt(0.5) * ffColor + FfxHalfOpt(0.5) * FfxDofGetIntermediateFarColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH);
|
||||
ffBR = FfxHalfOpt(0.5) * ffTR + FfxHalfOpt(0.25) * FfxDofGetIntermediateFarColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH) + FfxHalfOpt(0.25) * FfxDofGetIntermediateFarColor(baseIdx + FFX_DOF_COMBINE_ROW_PITCH + 1);
|
||||
|
||||
// top-left pixel
|
||||
FfxUInt32x2 coord = 2 * id;
|
||||
FfxUInt32x2 relCoord = 2 * gtID;
|
||||
FfxUInt32x2 coordA = coord;
|
||||
FfxHalfOpt4 colA = FfxDofFinalCombineColors(coord, relCoord, ffColor, nfColor, fgMinW);
|
||||
// top-right
|
||||
coord.x += 1;
|
||||
relCoord.x += 1;
|
||||
FfxUInt32x2 coordB = coord;
|
||||
FfxHalfOpt4 colB = FfxDofFinalCombineColors(coord, relCoord, ffTR, nfTR, fgMinW);
|
||||
// bottom-right
|
||||
coord.y++;
|
||||
relCoord.y++;
|
||||
FfxUInt32x2 coordC = coord;
|
||||
FfxHalfOpt4 colC = FfxDofFinalCombineColors(coord, relCoord, ffBR, nfBR, fgMinW);
|
||||
// bottom-left
|
||||
coord.x--;
|
||||
relCoord.x--;
|
||||
FfxUInt32x2 coordD = coord;
|
||||
FfxHalfOpt4 colD = FfxDofFinalCombineColors(coord, relCoord, ffBL, nfBL, fgMinW);
|
||||
|
||||
FfxDofSwizQuad(colA, colB, colC, colD);
|
||||
FfxDofSwizQuad(coordA, coordB, coordC, coordD);
|
||||
|
||||
FfxDofStoreOutput(coordA, colA);
|
||||
FfxDofStoreOutput(coordB, colB);
|
||||
FfxDofStoreOutput(coordC, colC);
|
||||
FfxDofStoreOutput(coordD, colD);
|
||||
}
|
||||
|
||||
/// Entry point. Meant to run in 8x8 threads and writes 16x16 output pixels.
|
||||
///
|
||||
/// @param threadID SV_DispatchThreadID.xy
|
||||
/// @param groupThreadID SV_GroupThreadID.xy
|
||||
/// @param group SV_GroupID.xy
|
||||
/// @param index SV_GroupIndex
|
||||
/// @param halfImageSize Pixel size of the input (half resolution)
|
||||
/// @param fullImageSize Pixel size of the output (full resolution)
|
||||
/// @ingroup FfxGPUDof
|
||||
void FfxDofCombineHalfRes(FfxUInt32x2 threadID, FfxUInt32x2 groupThreadID, FfxUInt32x2 group, FfxUInt32 index, FfxUInt32x2 halfImageSize, FfxUInt32x2 fullImageSize)
|
||||
{
|
||||
// classify tile
|
||||
FfxFloat32x2 tileCoc = FfxDofGetTileRadius(group);
|
||||
FfxBoolean nearNeeded = tileCoc.x > -1.025; // halved due to resolution change, then: 2px = threshold in main pass + small inaccuracy bias
|
||||
FfxBoolean allSharp = max(abs(tileCoc.x), abs(tileCoc.y)) < 0.25;
|
||||
|
||||
if (allSharp)
|
||||
{
|
||||
FfxDofCombineSharpOnly(group, groupThreadID);
|
||||
}
|
||||
else if (!nearNeeded)
|
||||
{
|
||||
FfxDofFetchFullColor(group, index, fullImageSize);
|
||||
FfxDofCombineFarOnly(threadID, groupThreadID, group, index, halfImageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
FfxDofFetchFullColor(group, index, fullImageSize);
|
||||
FfxDofCombineAll(threadID, groupThreadID, group, index, halfImageSize);
|
||||
}
|
||||
}
|
||||
101
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_dilate_depth.h
vendored
Normal file
101
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_dilate_depth.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_dof_common.h"
|
||||
|
||||
// helper function for dilating depth values circularly
|
||||
void FfxDofDilateStep(inout FfxFloat32 cMin, inout FfxFloat32 cMax, FfxInt32 x, FfxInt32 y, FfxInt32 r, FfxUInt32x2 size, FfxUInt32x2 dtID)
|
||||
{
|
||||
if (x * x + y * y <= r * r)
|
||||
{
|
||||
// inside the circle
|
||||
FfxInt32x2 tileID = FfxInt32x2(dtID) + FfxInt32x2(x, y);
|
||||
if (tileID.x >= 0 && tileID.y >= 0 && tileID.x < size.x && tileID.y < size.y)
|
||||
{
|
||||
FfxFloat32x2 localCocRange = FfxDofLoadTileRadius(tileID);
|
||||
FfxUInt32x2 tileRad = FfxDofPxRadToTiles(abs(localCocRange));
|
||||
|
||||
// seperately for min/max: check radius in range to spread and update
|
||||
if (x * x + y * y < tileRad.x * tileRad.x)
|
||||
{
|
||||
// using max for cMin and min for cMax, since cMin actually refers to the CoC for the minimal view depth
|
||||
// NOT the minimum signed CoC value
|
||||
cMin = max(cMin, localCocRange.x);
|
||||
}
|
||||
if (x * x + y * y < tileRad.y * tileRad.y)
|
||||
{
|
||||
cMax = min(cMax, localCocRange.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Entry point for the dilate pass.
|
||||
///
|
||||
/// @param tile Coordinate of the tile to run on (SV_DispatchThreadID)
|
||||
/// @param imageSize Resolution of the depth image (full resolution)
|
||||
/// @ingroup FfxGPUDof
|
||||
void FfxDofDilate(FfxUInt32x2 tile, FfxUInt32x2 imageSize)
|
||||
{
|
||||
// dilate scatter-as-gather using global max radius
|
||||
|
||||
// reject out-of-bounds on border
|
||||
FfxUInt32x2 size = FfxUInt32x2(ceil(FfxFloat32x2(imageSize) / FfxFloat32(FFX_DOF_DEPTH_TILE_SIZE)));
|
||||
|
||||
// get CoC and depth
|
||||
FfxInt32 rMax = FfxInt32(FfxDofGetMaxTileRadius());
|
||||
FfxFloat32x2 cocMinMax = FfxDofLoadTileRadius(tile);
|
||||
FfxFloat32x2 absCocMinMax = abs(cocMinMax);
|
||||
|
||||
FfxFloat32 cMin = cocMinMax.x;
|
||||
FfxFloat32 cMax = cocMinMax.y;
|
||||
|
||||
// Very extremes of the kernel done explicity. Expanding the square (loop below) to this radius would
|
||||
// waste time with a lot of failed radius checks.
|
||||
if (rMax > 0)
|
||||
{
|
||||
FfxDofDilateStep(cMin, cMax, -rMax, 0, rMax, size, tile);
|
||||
FfxDofDilateStep(cMin, cMax, rMax, 0, rMax, size, tile);
|
||||
FfxDofDilateStep(cMin, cMax, 0, -rMax, rMax, size, tile);
|
||||
FfxDofDilateStep(cMin, cMax, 0, rMax, rMax, size, tile);
|
||||
}
|
||||
// Gather the rest as a square shape. Likely faster than trying to make a circle.
|
||||
for (FfxInt32 x = -rMax + 1; x < rMax; x++)
|
||||
{
|
||||
for (FfxInt32 y = -rMax + 1; y < rMax; y++)
|
||||
{
|
||||
// Zero offset is the starting point, don't need to handle again.
|
||||
if (x == 0 && y == 0) continue;
|
||||
FfxDofDilateStep(cMin, cMax, x, y, rMax, size, tile);
|
||||
}
|
||||
}
|
||||
|
||||
// If center tile is in-focus enough: ignore far-field dilation (it is occluded).
|
||||
if (absCocMinMax.x < 0.5 && absCocMinMax.y < 0.5)
|
||||
{
|
||||
cMax = cocMinMax.y;
|
||||
}
|
||||
|
||||
// store min and max
|
||||
FfxDofStoreDilatedRadius(tile, FfxFloat32x2(cMin, cMax));
|
||||
}
|
||||
176
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_downsample_color.h
vendored
Normal file
176
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_downsample_color.h
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
// 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_core.h"
|
||||
|
||||
#ifndef FFX_DOF_OPTION_MAX_MIP
|
||||
#define FFX_DOF_OPTION_MAX_MIP FFX_DOF_INTERNAL_BILAT_MIP_COUNT
|
||||
#endif
|
||||
|
||||
#if FFX_HALF
|
||||
#define FFX_SPD_PACKED_ONLY
|
||||
|
||||
FFX_GROUPSHARED FfxFloat16x2 spdIntermediateRG[16][16];
|
||||
FFX_GROUPSHARED FfxFloat16x2 spdIntermediateBA[16][16];
|
||||
|
||||
FfxFloat16x4 SpdLoadSourceImageH(FfxInt32x2 tex, FfxUInt32 slice)
|
||||
{
|
||||
FfxFloat16 d = FfxFloat16(FfxDofLoadFullDepth(tex));
|
||||
FfxFloat16 c = FfxFloat16(FfxDofGetCoc(d));
|
||||
return FfxFloat16x4(FfxDofLoadSource(tex).rgb, c);
|
||||
}
|
||||
|
||||
FfxFloat16x4 SpdLoadH(FfxInt32x2 tex, FfxUInt32 slice)
|
||||
{
|
||||
return FfxFloat16x4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void SpdStoreH(FfxInt32x2 pix, FfxFloat16x4 value, FfxUInt32 mip, FfxUInt32 slice)
|
||||
{
|
||||
FfxDofStoreBilatMip(mip, pix, value);
|
||||
}
|
||||
|
||||
FfxFloat16x4 SpdLoadIntermediateH(FfxUInt32 x, FfxUInt32 y)
|
||||
{
|
||||
return FfxFloat16x4(
|
||||
spdIntermediateRG[x][y].x,
|
||||
spdIntermediateRG[x][y].y,
|
||||
spdIntermediateBA[x][y].x,
|
||||
spdIntermediateBA[x][y].y);
|
||||
}
|
||||
void SpdStoreIntermediateH(FfxUInt32 x, FfxUInt32 y, FfxFloat16x4 value)
|
||||
{
|
||||
spdIntermediateRG[x][y] = value.xy;
|
||||
spdIntermediateBA[x][y] = value.zw;
|
||||
}
|
||||
|
||||
/// Bilateral downsampling function, half-precision version
|
||||
/// @ingroup FfxGPUDof
|
||||
FfxFloat16x4 FfxDofDownsampleQuadH(FfxFloat16x4 v0, FfxFloat16x4 v1, FfxFloat16x4 v2, FfxFloat16x4 v3)
|
||||
{
|
||||
FfxFloat16 c0 = v0.a;
|
||||
FfxFloat16 c1 = v1.a;
|
||||
FfxFloat16 c2 = v2.a;
|
||||
FfxFloat16 c3 = v3.a;
|
||||
FfxFloat16 w1 = ffxSaturate(FfxFloat16(1.0) - abs(c0 - c1));
|
||||
FfxFloat16 w2 = ffxSaturate(FfxFloat16(1.0) - abs(c0 - c2));
|
||||
FfxFloat16 w3 = ffxSaturate(FfxFloat16(1.0) - abs(c0 - c3));
|
||||
FfxFloat16x3 color = v0.rgb + w1 * v1.rgb + w2 * v2.rgb + w3 * v3.rgb;
|
||||
FfxFloat16 weights = FfxFloat16(1.0) + w1 + w2 + w3;
|
||||
return FfxFloat16x4(color / weights, c0);
|
||||
}
|
||||
|
||||
FfxFloat16x4 SpdReduce4H(FfxFloat16x4 v0, FfxFloat16x4 v1, FfxFloat16x4 v2, FfxFloat16x4 v3)
|
||||
{
|
||||
return FfxDofDownsampleQuadH(v0, v1, v2, v3);
|
||||
}
|
||||
#else // #if FFX_HALF
|
||||
#define FFX_SPD_NO_WAVE_OPERATIONS 1
|
||||
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)
|
||||
{
|
||||
FfxFloat32 d = FfxDofLoadFullDepth(tex);
|
||||
FfxFloat32 c = FfxDofGetCoc(d);
|
||||
return FfxFloat32x4(FfxDofLoadSource(tex).rgb, c);
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdLoad(FfxInt32x2 tex, FfxUInt32 slice)
|
||||
{
|
||||
return FfxFloat32x4(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void SpdStore(FfxInt32x2 pix, FfxFloat32x4 value, FfxUInt32 mip, FfxUInt32 slice)
|
||||
{
|
||||
FfxDofStoreBilatMip(mip, pix, value);
|
||||
}
|
||||
|
||||
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.r;
|
||||
spdIntermediateG[x][y] = value.g;
|
||||
spdIntermediateB[x][y] = value.b;
|
||||
spdIntermediateA[x][y] = value.a;
|
||||
}
|
||||
|
||||
/// Bilateral downsampling function, full-precision version
|
||||
/// @ingroup FfxGPUDof
|
||||
FfxFloat32x4 FfxDofDownsampleQuad(FfxFloat32x4 v0, FfxFloat32x4 v1, FfxFloat32x4 v2, FfxFloat32x4 v3)
|
||||
{
|
||||
FfxFloat32 c0 = v0.a;
|
||||
FfxFloat32 c1 = v1.a;
|
||||
FfxFloat32 c2 = v2.a;
|
||||
FfxFloat32 c3 = v3.a;
|
||||
FfxFloat32 w1 = ffxSaturate(1.0 - abs(c0 - c1));
|
||||
FfxFloat32 w2 = ffxSaturate(1.0 - abs(c0 - c2));
|
||||
FfxFloat32 w3 = ffxSaturate(1.0 - abs(c0 - c3));
|
||||
FfxFloat32x3 color = v0.rgb + w1 * v1.rgb + w2 * v2.rgb + w3 * v3.rgb;
|
||||
FfxFloat32 weights = 1.0 + w1 + w2 + w3;
|
||||
return FfxFloat32x4(color / weights, c0);
|
||||
}
|
||||
|
||||
FfxFloat32x4 SpdReduce4(FfxFloat32x4 v0, FfxFloat32x4 v1, FfxFloat32x4 v2, FfxFloat32x4 v3)
|
||||
{
|
||||
return FfxDofDownsampleQuad(v0, v1, v2, v3);
|
||||
}
|
||||
#endif // #if FFX_HALF #else
|
||||
|
||||
// we only generate 4 mips, so these functions are not needed and never called.
|
||||
void SpdIncreaseAtomicCounter(FfxUInt32 slice)
|
||||
{
|
||||
/*nothing*/
|
||||
}
|
||||
FfxUInt32 SpdGetAtomicCounter()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void SpdResetAtomicCounter(FfxUInt32 slice)
|
||||
{
|
||||
/*nothing*/
|
||||
}
|
||||
|
||||
#include "spd/ffx_spd.h"
|
||||
|
||||
/// Entry point for the downsample color pass. Uses SPD internally.
|
||||
///
|
||||
/// @param LocalThreadId Thread index in thread group (SV_GroupIndex)
|
||||
/// @param WorkGroupId Coordinate of the tile (SV_GroupID.xy)
|
||||
/// @ingroup FfxGPUDof
|
||||
void DownsampleColor(FfxUInt32 LocalThreadId, FfxUInt32x2 WorkGroupId)
|
||||
{
|
||||
#if FFX_HALF
|
||||
SpdDownsampleH(WorkGroupId, LocalThreadId, FfxUInt32(FFX_DOF_OPTION_MAX_MIP), FfxUInt32(0), FfxUInt32(0));
|
||||
#else
|
||||
SpdDownsample(WorkGroupId, LocalThreadId, FfxUInt32(FFX_DOF_OPTION_MAX_MIP), FfxUInt32(0), FfxUInt32(0));
|
||||
#endif
|
||||
}
|
||||
77
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_downsample_depth.h
vendored
Normal file
77
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_downsample_depth.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// 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_core.h"
|
||||
#include "ffx_dof_common.h"
|
||||
|
||||
FfxUInt32x2 FfxDofCocRadInTiles(FfxFloat32x2 zMinMax)
|
||||
{
|
||||
FfxFloat32x2 rPx = abs(FfxDofGetCoc2(zMinMax));
|
||||
return FfxDofPxRadToTiles(rPx);
|
||||
}
|
||||
|
||||
FfxUInt32 FfxDofMaxCocInTiles(FfxFloat32x2 zMinMax)
|
||||
{
|
||||
FfxUInt32x2 rTiles = FfxDofCocRadInTiles(zMinMax);
|
||||
return max(rTiles.x, rTiles.y);
|
||||
}
|
||||
|
||||
/// Entry point for depth downsample function. SPD is not used for this,
|
||||
/// since we only need one specific downsampled resolution.
|
||||
///
|
||||
/// @param tile coordinate of the tile to run on (SV_DispatchThreadID)
|
||||
/// @param imageSize Size of the depth image (full resolution)
|
||||
/// @ingroup FfxGPUDof
|
||||
void DownsampleDepth(FfxUInt32x2 tile, FfxUInt32x2 imageSize)
|
||||
{
|
||||
FfxFloat32 minD = 1.0;
|
||||
FfxFloat32 maxD = 0.0;
|
||||
|
||||
const FfxUInt32x2 coordBase = tile * FFX_DOF_DEPTH_TILE_SIZE;
|
||||
const FfxFloat32x2 rcpImageSize = ffxReciprocal(FfxFloat32x2(imageSize));
|
||||
|
||||
for (FfxUInt32 yy = 0; yy < FFX_DOF_DEPTH_TILE_SIZE; yy += 2)
|
||||
{
|
||||
for (FfxUInt32 xx = 0; xx < FFX_DOF_DEPTH_TILE_SIZE; xx += 2)
|
||||
{
|
||||
FfxUInt32x2 coordInt = coordBase + FfxUInt32x2(xx, yy);
|
||||
FfxFloat32x2 coord = ffxSaturate(FfxFloat32x2(coordInt) * rcpImageSize);
|
||||
FfxFloat32x4 d = FfxDofGatherDepth(coord);
|
||||
|
||||
FfxFloat32 lo = min(min(min(d.x, d.y), d.z), d.w);
|
||||
FfxFloat32 hi = max(max(max(d.x, d.y), d.z), d.w);
|
||||
minD = min(minD, lo);
|
||||
maxD = max(maxD, hi);
|
||||
}
|
||||
}
|
||||
|
||||
#if FFX_DOF_OPTION_REVERSE_DEPTH
|
||||
// if Z-buffer is reversed, the nearest Z is the max.
|
||||
FfxFloat32x2 nearFarDepth = FfxFloat32x2(maxD, minD);
|
||||
#else
|
||||
FfxFloat32x2 nearFarDepth = FfxFloat32x2(minD, maxD);
|
||||
#endif
|
||||
FfxFloat32x2 coc = FfxDofGetCoc2(nearFarDepth);
|
||||
FfxUInt32 rTiles = FfxDofMaxCocInTiles(nearFarDepth);
|
||||
FfxDofAccumMaxTileRadius(rTiles);
|
||||
FfxDofStoreTileRadius(tile, coc);
|
||||
}
|
||||
50
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_resources.h
vendored
Normal file
50
manul/thirdparty/fsr2/include/FidelityFX/gpu/dof/ffx_dof_resources.h
vendored
Normal file
@@ -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_DOF_RESOURCES_H
|
||||
#define FFX_DOF_RESOURCES_H
|
||||
|
||||
#if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_NULL 0
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INPUT_DEPTH 1
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INPUT_COLOR 2
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_BILAT_COLOR 3 // same as MIP0
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_BILAT_COLOR_MIP0 3
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_BILAT_COLOR_MIP1 4
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_BILAT_COLOR_MIP2 5
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_BILAT_COLOR_MIP3 6
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_RADIUS 7
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_DILATED_RADIUS 8
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_NEAR 9
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_FAR 10
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_OUTPUT_COLOR 11
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_INTERNAL_GLOBALS 12
|
||||
|
||||
#define FFX_DOF_RESOURCE_IDENTIFIER_COUNT 13
|
||||
|
||||
#define FFX_DOF_CONSTANTBUFFER_IDENTIFIER_DOF 0
|
||||
|
||||
#define FFX_DOF_INTERNAL_BILAT_MIP_COUNT 4
|
||||
|
||||
#endif // #if defined(FFX_CPU) || defined(FFX_GPU)
|
||||
|
||||
#endif //!defined( FFX_DOF_RESOURCES_H )
|
||||
558
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_common_types.h
vendored
Normal file
558
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_common_types.h
vendored
Normal file
@@ -0,0 +1,558 @@
|
||||
// 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_COMMON_TYPES_H
|
||||
#define FFX_COMMON_TYPES_H
|
||||
|
||||
#if defined(FFX_CPU)
|
||||
#define FFX_PARAMETER_IN
|
||||
#define FFX_PARAMETER_OUT
|
||||
#define FFX_PARAMETER_INOUT
|
||||
#define FFX_PARAMETER_UNIFORM
|
||||
#elif defined(FFX_HLSL)
|
||||
#define FFX_PARAMETER_IN in
|
||||
#define FFX_PARAMETER_OUT out
|
||||
#define FFX_PARAMETER_INOUT inout
|
||||
#define FFX_PARAMETER_UNIFORM uniform
|
||||
#elif defined(FFX_GLSL)
|
||||
#define FFX_PARAMETER_IN in
|
||||
#define FFX_PARAMETER_OUT out
|
||||
#define FFX_PARAMETER_INOUT inout
|
||||
#define FFX_PARAMETER_UNIFORM const //[cacao_placeholder] until a better fit is found!
|
||||
#endif // #if defined(FFX_CPU)
|
||||
|
||||
#if defined(FFX_CPU)
|
||||
/// A typedef for a boolean value.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef bool FfxBoolean;
|
||||
|
||||
/// A typedef for a unsigned 8bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef uint8_t FfxUInt8;
|
||||
|
||||
/// A typedef for a unsigned 16bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef uint16_t FfxUInt16;
|
||||
|
||||
/// A typedef for a unsigned 32bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef uint32_t FfxUInt32;
|
||||
|
||||
/// A typedef for a unsigned 64bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef uint64_t FfxUInt64;
|
||||
|
||||
/// A typedef for a signed 8bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef int8_t FfxInt8;
|
||||
|
||||
/// A typedef for a signed 16bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef int16_t FfxInt16;
|
||||
|
||||
/// A typedef for a signed 32bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef int32_t FfxInt32;
|
||||
|
||||
/// A typedef for a signed 64bit integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef int64_t FfxInt64;
|
||||
|
||||
/// A typedef for a floating point value.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32;
|
||||
|
||||
/// A typedef for a 2-dimensional floating point value.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32x2[2];
|
||||
|
||||
/// A typedef for a 3-dimensional floating point value.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32x3[3];
|
||||
|
||||
/// A typedef for a 4-dimensional floating point value.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32x4[4];
|
||||
|
||||
/// A typedef for a 2x2 floating point matrix.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32x2x2[4];
|
||||
|
||||
/// A typedef for a 3x3 floating point matrix.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32x3x3[9];
|
||||
|
||||
/// A typedef for a 3x4 floating point matrix.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32x3x4[12];
|
||||
|
||||
/// A typedef for a 4x4 floating point matrix.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef float FfxFloat32x4x4[16];
|
||||
|
||||
/// A typedef for a 2-dimensional 32bit signed integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef int32_t FfxInt32x2[2];
|
||||
|
||||
/// A typedef for a 3-dimensional 32bit signed integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef int32_t FfxInt32x3[3];
|
||||
|
||||
/// A typedef for a 4-dimensional 32bit signed integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef int32_t FfxInt32x4[4];
|
||||
|
||||
/// A typedef for a 2-dimensional 32bit usigned integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef uint32_t FfxUInt32x2[2];
|
||||
|
||||
/// A typedef for a 3-dimensional 32bit unsigned integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef uint32_t FfxUInt32x3[3];
|
||||
|
||||
/// A typedef for a 4-dimensional 32bit unsigned integer.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
typedef uint32_t FfxUInt32x4[4];
|
||||
#endif // #if defined(FFX_CPU)
|
||||
|
||||
#if defined(FFX_HLSL)
|
||||
|
||||
#define FfxFloat32Mat4 matrix <float, 4, 4>
|
||||
#define FfxFloat32Mat3 matrix <float, 3, 3>
|
||||
|
||||
/// A typedef for a boolean value.
|
||||
///
|
||||
/// @ingroup HLSLTypes
|
||||
typedef bool FfxBoolean;
|
||||
|
||||
#if FFX_HLSL_SM>=62
|
||||
|
||||
/// @defgroup HLSL62Types HLSL 6.2 And Above Types
|
||||
/// HLSL 6.2 and above type defines for all commonly used variables
|
||||
///
|
||||
/// @ingroup HLSLTypes
|
||||
|
||||
/// A typedef for a floating point value.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef float32_t FfxFloat32;
|
||||
|
||||
/// A typedef for a 2-dimensional floating point value.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef float32_t2 FfxFloat32x2;
|
||||
|
||||
/// A typedef for a 3-dimensional floating point value.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef float32_t3 FfxFloat32x3;
|
||||
|
||||
/// A typedef for a 4-dimensional floating point value.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef float32_t4 FfxFloat32x4;
|
||||
|
||||
/// A [cacao_placeholder] typedef for matrix type until confirmed.
|
||||
typedef float4x4 FfxFloat32x4x4;
|
||||
typedef float3x4 FfxFloat32x3x4;
|
||||
typedef float3x3 FfxFloat32x3x3;
|
||||
typedef float2x2 FfxFloat32x2x2;
|
||||
|
||||
/// A typedef for a unsigned 32bit integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef uint32_t FfxUInt32;
|
||||
|
||||
/// A typedef for a 2-dimensional 32bit unsigned integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef uint32_t2 FfxUInt32x2;
|
||||
|
||||
/// A typedef for a 3-dimensional 32bit unsigned integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef uint32_t3 FfxUInt32x3;
|
||||
|
||||
/// A typedef for a 4-dimensional 32bit unsigned integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef uint32_t4 FfxUInt32x4;
|
||||
|
||||
/// A typedef for a signed 32bit integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef int32_t FfxInt32;
|
||||
|
||||
/// A typedef for a 2-dimensional signed 32bit integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef int32_t2 FfxInt32x2;
|
||||
|
||||
/// A typedef for a 3-dimensional signed 32bit integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef int32_t3 FfxInt32x3;
|
||||
|
||||
/// A typedef for a 4-dimensional signed 32bit integer.
|
||||
///
|
||||
/// @ingroup HLSL62Types
|
||||
typedef int32_t4 FfxInt32x4;
|
||||
|
||||
#else // #if FFX_HLSL_SM>=62
|
||||
|
||||
/// @defgroup HLSLBaseTypes HLSL 6.1 And Below Types
|
||||
/// HLSL 6.1 and below type defines for all commonly used variables
|
||||
///
|
||||
/// @ingroup HLSLTypes
|
||||
|
||||
#define FfxFloat32 float
|
||||
#define FfxFloat32x2 float2
|
||||
#define FfxFloat32x3 float3
|
||||
#define FfxFloat32x4 float4
|
||||
|
||||
/// A [cacao_placeholder] typedef for matrix type until confirmed.
|
||||
#define FfxFloat32x4x4 float4x4
|
||||
#define FfxFloat32x3x4 float3x4
|
||||
#define FfxFloat32x3x3 float3x3
|
||||
#define FfxFloat32x2x2 float2x2
|
||||
|
||||
/// A typedef for a unsigned 32bit integer.
|
||||
///
|
||||
/// @ingroup GPU
|
||||
typedef uint FfxUInt32;
|
||||
typedef uint2 FfxUInt32x2;
|
||||
typedef uint3 FfxUInt32x3;
|
||||
typedef uint4 FfxUInt32x4;
|
||||
|
||||
typedef int FfxInt32;
|
||||
typedef int2 FfxInt32x2;
|
||||
typedef int3 FfxInt32x3;
|
||||
typedef int4 FfxInt32x4;
|
||||
|
||||
#endif // #if FFX_HLSL_SM>=62
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#if FFX_HLSL_SM >= 62
|
||||
|
||||
typedef float16_t FfxFloat16;
|
||||
typedef float16_t2 FfxFloat16x2;
|
||||
typedef float16_t3 FfxFloat16x3;
|
||||
typedef float16_t4 FfxFloat16x4;
|
||||
|
||||
/// A typedef for an unsigned 16bit integer.
|
||||
///
|
||||
/// @ingroup HLSLTypes
|
||||
typedef uint16_t FfxUInt16;
|
||||
typedef uint16_t2 FfxUInt16x2;
|
||||
typedef uint16_t3 FfxUInt16x3;
|
||||
typedef uint16_t4 FfxUInt16x4;
|
||||
|
||||
/// A typedef for a signed 16bit integer.
|
||||
///
|
||||
/// @ingroup HLSLTypes
|
||||
typedef int16_t FfxInt16;
|
||||
typedef int16_t2 FfxInt16x2;
|
||||
typedef int16_t3 FfxInt16x3;
|
||||
typedef int16_t4 FfxInt16x4;
|
||||
#else // #if FFX_HLSL_SM>=62
|
||||
typedef min16float FfxFloat16;
|
||||
typedef min16float2 FfxFloat16x2;
|
||||
typedef min16float3 FfxFloat16x3;
|
||||
typedef min16float4 FfxFloat16x4;
|
||||
|
||||
/// A typedef for an unsigned 16bit integer.
|
||||
///
|
||||
/// @ingroup HLSLTypes
|
||||
typedef min16uint FfxUInt16;
|
||||
typedef min16uint2 FfxUInt16x2;
|
||||
typedef min16uint3 FfxUInt16x3;
|
||||
typedef min16uint4 FfxUInt16x4;
|
||||
|
||||
/// A typedef for a signed 16bit integer.
|
||||
///
|
||||
/// @ingroup HLSLTypes
|
||||
typedef min16int FfxInt16;
|
||||
typedef min16int2 FfxInt16x2;
|
||||
typedef min16int3 FfxInt16x3;
|
||||
typedef min16int4 FfxInt16x4;
|
||||
#endif // #if FFX_HLSL_SM>=62
|
||||
|
||||
#endif // FFX_HALF
|
||||
|
||||
#endif // #if defined(FFX_HLSL)
|
||||
|
||||
#if defined(FFX_GLSL)
|
||||
|
||||
#define FfxFloat32Mat4 mat4
|
||||
#define FfxFloat32Mat3 mat3
|
||||
|
||||
/// A typedef for a boolean value.
|
||||
///
|
||||
/// @ingroup GLSLTypes
|
||||
#define FfxBoolean bool
|
||||
#define FfxFloat32 float
|
||||
#define FfxFloat32x2 vec2
|
||||
#define FfxFloat32x3 vec3
|
||||
#define FfxFloat32x4 vec4
|
||||
#define FfxUInt32 uint
|
||||
#define FfxUInt32x2 uvec2
|
||||
#define FfxUInt32x3 uvec3
|
||||
#define FfxUInt32x4 uvec4
|
||||
#define FfxInt32 int
|
||||
#define FfxInt32x2 ivec2
|
||||
#define FfxInt32x3 ivec3
|
||||
#define FfxInt32x4 ivec4
|
||||
|
||||
/// A [cacao_placeholder] typedef for matrix type until confirmed.
|
||||
#define FfxFloat32x4x4 mat4
|
||||
#define FfxFloat32x3x4 mat4x3
|
||||
#define FfxFloat32x3x3 mat3
|
||||
#define FfxFloat32x2x2 mat2
|
||||
|
||||
#if FFX_HALF
|
||||
#define FfxFloat16 float16_t
|
||||
#define FfxFloat16x2 f16vec2
|
||||
#define FfxFloat16x3 f16vec3
|
||||
#define FfxFloat16x4 f16vec4
|
||||
#define FfxUInt16 uint16_t
|
||||
#define FfxUInt16x2 u16vec2
|
||||
#define FfxUInt16x3 u16vec3
|
||||
#define FfxUInt16x4 u16vec4
|
||||
#define FfxInt16 int16_t
|
||||
#define FfxInt16x2 i16vec2
|
||||
#define FfxInt16x3 i16vec3
|
||||
#define FfxInt16x4 i16vec4
|
||||
#endif // FFX_HALF
|
||||
#endif // #if defined(FFX_GLSL)
|
||||
|
||||
// Global toggles:
|
||||
// #define FFX_HALF (1)
|
||||
// #define FFX_HLSL_SM (62)
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#if FFX_HLSL_SM >= 62
|
||||
|
||||
#define FFX_MIN16_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType##16_t TypeName;
|
||||
#define FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType##16_t, COL> TypeName;
|
||||
#define FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType##16_t, ROW, COL> TypeName;
|
||||
|
||||
#define FFX_16BIT_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType##16_t TypeName;
|
||||
#define FFX_16BIT_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType##16_t, COL> TypeName;
|
||||
#define FFX_16BIT_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType##16_t, ROW, COL> TypeName;
|
||||
|
||||
#else //FFX_HLSL_SM>=62
|
||||
|
||||
#define FFX_MIN16_SCALAR( TypeName, BaseComponentType ) typedef min16##BaseComponentType TypeName;
|
||||
#define FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<min16##BaseComponentType, COL> TypeName;
|
||||
#define FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<min16##BaseComponentType, ROW, COL> TypeName;
|
||||
|
||||
#define FFX_16BIT_SCALAR( TypeName, BaseComponentType ) FFX_MIN16_SCALAR( TypeName, BaseComponentType );
|
||||
#define FFX_16BIT_VECTOR( TypeName, BaseComponentType, COL ) FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL );
|
||||
#define FFX_16BIT_MATRIX( TypeName, BaseComponentType, ROW, COL ) FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL );
|
||||
|
||||
#endif //FFX_HLSL_SM>=62
|
||||
|
||||
#else //FFX_HALF
|
||||
|
||||
#define FFX_MIN16_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType TypeName;
|
||||
#define FFX_MIN16_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType, COL> TypeName;
|
||||
#define FFX_MIN16_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType, ROW, COL> TypeName;
|
||||
|
||||
#define FFX_16BIT_SCALAR( TypeName, BaseComponentType ) typedef BaseComponentType TypeName;
|
||||
#define FFX_16BIT_VECTOR( TypeName, BaseComponentType, COL ) typedef vector<BaseComponentType, COL> TypeName;
|
||||
#define FFX_16BIT_MATRIX( TypeName, BaseComponentType, ROW, COL ) typedef matrix<BaseComponentType, ROW, COL> TypeName;
|
||||
|
||||
#endif //FFX_HALF
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
// Common typedefs:
|
||||
#if defined(FFX_HLSL)
|
||||
FFX_MIN16_SCALAR( FFX_MIN16_F , float );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_F2, float, 2 );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_F3, float, 3 );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_F4, float, 4 );
|
||||
|
||||
FFX_MIN16_SCALAR( FFX_MIN16_I, int );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_I2, int, 2 );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_I3, int, 3 );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_I4, int, 4 );
|
||||
|
||||
FFX_MIN16_SCALAR( FFX_MIN16_U, uint );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_U2, uint, 2 );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_U3, uint, 3 );
|
||||
FFX_MIN16_VECTOR( FFX_MIN16_U4, uint, 4 );
|
||||
|
||||
FFX_16BIT_SCALAR( FFX_F16_t , float );
|
||||
FFX_16BIT_VECTOR( FFX_F16_t2, float, 2 );
|
||||
FFX_16BIT_VECTOR( FFX_F16_t3, float, 3 );
|
||||
FFX_16BIT_VECTOR( FFX_F16_t4, float, 4 );
|
||||
|
||||
FFX_16BIT_SCALAR( FFX_I16_t, int );
|
||||
FFX_16BIT_VECTOR( FFX_I16_t2, int, 2 );
|
||||
FFX_16BIT_VECTOR( FFX_I16_t3, int, 3 );
|
||||
FFX_16BIT_VECTOR( FFX_I16_t4, int, 4 );
|
||||
|
||||
FFX_16BIT_SCALAR( FFX_U16_t, uint );
|
||||
FFX_16BIT_VECTOR( FFX_U16_t2, uint, 2 );
|
||||
FFX_16BIT_VECTOR( FFX_U16_t3, uint, 3 );
|
||||
FFX_16BIT_VECTOR( FFX_U16_t4, uint, 4 );
|
||||
|
||||
#define TYPEDEF_MIN16_TYPES(Prefix) \
|
||||
typedef FFX_MIN16_F Prefix##_F; \
|
||||
typedef FFX_MIN16_F2 Prefix##_F2; \
|
||||
typedef FFX_MIN16_F3 Prefix##_F3; \
|
||||
typedef FFX_MIN16_F4 Prefix##_F4; \
|
||||
typedef FFX_MIN16_I Prefix##_I; \
|
||||
typedef FFX_MIN16_I2 Prefix##_I2; \
|
||||
typedef FFX_MIN16_I3 Prefix##_I3; \
|
||||
typedef FFX_MIN16_I4 Prefix##_I4; \
|
||||
typedef FFX_MIN16_U Prefix##_U; \
|
||||
typedef FFX_MIN16_U2 Prefix##_U2; \
|
||||
typedef FFX_MIN16_U3 Prefix##_U3; \
|
||||
typedef FFX_MIN16_U4 Prefix##_U4;
|
||||
|
||||
#define TYPEDEF_16BIT_TYPES(Prefix) \
|
||||
typedef FFX_16BIT_F Prefix##_F; \
|
||||
typedef FFX_16BIT_F2 Prefix##_F2; \
|
||||
typedef FFX_16BIT_F3 Prefix##_F3; \
|
||||
typedef FFX_16BIT_F4 Prefix##_F4; \
|
||||
typedef FFX_16BIT_I Prefix##_I; \
|
||||
typedef FFX_16BIT_I2 Prefix##_I2; \
|
||||
typedef FFX_16BIT_I3 Prefix##_I3; \
|
||||
typedef FFX_16BIT_I4 Prefix##_I4; \
|
||||
typedef FFX_16BIT_U Prefix##_U; \
|
||||
typedef FFX_16BIT_U2 Prefix##_U2; \
|
||||
typedef FFX_16BIT_U3 Prefix##_U3; \
|
||||
typedef FFX_16BIT_U4 Prefix##_U4;
|
||||
|
||||
#define TYPEDEF_FULL_PRECISION_TYPES(Prefix) \
|
||||
typedef FfxFloat32 Prefix##_F; \
|
||||
typedef FfxFloat32x2 Prefix##_F2; \
|
||||
typedef FfxFloat32x3 Prefix##_F3; \
|
||||
typedef FfxFloat32x4 Prefix##_F4; \
|
||||
typedef FfxInt32 Prefix##_I; \
|
||||
typedef FfxInt32x2 Prefix##_I2; \
|
||||
typedef FfxInt32x3 Prefix##_I3; \
|
||||
typedef FfxInt32x4 Prefix##_I4; \
|
||||
typedef FfxUInt32 Prefix##_U; \
|
||||
typedef FfxUInt32x2 Prefix##_U2; \
|
||||
typedef FfxUInt32x3 Prefix##_U3; \
|
||||
typedef FfxUInt32x4 Prefix##_U4;
|
||||
#endif // #if defined(FFX_HLSL)
|
||||
|
||||
#if defined(FFX_GLSL)
|
||||
|
||||
#if FFX_HALF
|
||||
|
||||
#define FFX_MIN16_F float16_t
|
||||
#define FFX_MIN16_F2 f16vec2
|
||||
#define FFX_MIN16_F3 f16vec3
|
||||
#define FFX_MIN16_F4 f16vec4
|
||||
|
||||
#define FFX_MIN16_I int16_t
|
||||
#define FFX_MIN16_I2 i16vec2
|
||||
#define FFX_MIN16_I3 i16vec3
|
||||
#define FFX_MIN16_I4 i16vec4
|
||||
|
||||
#define FFX_MIN16_U uint16_t
|
||||
#define FFX_MIN16_U2 u16vec2
|
||||
#define FFX_MIN16_U3 u16vec3
|
||||
#define FFX_MIN16_U4 u16vec4
|
||||
|
||||
#define FFX_16BIT_F float16_t
|
||||
#define FFX_16BIT_F2 f16vec2
|
||||
#define FFX_16BIT_F3 f16vec3
|
||||
#define FFX_16BIT_F4 f16vec4
|
||||
|
||||
#define FFX_16BIT_I int16_t
|
||||
#define FFX_16BIT_I2 i16vec2
|
||||
#define FFX_16BIT_I3 i16vec3
|
||||
#define FFX_16BIT_I4 i16vec4
|
||||
|
||||
#define FFX_16BIT_U uint16_t
|
||||
#define FFX_16BIT_U2 u16vec2
|
||||
#define FFX_16BIT_U3 u16vec3
|
||||
#define FFX_16BIT_U4 u16vec4
|
||||
|
||||
#else // FFX_HALF
|
||||
|
||||
#define FFX_MIN16_F float
|
||||
#define FFX_MIN16_F2 vec2
|
||||
#define FFX_MIN16_F3 vec3
|
||||
#define FFX_MIN16_F4 vec4
|
||||
|
||||
#define FFX_MIN16_I int
|
||||
#define FFX_MIN16_I2 ivec2
|
||||
#define FFX_MIN16_I3 ivec3
|
||||
#define FFX_MIN16_I4 ivec4
|
||||
|
||||
#define FFX_MIN16_U uint
|
||||
#define FFX_MIN16_U2 uvec2
|
||||
#define FFX_MIN16_U3 uvec3
|
||||
#define FFX_MIN16_U4 uvec4
|
||||
|
||||
#define FFX_16BIT_F float
|
||||
#define FFX_16BIT_F2 vec2
|
||||
#define FFX_16BIT_F3 vec3
|
||||
#define FFX_16BIT_F4 vec4
|
||||
|
||||
#define FFX_16BIT_I int
|
||||
#define FFX_16BIT_I2 ivec2
|
||||
#define FFX_16BIT_I3 ivec3
|
||||
#define FFX_16BIT_I4 ivec4
|
||||
|
||||
#define FFX_16BIT_U uint
|
||||
#define FFX_16BIT_U2 uvec2
|
||||
#define FFX_16BIT_U3 uvec3
|
||||
#define FFX_16BIT_U4 uvec4
|
||||
|
||||
#endif // FFX_HALF
|
||||
|
||||
#endif // #if defined(FFX_GLSL)
|
||||
|
||||
#endif // #if defined(FFX_GPU)
|
||||
#endif // #ifndef FFX_COMMON_TYPES_H
|
||||
80
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core.h
vendored
Normal file
80
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// 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.
|
||||
|
||||
/// @defgroup FfxGPU GPU
|
||||
/// The FidelityFX SDK GPU References
|
||||
///
|
||||
/// @ingroup ffxSDK
|
||||
|
||||
/// @defgroup FfxHLSL HLSL References
|
||||
/// FidelityFX SDK HLSL GPU References
|
||||
///
|
||||
/// @ingroup FfxGPU
|
||||
|
||||
/// @defgroup FfxGLSL GLSL References
|
||||
/// FidelityFX SDK GLSL GPU References
|
||||
///
|
||||
/// @ingroup FfxGPU
|
||||
|
||||
/// @defgroup FfxGPUEffects FidelityFX GPU References
|
||||
/// FidelityFX Effect GPU Reference Documentation
|
||||
///
|
||||
/// @ingroup FfxGPU
|
||||
|
||||
/// @defgroup GPUCore GPU Core
|
||||
/// GPU defines and functions
|
||||
///
|
||||
/// @ingroup FfxGPU
|
||||
|
||||
#if !defined(FFX_CORE_H)
|
||||
#define FFX_CORE_H
|
||||
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic push
|
||||
#pragma dxc diagnostic ignored "-Wambig-lit-shift"
|
||||
#endif //__hlsl_dx_compiler
|
||||
|
||||
#include "ffx_common_types.h"
|
||||
|
||||
#if defined(FFX_CPU)
|
||||
#include "ffx_core_cpu.h"
|
||||
#endif // #if defined(FFX_CPU)
|
||||
|
||||
#if defined(FFX_GLSL) && defined(FFX_GPU)
|
||||
#include "ffx_core_glsl.h"
|
||||
#endif // #if defined(FFX_GLSL) && defined(FFX_GPU)
|
||||
|
||||
#if defined(FFX_HLSL) && defined(FFX_GPU)
|
||||
#include "ffx_core_hlsl.h"
|
||||
#endif // #if defined(FFX_HLSL) && defined(FFX_GPU)
|
||||
|
||||
#if defined(FFX_GPU)
|
||||
#include "ffx_core_gpu_common.h"
|
||||
#include "ffx_core_gpu_common_half.h"
|
||||
#include "ffx_core_portability.h"
|
||||
#endif // #if defined(FFX_GPU)
|
||||
|
||||
#ifdef __hlsl_dx_compiler
|
||||
#pragma dxc diagnostic pop
|
||||
#endif //__hlsl_dx_compiler
|
||||
|
||||
#endif // #if !defined(FFX_CORE_H)
|
||||
338
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_cpu.h
vendored
Normal file
338
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_cpu.h
vendored
Normal file
@@ -0,0 +1,338 @@
|
||||
// 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.
|
||||
|
||||
/// A define for a true value in a boolean expression.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
#define FFX_TRUE (1)
|
||||
|
||||
/// A define for a false value in a boolean expression.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
#define FFX_FALSE (0)
|
||||
|
||||
#if !defined(FFX_STATIC)
|
||||
/// A define to abstract declaration of static variables and functions.
|
||||
///
|
||||
/// @ingroup CPUTypes
|
||||
#define FFX_STATIC static
|
||||
#endif // #if !defined(FFX_STATIC)
|
||||
|
||||
/// @defgroup CPUCore CPU Core
|
||||
/// Core CPU-side defines and functions
|
||||
///
|
||||
/// @ingroup ffxHost
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
|
||||
/// Interpret the bit layout of an IEEE-754 floating point value as an unsigned integer.
|
||||
///
|
||||
/// @param [in] x A 32bit floating value.
|
||||
///
|
||||
/// @returns
|
||||
/// An unsigned 32bit integer value containing the bit pattern of <c><i>x</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxUInt32 ffxAsUInt32(FfxFloat32 x)
|
||||
{
|
||||
union
|
||||
{
|
||||
FfxFloat32 f;
|
||||
FfxUInt32 u;
|
||||
} bits;
|
||||
|
||||
bits.f = x;
|
||||
return bits.u;
|
||||
}
|
||||
|
||||
FFX_STATIC FfxFloat32 ffxDot2(FfxFloat32x2 a, FfxFloat32x2 b)
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1];
|
||||
}
|
||||
|
||||
FFX_STATIC FfxFloat32 ffxDot3(FfxFloat32x3 a, FfxFloat32x3 b)
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
}
|
||||
|
||||
FFX_STATIC FfxFloat32 ffxDot4(FfxFloat32x4 a, FfxFloat32x4 b)
|
||||
{
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
|
||||
}
|
||||
|
||||
/// Compute the linear interopation between two values.
|
||||
///
|
||||
/// Implemented by calling the GLSL <c><i>mix</i></c> instrinsic function. Implements the
|
||||
/// following math:
|
||||
///
|
||||
/// (1 - t) * x + t * y
|
||||
///
|
||||
/// @param [in] x The first value to lerp between.
|
||||
/// @param [in] y The second value to lerp between.
|
||||
/// @param [in] t The value to determine how much of <c><i>x</i></c> and how much of <c><i>y</i></c>.
|
||||
///
|
||||
/// @returns
|
||||
/// A linearly interpolated value between <c><i>x</i></c> and <c><i>y</i></c> according to <c><i>t</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxFloat32 ffxLerp(FfxFloat32 x, FfxFloat32 y, FfxFloat32 t)
|
||||
{
|
||||
return y * t + (-x * t + x);
|
||||
}
|
||||
|
||||
/// Compute the reciprocal of a value.
|
||||
///
|
||||
/// @param [in] x The value to compute the reciprocal for.
|
||||
///
|
||||
/// @returns
|
||||
/// The reciprocal value of <c><i>x</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxFloat32 ffxReciprocal(FfxFloat32 x)
|
||||
{
|
||||
return 1.0f / x;
|
||||
}
|
||||
|
||||
/// Compute the square root of a value.
|
||||
///
|
||||
/// @param [in] x The first value to compute the min of.
|
||||
///
|
||||
/// @returns
|
||||
/// The the square root of <c><i>x</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxFloat32 ffxSqrt(FfxFloat32 x)
|
||||
{
|
||||
return FfxFloat32(sqrt(x));
|
||||
}
|
||||
|
||||
FFX_STATIC FfxUInt32 ffxAShrSU1(FfxUInt32 a, FfxUInt32 b)
|
||||
{
|
||||
return FfxUInt32(FfxInt32(a) >> FfxInt32(b));
|
||||
}
|
||||
|
||||
/// Compute the factional part of a decimal value.
|
||||
///
|
||||
/// This function calculates <c><i>x - floor(x)</i></c>.
|
||||
///
|
||||
/// @param [in] x The value to compute the fractional part from.
|
||||
///
|
||||
/// @returns
|
||||
/// The fractional part of <c><i>x</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxFloat32 ffxFract(FfxFloat32 x)
|
||||
{
|
||||
return x - FfxFloat32(floor(x));
|
||||
}
|
||||
|
||||
/// Compute the reciprocal square root of a value.
|
||||
///
|
||||
/// @param [in] x The value to compute the reciprocal for.
|
||||
///
|
||||
/// @returns
|
||||
/// The reciprocal square root value of <c><i>x</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxFloat32 ffxRsqrt(FfxFloat32 x)
|
||||
{
|
||||
return ffxReciprocal(ffxSqrt(x));
|
||||
}
|
||||
|
||||
FFX_STATIC FfxFloat32 ffxMin(FfxFloat32 x, FfxFloat32 y)
|
||||
{
|
||||
return x < y ? x : y;
|
||||
}
|
||||
|
||||
FFX_STATIC FfxUInt32 ffxMin(FfxUInt32 x, FfxUInt32 y)
|
||||
{
|
||||
return x < y ? x : y;
|
||||
}
|
||||
|
||||
FFX_STATIC FfxFloat32 ffxMax(FfxFloat32 x, FfxFloat32 y)
|
||||
{
|
||||
return x > y ? x : y;
|
||||
}
|
||||
|
||||
FFX_STATIC FfxUInt32 ffxMax(FfxUInt32 x, FfxUInt32 y)
|
||||
{
|
||||
return x > y ? x : y;
|
||||
}
|
||||
|
||||
/// Clamp a value to a [0..1] range.
|
||||
///
|
||||
/// @param [in] x The value to clamp to [0..1] range.
|
||||
///
|
||||
/// @returns
|
||||
/// The clamped version of <c><i>x</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxFloat32 ffxSaturate(FfxFloat32 x)
|
||||
{
|
||||
return ffxMin(1.0f, ffxMax(0.0f, x));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FFX_STATIC void ffxOpAAddOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b)
|
||||
{
|
||||
d[0] = a[0] + b;
|
||||
d[1] = a[1] + b;
|
||||
d[2] = a[2] + b;
|
||||
return;
|
||||
}
|
||||
|
||||
FFX_STATIC void ffxOpACpyF3(FfxFloat32x3 d, FfxFloat32x3 a)
|
||||
{
|
||||
d[0] = a[0];
|
||||
d[1] = a[1];
|
||||
d[2] = a[2];
|
||||
return;
|
||||
}
|
||||
|
||||
FFX_STATIC void ffxOpAMulF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32x3 b)
|
||||
{
|
||||
d[0] = a[0] * b[0];
|
||||
d[1] = a[1] * b[1];
|
||||
d[2] = a[2] * b[2];
|
||||
return;
|
||||
}
|
||||
|
||||
FFX_STATIC void ffxOpAMulOneF3(FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b)
|
||||
{
|
||||
d[0] = a[0] * b;
|
||||
d[1] = a[1] * b;
|
||||
d[2] = a[2] * b;
|
||||
return;
|
||||
}
|
||||
|
||||
FFX_STATIC void ffxOpARcpF3(FfxFloat32x3 d, FfxFloat32x3 a)
|
||||
{
|
||||
d[0] = ffxReciprocal(a[0]);
|
||||
d[1] = ffxReciprocal(a[1]);
|
||||
d[2] = ffxReciprocal(a[2]);
|
||||
return;
|
||||
}
|
||||
|
||||
/// Convert FfxFloat32 to half (in lower 16-bits of output).
|
||||
///
|
||||
/// This function implements the same fast technique that is documented here: ftp://ftp.fox-toolkit.org/pub/fasthalffloatconversion.pdf
|
||||
///
|
||||
/// The function supports denormals.
|
||||
///
|
||||
/// Some conversion rules are to make computations possibly "safer" on the GPU,
|
||||
/// -INF & -NaN -> -65504
|
||||
/// +INF & +NaN -> +65504
|
||||
///
|
||||
/// @param [in] f The 32bit floating point value to convert.
|
||||
///
|
||||
/// @returns
|
||||
/// The closest 16bit floating point value to <c><i>f</i></c>.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxUInt32 ffxF32ToF16(FfxFloat32 f)
|
||||
{
|
||||
static FfxUInt16 base[512] = {
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
||||
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400,
|
||||
0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00, 0x2000, 0x2400, 0x2800, 0x2c00, 0x3000, 0x3400, 0x3800, 0x3c00, 0x4000, 0x4400, 0x4800, 0x4c00, 0x5000,
|
||||
0x5400, 0x5800, 0x5c00, 0x6000, 0x6400, 0x6800, 0x6c00, 0x7000, 0x7400, 0x7800, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
|
||||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
|
||||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
|
||||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
|
||||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
|
||||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff,
|
||||
0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x7bff, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
|
||||
0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8001, 0x8002,
|
||||
0x8004, 0x8008, 0x8010, 0x8020, 0x8040, 0x8080, 0x8100, 0x8200, 0x8400, 0x8800, 0x8c00, 0x9000, 0x9400, 0x9800, 0x9c00, 0xa000, 0xa400, 0xa800, 0xac00,
|
||||
0xb000, 0xb400, 0xb800, 0xbc00, 0xc000, 0xc400, 0xc800, 0xcc00, 0xd000, 0xd400, 0xd800, 0xdc00, 0xe000, 0xe400, 0xe800, 0xec00, 0xf000, 0xf400, 0xf800,
|
||||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff,
|
||||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff,
|
||||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff,
|
||||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff,
|
||||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff,
|
||||
0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff, 0xfbff
|
||||
};
|
||||
|
||||
static FfxUInt8 shift[512] = {
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
|
||||
0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
FfxFloat32 f;
|
||||
FfxUInt32 u;
|
||||
} bits;
|
||||
|
||||
bits.f = f;
|
||||
FfxUInt32 u = bits.u;
|
||||
FfxUInt32 i = u >> 23;
|
||||
return (FfxUInt32)(base[i]) + ((u & 0x7fffff) >> shift[i]);
|
||||
}
|
||||
|
||||
/// Pack 2x32-bit floating point values in a single 32bit value.
|
||||
///
|
||||
/// This function first converts each component of <c><i>value</i></c> into their nearest 16-bit floating
|
||||
/// point representation, and then stores the X and Y components in the lower and upper 16 bits of the
|
||||
/// 32bit unsigned integer respectively.
|
||||
///
|
||||
/// @param [in] x A 2-dimensional floating point value to convert and pack.
|
||||
///
|
||||
/// @returns
|
||||
/// A packed 32bit value containing 2 16bit floating point values.
|
||||
///
|
||||
/// @ingroup CPUCore
|
||||
FFX_STATIC FfxUInt32 ffxPackHalf2x16(FfxFloat32x2 x)
|
||||
{
|
||||
return ffxF32ToF16(x[0]) + (ffxF32ToF16(x[1]) << 16);
|
||||
}
|
||||
1916
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_glsl.h
vendored
Normal file
1916
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_glsl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2736
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_gpu_common.h
vendored
Normal file
2736
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_gpu_common.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2981
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_gpu_common_half.h
vendored
Normal file
2981
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_gpu_common_half.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1898
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_hlsl.h
vendored
Normal file
1898
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_hlsl.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
46
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_portability.h
vendored
Normal file
46
manul/thirdparty/fsr2/include/FidelityFX/gpu/ffx_core_portability.h
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// 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.
|
||||
|
||||
void ffxOpAAddOneF3(FFX_PARAMETER_OUT FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b)
|
||||
{
|
||||
d = a + ffxBroadcast3(b);
|
||||
}
|
||||
|
||||
void ffxOpACpyF3(FFX_PARAMETER_OUT FfxFloat32x3 d, FfxFloat32x3 a)
|
||||
{
|
||||
d = a;
|
||||
}
|
||||
|
||||
void ffxOpAMulF3(FFX_PARAMETER_OUT FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32x3 b)
|
||||
{
|
||||
d = a * b;
|
||||
}
|
||||
|
||||
void ffxOpAMulOneF3(FFX_PARAMETER_OUT FfxFloat32x3 d, FfxFloat32x3 a, FfxFloat32 b)
|
||||
{
|
||||
d = a * b;
|
||||
}
|
||||
|
||||
void ffxOpARcpF3(FFX_PARAMETER_OUT FfxFloat32x3 d, FfxFloat32x3 a)
|
||||
{
|
||||
d = ffxReciprocal(a);
|
||||
}
|
||||
@@ -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
manul/thirdparty/fsr2/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation.h
vendored
Normal file
192
manul/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)
|
||||
445
manul/thirdparty/fsr2/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_common.h
vendored
Normal file
445
manul/thirdparty/fsr2/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_common.h
vendored
Normal file
@@ -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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user