From d77d3fc94b76d3722e2052bcd662ca9e45906dbe Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 30 Sep 2022 13:14:08 +0200 Subject: [PATCH 01/11] Improve wider platform support Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/CMakeLists.txt | 6 ++++++ src/ffx-fsr2-api/ffx_fsr2.cpp | 19 ++++++++++++------- src/ffx-fsr2-api/ffx_types.h | 1 + 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/ffx-fsr2-api/CMakeLists.txt b/src/ffx-fsr2-api/CMakeLists.txt index 7ef023c..6a456bf 100644 --- a/src/ffx-fsr2-api/CMakeLists.txt +++ b/src/ffx-fsr2-api/CMakeLists.txt @@ -41,6 +41,12 @@ if(CMAKE_GENERATOR_PLATFORM STREQUAL "x64" OR CMAKE_EXE_LINKER_FLAGS STREQUAL "/ set(FSR2_PLATFORM_NAME x64) elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32" OR CMAKE_EXE_LINKER_FLAGS STREQUAL "/machine:X86") set(FSR2_PLATFORM_NAME x86) +elseif(CMAKE_SYSTEM_PROCESSOR) + set(FSR2_PLATFORM_NAME ${CMAKE_SYSTEM_PROCESSOR}) + + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + add_compile_definitions(FFX_GCC) + endif() else() message(FATAL_ERROR "Unsupported target platform - only supporting x64 and Win32 currently") endif() diff --git a/src/ffx-fsr2-api/ffx_fsr2.cpp b/src/ffx-fsr2-api/ffx_fsr2.cpp index ebd69d5..9370fcc 100644 --- a/src/ffx-fsr2-api/ffx_fsr2.cpp +++ b/src/ffx-fsr2-api/ffx_fsr2.cpp @@ -22,6 +22,7 @@ #include // for max used inside SPD CPU code. #include // for fabs, abs, sinf, sqrt, etc. #include // for memset +#include // for wcscmp, wcscpy #include // for FLT_EPSILON #include "ffx_fsr2.h" #define FFX_CPU @@ -36,6 +37,10 @@ #pragma clang diagnostic ignored "-Wunused-variable" #endif +#ifndef _countof +#define _countof(array) (sizeof(array) / sizeof(array[0])) +#endif + // max queued frames for descriptor management static const uint32_t FSR2_MAX_QUEUED_FRAMES = 16; @@ -484,13 +489,13 @@ static void scheduleDispatch(FfxFsr2Context_Private* context, const FfxFsr2Dispa const uint32_t currentResourceId = pipeline->srvResourceBindings[currentShaderResourceViewIndex].resourceIdentifier; const FfxResourceInternal currentResource = context->srvResources[currentResourceId]; jobDescriptor.srvs[currentShaderResourceViewIndex] = currentResource; - wcscpy_s(jobDescriptor.srvNames[currentShaderResourceViewIndex], pipeline->srvResourceBindings[currentShaderResourceViewIndex].name); + wcscpy(jobDescriptor.srvNames[currentShaderResourceViewIndex], pipeline->srvResourceBindings[currentShaderResourceViewIndex].name); } for (uint32_t currentUnorderedAccessViewIndex = 0; currentUnorderedAccessViewIndex < pipeline->uavCount; ++currentUnorderedAccessViewIndex) { const uint32_t currentResourceId = pipeline->uavResourceBindings[currentUnorderedAccessViewIndex].resourceIdentifier; - wcscpy_s(jobDescriptor.uavNames[currentUnorderedAccessViewIndex], pipeline->uavResourceBindings[currentUnorderedAccessViewIndex].name); + wcscpy(jobDescriptor.uavNames[currentUnorderedAccessViewIndex], pipeline->uavResourceBindings[currentUnorderedAccessViewIndex].name); if (currentResourceId >= FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_0 && currentResourceId <= FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_12) { @@ -512,7 +517,7 @@ static void scheduleDispatch(FfxFsr2Context_Private* context, const FfxFsr2Dispa jobDescriptor.pipeline = *pipeline; for (uint32_t currentRootConstantIndex = 0; currentRootConstantIndex < pipeline->constCount; ++currentRootConstantIndex) { - wcscpy_s( jobDescriptor.cbNames[currentRootConstantIndex], pipeline->cbResourceBindings[currentRootConstantIndex].name); + wcscpy( jobDescriptor.cbNames[currentRootConstantIndex], pipeline->cbResourceBindings[currentRootConstantIndex].name); jobDescriptor.cbs[currentRootConstantIndex] = globalFsr2ConstantBuffers[pipeline->cbResourceBindings[currentRootConstantIndex].resourceIdentifier]; } @@ -1003,9 +1008,9 @@ FfxErrorCode ffxFsr2ContextGenerateReactiveMask(FfxFsr2Context* context, const F contextPrivate->contextDescription.callbacks.fpRegisterResource(&contextPrivate->contextDescription.callbacks, ¶ms->colorOpaqueOnly, &jobDescriptor.srvs[0]); contextPrivate->contextDescription.callbacks.fpRegisterResource(&contextPrivate->contextDescription.callbacks, ¶ms->colorPreUpscale, &jobDescriptor.srvs[1]); contextPrivate->contextDescription.callbacks.fpRegisterResource(&contextPrivate->contextDescription.callbacks, ¶ms->outReactive, &jobDescriptor.uavs[0]); - wcscpy_s(jobDescriptor.srvNames[0], pipeline->srvResourceBindings[0].name); - wcscpy_s(jobDescriptor.srvNames[1], pipeline->srvResourceBindings[1].name); - wcscpy_s(jobDescriptor.uavNames[0], pipeline->uavResourceBindings[0].name); + wcscpy(jobDescriptor.srvNames[0], pipeline->srvResourceBindings[0].name); + wcscpy(jobDescriptor.srvNames[1], pipeline->srvResourceBindings[1].name); + wcscpy(jobDescriptor.uavNames[0], pipeline->uavResourceBindings[0].name); jobDescriptor.dimensions[0] = dispatchSrcX; jobDescriptor.dimensions[1] = dispatchSrcY; @@ -1020,7 +1025,7 @@ FfxErrorCode ffxFsr2ContextGenerateReactiveMask(FfxFsr2Context* context, const F jobDescriptor.cbs[0].uint32Size = sizeof(constants); memcpy(&jobDescriptor.cbs[0].data, &constants, sizeof(constants)); - wcscpy_s(jobDescriptor.cbNames[0], pipeline->cbResourceBindings[0].name); + wcscpy(jobDescriptor.cbNames[0], pipeline->cbResourceBindings[0].name); FfxGpuJobDescription dispatchJob = { FFX_GPU_JOB_COMPUTE }; dispatchJob.computeJobDescriptor = jobDescriptor; diff --git a/src/ffx-fsr2-api/ffx_types.h b/src/ffx-fsr2-api/ffx_types.h index 75fb0e8..775d334 100644 --- a/src/ffx-fsr2-api/ffx_types.h +++ b/src/ffx-fsr2-api/ffx_types.h @@ -22,6 +22,7 @@ #pragma once #include +#include #if defined (FFX_GCC) /// FidelityFX exported functions From e124780b8385d8db11500ca557ed22603ac9499f Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 30 Sep 2022 13:25:54 +0200 Subject: [PATCH 02/11] Add compatibility via wine Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/CMakeLists.txt | 9 +++++++-- tools/sc/FidelityFX_SC.sh | 2 ++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100755 tools/sc/FidelityFX_SC.sh diff --git a/src/ffx-fsr2-api/CMakeLists.txt b/src/ffx-fsr2-api/CMakeLists.txt index 6a456bf..4a4007b 100644 --- a/src/ffx-fsr2-api/CMakeLists.txt +++ b/src/ffx-fsr2-api/CMakeLists.txt @@ -69,8 +69,13 @@ if(FSR2_VS_VERSION STREQUAL 2015) set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION "10.0.18362.0") endif() -set(FFX_SC_EXECUTABLE - ${CMAKE_CURRENT_SOURCE_DIR}/../../tools/sc/FidelityFX_SC.exe) +if (WIN32) + set(FFX_SC_EXECUTABLE + ${CMAKE_CURRENT_SOURCE_DIR}/../../tools/sc/FidelityFX_SC.exe) +else() + set(FFX_SC_EXECUTABLE + ${CMAKE_CURRENT_SOURCE_DIR}/../../tools/sc/FidelityFX_SC.sh) +endif() set(FFX_SC_BASE_ARGS -reflection -deps=gcc -DFFX_GPU=1 diff --git a/tools/sc/FidelityFX_SC.sh b/tools/sc/FidelityFX_SC.sh new file mode 100755 index 0000000..5e20996 --- /dev/null +++ b/tools/sc/FidelityFX_SC.sh @@ -0,0 +1,2 @@ +#!/bin/sh +wine $(dirname "$0")/FidelityFX_SC.exe $@ From 61f48eed1777377ab2fed6e99837b3cfd8cf1d4e Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 30 Sep 2022 13:39:53 +0200 Subject: [PATCH 03/11] Add branch for specific compiler flags Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ffx-fsr2-api/CMakeLists.txt b/src/ffx-fsr2-api/CMakeLists.txt index 4a4007b..1e2bf69 100644 --- a/src/ffx-fsr2-api/CMakeLists.txt +++ b/src/ffx-fsr2-api/CMakeLists.txt @@ -51,8 +51,10 @@ else() message(FATAL_ERROR "Unsupported target platform - only supporting x64 and Win32 currently") endif() -# Embed PDBs in the debug versions of the libs -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7") +if (MSVC) + # Embed PDBs in the debug versions of the libs + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Z7") +endif() # Write both debug and release versions of the static libs to the /lib folder as they are uniquely named set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_HOME_DIRECTORY}/bin/ffx_fsr2_api/) From 506db081f35681ddaf9df8039f3163ea2575f84e Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 30 Sep 2022 13:54:19 +0200 Subject: [PATCH 04/11] Expose target name to parent scope as variable Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ffx-fsr2-api/CMakeLists.txt b/src/ffx-fsr2-api/CMakeLists.txt index 1e2bf69..fc48d80 100644 --- a/src/ffx-fsr2-api/CMakeLists.txt +++ b/src/ffx-fsr2-api/CMakeLists.txt @@ -109,14 +109,20 @@ else() add_library(ffx_fsr2_api_${FSR2_PLATFORM_NAME} STATIC ${SOURCES}) endif() +set(FFX_FSR2_API ffx_fsr2_api_${FSR2_PLATFORM_NAME} PARENT_SCOPE) + # graphics api backends if(FFX_FSR2_API_DX12) message("Will build FSR2 library: DX12 backend") add_subdirectory(dx12) + + set(FFX_FSR2_API_DX12 ffx_fsr2_api_dx12_${FSR2_PLATFORM_NAME} PARENT_SCOPE) endif() if(FFX_FSR2_API_VK) message("Will build FSR2 library: Vulkan backend") add_subdirectory(vk) + + set(FFX_FSR2_API_VK ffx_fsr2_api_vk_${FSR2_PLATFORM_NAME} PARENT_SCOPE) endif() # api From a5e08514d4362b18d0fb10ef5640d35105714d60 Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 30 Sep 2022 14:50:32 +0200 Subject: [PATCH 05/11] Fix bash permutation of shader compile definitions Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/CMakeLists.txt | 13 +++++++------ src/ffx-fsr2-api/vk/CMakeLists.txt | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ffx-fsr2-api/CMakeLists.txt b/src/ffx-fsr2-api/CMakeLists.txt index fc48d80..8b91258 100644 --- a/src/ffx-fsr2-api/CMakeLists.txt +++ b/src/ffx-fsr2-api/CMakeLists.txt @@ -92,12 +92,13 @@ set(FFX_SC_BASE_ARGS set(FFX_SC_PERMUTATION_ARGS # Reproject can use either reference lanczos or LUT - -DFFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE={0,1} - -DFFX_FSR2_OPTION_HDR_COLOR_INPUT={0,1} - -DFFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS={0,1} - -DFFX_FSR2_OPTION_JITTERED_MOTION_VECTORS={0,1} - -DFFX_FSR2_OPTION_INVERTED_DEPTH={0,1} - -DFFX_FSR2_OPTION_APPLY_SHARPENING={0,1}) + '-DFFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE={0,1}' + '-DFFX_FSR2_OPTION_HDR_COLOR_INPUT={0,1}' + '-DFFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS={0,1}' + '-DFFX_FSR2_OPTION_JITTERED_MOTION_VECTORS={0,1}' + '-DFFX_FSR2_OPTION_INVERTED_DEPTH={0,1}' + '-DFFX_FSR2_OPTION_APPLY_SHARPENING={0,1}' +) file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" diff --git a/src/ffx-fsr2-api/vk/CMakeLists.txt b/src/ffx-fsr2-api/vk/CMakeLists.txt index 933d097..03843df 100644 --- a/src/ffx-fsr2-api/vk/CMakeLists.txt +++ b/src/ffx-fsr2-api/vk/CMakeLists.txt @@ -80,7 +80,7 @@ foreach(PASS_SHADER ${PASS_SHADERS}) # skip 16-bit permutations for the compute luminance pyramid pass set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_VK_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} -DFFX_HALF=0) else() - set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_VK_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} -DFFX_HALF={0,1}) + set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_VK_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} '-DFFX_HALF={0,1}') endif() if(USE_DEPFILE) @@ -107,4 +107,4 @@ add_custom_target(shader_permutations_vk DEPENDS ${PERMUTATION_OUTPUTS}) add_dependencies(${FFX_SC_DEPENDENT_TARGET} shader_permutations_vk) source_group("source" FILES ${VK}) -source_group("shaders" FILES ${SHADERS}) \ No newline at end of file +source_group("shaders" FILES ${SHADERS}) From 902e61d5bbc1939c9df63a53bc6b761d3c6fc601 Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 30 Sep 2022 14:53:50 +0200 Subject: [PATCH 06/11] Fix last compile errors with gcc Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp index 867da60..875bd7b 100644 --- a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp +++ b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp @@ -27,6 +27,7 @@ #include #include #include +#include // prototypes for functions in the interface FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDeviceCapabilities* deviceCapabilities, FfxDevice device); @@ -551,7 +552,7 @@ FfxResource ffxGetTextureResourceVK(FfxFsr2Context* context, VkImage imgVk, VkIm #ifdef _DEBUG if (name) { - wcscpy_s(resource.name, name); + wcscpy(resource.name, name); } #endif @@ -575,7 +576,7 @@ FfxResource ffxGetBufferResourceVK(FfxFsr2Context* context, VkBuffer bufVk, uint #ifdef _DEBUG if (name) { - wcscpy_s(resource.name, name); + wcscpy(resource.name, name); } #endif @@ -1298,17 +1299,17 @@ FfxErrorCode CreatePipelineVK(FfxFsr2Interface* backendInterface, FfxFsr2Pass pa for (uint32_t srvIndex = 0; srvIndex < outPipeline->srvCount; ++srvIndex) { outPipeline->srvResourceBindings[srvIndex].slotIndex = shaderBlob.boundSampledImageBindings[srvIndex]; - wcscpy_s(outPipeline->srvResourceBindings[srvIndex].name, converter.from_bytes(shaderBlob.boundSampledImageNames[srvIndex]).c_str()); + wcscpy(outPipeline->srvResourceBindings[srvIndex].name, converter.from_bytes(shaderBlob.boundSampledImageNames[srvIndex]).c_str()); } for (uint32_t uavIndex = 0; uavIndex < outPipeline->uavCount; ++uavIndex) { outPipeline->uavResourceBindings[uavIndex].slotIndex = shaderBlob.boundStorageImageBindings[uavIndex]; - wcscpy_s(outPipeline->uavResourceBindings[uavIndex].name, converter.from_bytes(shaderBlob.boundStorageImageNames[uavIndex]).c_str()); + wcscpy(outPipeline->uavResourceBindings[uavIndex].name, converter.from_bytes(shaderBlob.boundStorageImageNames[uavIndex]).c_str()); } for (uint32_t cbIndex = 0; cbIndex < outPipeline->constCount; ++cbIndex) { outPipeline->cbResourceBindings[cbIndex].slotIndex = shaderBlob.boundUniformBufferBindings[cbIndex]; - wcscpy_s(outPipeline->cbResourceBindings[cbIndex].name, converter.from_bytes(shaderBlob.boundUniformBufferNames[cbIndex]).c_str()); + wcscpy(outPipeline->cbResourceBindings[cbIndex].name, converter.from_bytes(shaderBlob.boundUniformBufferNames[cbIndex]).c_str()); } // create descriptor set layout @@ -1913,4 +1914,4 @@ FfxErrorCode DestroyPipelineVK(FfxFsr2Interface* backendInterface, FfxPipelineSt } return FFX_OK; -} \ No newline at end of file +} From 0ce4ff5c5a0210273be7e3085bb4b15d0590431c Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 30 Sep 2022 15:04:45 +0200 Subject: [PATCH 07/11] Adjust branch for clang and other compilers Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ffx-fsr2-api/CMakeLists.txt b/src/ffx-fsr2-api/CMakeLists.txt index 8b91258..89417c0 100644 --- a/src/ffx-fsr2-api/CMakeLists.txt +++ b/src/ffx-fsr2-api/CMakeLists.txt @@ -44,8 +44,8 @@ elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32" OR CMAKE_EXE_LINKER_FLAGS STREQ elseif(CMAKE_SYSTEM_PROCESSOR) set(FSR2_PLATFORM_NAME ${CMAKE_SYSTEM_PROCESSOR}) - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - add_compile_definitions(FFX_GCC) + if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (NOT MSVC)) + add_compile_definitions(FFX_GCC) # Should work with gcc and others endif() else() message(FATAL_ERROR "Unsupported target platform - only supporting x64 and Win32 currently") From 59950a85247baa4e099537324912a1f0e3a7b5d5 Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Thu, 20 Oct 2022 19:00:06 +0200 Subject: [PATCH 08/11] Fix issues with build on Windows Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/CMakeLists.txt | 33 +++++++++++++++++++++--------- src/ffx-fsr2-api/vk/CMakeLists.txt | 9 ++++++-- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/ffx-fsr2-api/CMakeLists.txt b/src/ffx-fsr2-api/CMakeLists.txt index 89417c0..65473e8 100644 --- a/src/ffx-fsr2-api/CMakeLists.txt +++ b/src/ffx-fsr2-api/CMakeLists.txt @@ -88,17 +88,30 @@ set(FFX_SC_BASE_ARGS -DFFX_FSR2_OPTION_POSTPROCESSLOCKSTATUS_SAMPLERS_USE_DATA_HALF=0 # Upsample uses lanczos approximation -DFFX_FSR2_OPTION_UPSAMPLE_USE_LANCZOS_TYPE=2 - ) - -set(FFX_SC_PERMUTATION_ARGS - # Reproject can use either reference lanczos or LUT - '-DFFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE={0,1}' - '-DFFX_FSR2_OPTION_HDR_COLOR_INPUT={0,1}' - '-DFFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS={0,1}' - '-DFFX_FSR2_OPTION_JITTERED_MOTION_VECTORS={0,1}' - '-DFFX_FSR2_OPTION_INVERTED_DEPTH={0,1}' - '-DFFX_FSR2_OPTION_APPLY_SHARPENING={0,1}' ) + +if (WIN32) + set(FFX_SC_PERMUTATION_ARGS + # Reproject can use either reference lanczos or LUT + -DFFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE={0,1} + -DFFX_FSR2_OPTION_HDR_COLOR_INPUT={0,1} + -DFFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS={0,1} + -DFFX_FSR2_OPTION_JITTERED_MOTION_VECTORS={0,1} + -DFFX_FSR2_OPTION_INVERTED_DEPTH={0,1} + -DFFX_FSR2_OPTION_APPLY_SHARPENING={0,1} + ) +else() + # Fix bash curly braces replacement + set(FFX_SC_PERMUTATION_ARGS + # Reproject can use either reference lanczos or LUT + '-DFFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE={0,1}' + '-DFFX_FSR2_OPTION_HDR_COLOR_INPUT={0,1}' + '-DFFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS={0,1}' + '-DFFX_FSR2_OPTION_JITTERED_MOTION_VECTORS={0,1}' + '-DFFX_FSR2_OPTION_INVERTED_DEPTH={0,1}' + '-DFFX_FSR2_OPTION_APPLY_SHARPENING={0,1}' + ) +endif() file(GLOB SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp" diff --git a/src/ffx-fsr2-api/vk/CMakeLists.txt b/src/ffx-fsr2-api/vk/CMakeLists.txt index 03843df..6a182ef 100644 --- a/src/ffx-fsr2-api/vk/CMakeLists.txt +++ b/src/ffx-fsr2-api/vk/CMakeLists.txt @@ -80,8 +80,13 @@ foreach(PASS_SHADER ${PASS_SHADERS}) # skip 16-bit permutations for the compute luminance pyramid pass set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_VK_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} -DFFX_HALF=0) else() - set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_VK_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} '-DFFX_HALF={0,1}') - endif() + if (WIN32) + set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_VK_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} -DFFX_HALF={0,1}) + else() + # Fix bash curly braces replacement + set(FFX_SC_ARGS ${FFX_SC_BASE_ARGS} ${FFX_SC_VK_BASE_ARGS} ${FFX_SC_PERMUTATION_ARGS} '-DFFX_HALF={0,1}') + endif() + endif() if(USE_DEPFILE) add_custom_command( From 55e8f935c5bf11dd7554857f1f69a8422da83b6f Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Tue, 10 Jan 2023 18:38:31 -0500 Subject: [PATCH 09/11] Fix abs() on gcc --- src/ffx-fsr2-api/ffx_fsr2.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ffx-fsr2-api/ffx_fsr2.cpp b/src/ffx-fsr2-api/ffx_fsr2.cpp index 057a6af..0d9adcc 100644 --- a/src/ffx-fsr2-api/ffx_fsr2.cpp +++ b/src/ffx-fsr2-api/ffx_fsr2.cpp @@ -94,7 +94,7 @@ static const ResourceBinding uavResourceBindingTable[] = {FFX_FSR2_RESOURCE_IDENTIFIER_DILATED_REACTIVE_MASKS, L"rw_dilated_reactive_masks"}, {FFX_FSR2_RESOURCE_IDENTIFIER_EXPOSURE, L"rw_exposure"}, {FFX_FSR2_RESOURCE_IDENTIFIER_SPD_ATOMIC_COUNT, L"rw_spd_global_atomic"}, -#if defined(FFX_INTERNAL) +#if defined(FFX_INTERNAL) {FFX_FSR2_RESOURCE_IDENTIFIER_DEBUG_OUTPUT, L"rw_debug_out"}, #endif }; @@ -166,7 +166,7 @@ FfxConstantBuffer globalFsr2ConstantBuffers[3] = { // Lanczos static float lanczos2(float value) { - return abs(value) < FFX_EPSILON ? 1.f : (sinf(FFX_PI * value) / (FFX_PI * value)) * (sinf(0.5f * FFX_PI * value) / (0.5f * FFX_PI * value)); + return std::abs(value) < FFX_EPSILON ? 1.f : (sinf(FFX_PI * value) / (FFX_PI * value)) * (sinf(0.5f * FFX_PI * value) / (0.5f * FFX_PI * value)); } // Calculate halton number for index and base. @@ -266,7 +266,7 @@ static FfxErrorCode createPipelineStates(FfxFsr2Context_Private* context) FFX_VALIDATE(context->contextDescription.callbacks.fpCreatePipeline(&context->contextDescription.callbacks, FFX_FSR2_PASS_ACCUMULATE, &pipelineDescription, &context->pipelineAccumulate)); FFX_VALIDATE(context->contextDescription.callbacks.fpCreatePipeline(&context->contextDescription.callbacks, FFX_FSR2_PASS_ACCUMULATE_SHARPEN, &pipelineDescription, &context->pipelineAccumulateSharpen)); FFX_VALIDATE(context->contextDescription.callbacks.fpCreatePipeline(&context->contextDescription.callbacks, FFX_FSR2_PASS_GENERATE_REACTIVE, &pipelineDescription, &context->pipelineGenerateReactive)); - + // for each pipeline: re-route/fix-up IDs based on names patchResourceBindings(&context->pipelinePrepareInputColor); patchResourceBindings(&context->pipelineDepthClip); @@ -349,7 +349,7 @@ static FfxErrorCode fsr2Create(FfxFsr2Context_Private* context, const FfxFsr2Con { FFX_FSR2_RESOURCE_IDENTIFIER_DEPTH_CLIP, L"FSR2_DepthClip", FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R8_UNORM, contextDescription->maxRenderSize.width, contextDescription->maxRenderSize.height, 1, FFX_RESOURCE_FLAGS_ALIASABLE }, - + { FFX_FSR2_RESOURCE_IDENTIFIER_LOCK_STATUS_1, L"FSR2_LockStatus1", (FfxResourceUsage)(FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV), FFX_SURFACE_FORMAT_R11G11B10_FLOAT, contextDescription->displaySize.width, contextDescription->displaySize.height, 1, FFX_RESOURCE_FLAGS_NONE }, @@ -510,7 +510,7 @@ static void scheduleDispatch(FfxFsr2Context_Private* context, const FfxFsr2Dispa jobDescriptor.uavMip[currentUnorderedAccessViewIndex] = 0; } } - + jobDescriptor.dimensions[0] = dispatchX; jobDescriptor.dimensions[1] = dispatchY; jobDescriptor.dimensions[2] = 1; @@ -591,7 +591,7 @@ static FfxErrorCode fsr2Dispatch(FfxFsr2Context_Private* context, const FfxFsr2D context->contextDescription.callbacks.fpRegisterResource(&context->contextDescription.callbacks, ¶ms->exposure, &context->srvResources[FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_EXPOSURE]); } } - + if (ffxFsr2ResourceIsNull(params->reactive)) { context->srvResources[FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_REACTIVE_MASK] = context->srvResources[FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_DEFAULT_REACTIVITY]; } else { From ec9fcf97f4241ed0a967b7a31c769ec993535d83 Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 13 Jan 2023 14:38:45 +0100 Subject: [PATCH 10/11] Fix Vulkan spec violation regarding requiredSubgroupSizeStages with subgroupSizeControl Signed-off-by: TheJackiMonster --- src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp index 4768708..cc12022 100644 --- a/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp +++ b/src/ffx-fsr2-api/vk/ffx_fsr2_vk.cpp @@ -720,9 +720,11 @@ FfxErrorCode GetDeviceCapabilitiesVK(FfxFsr2Interface* backendInterface, FfxDevi deviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; deviceProperties2.pNext = &subgroupSizeControlProperties; vkGetPhysicalDeviceProperties2(context->physicalDevice, &deviceProperties2); - - deviceCapabilities->waveLaneCountMin = subgroupSizeControlProperties.minSubgroupSize; - deviceCapabilities->waveLaneCountMax = subgroupSizeControlProperties.maxSubgroupSize; + + if (subgroupSizeControlProperties.requiredSubgroupSizeStages & VK_SHADER_STAGE_COMPUTE_BIT) { + deviceCapabilities->waveLaneCountMin = subgroupSizeControlProperties.minSubgroupSize; + deviceCapabilities->waveLaneCountMax = subgroupSizeControlProperties.maxSubgroupSize; + } } if (strcmp(backendContext->extensionProperties[i].extensionName, VK_KHR_SHADER_FLOAT16_INT8_EXTENSION_NAME) == 0) { From a10cd3c227424a34f4f1b3a287753dbdecbbe272 Mon Sep 17 00:00:00 2001 From: TheJackiMonster Date: Fri, 3 Mar 2023 02:36:46 +0100 Subject: [PATCH 11/11] Implement python script to remove wine requirement Signed-off-by: TheJackiMonster --- tools/sc/FidelityFX_SC.py | 291 ++++++++++++++++++++++++++++++++++++++ tools/sc/FidelityFX_SC.sh | 7 +- 2 files changed, 297 insertions(+), 1 deletion(-) create mode 100755 tools/sc/FidelityFX_SC.py diff --git a/tools/sc/FidelityFX_SC.py b/tools/sc/FidelityFX_SC.py new file mode 100755 index 0000000..f5300b5 --- /dev/null +++ b/tools/sc/FidelityFX_SC.py @@ -0,0 +1,291 @@ +#!/bin/python + +import argparse +import hashlib +import json +import mmap +import os +import subprocess + + +def hash_file(path): + algorithm = hashlib.md5() + with open(path, 'rb') as file: + with mmap.mmap(file.fileno(), 0, prot=mmap.PROT_READ) as memory: + algorithm.update(memory) + return algorithm.hexdigest() + + +def append_resources(code, name, data, key, resource_name): + if not key in data: + return + + for res in data[key]: + if res['name'][-2:] == '_t': + res['name'] = res['name'][:-2] + + data[key].sort(key=lambda res: res['binding']) + + code.append('static const char* g_{0}_{1}ResourceNames[] ='.format(name, resource_name)) + code.append('{ ' + ', '.join(['"{0}"'.format(res['name']) for res in data[key]]) + ', };') + code.append('static const uint32_t g_{0}_{1}ResourceBindings[] ='.format(name, resource_name)) + code.append('{ ' + ', '.join([str(res['binding']) for res in data[key]]) + ', };') + code.append('static const uint32_t g_{0}_{1}ResourceCounts[] ='.format(name, resource_name)) + code.append('{ ' + ', '.join(['1' for res in data[key]]) + ', };') + code.append('static const uint32_t g_{0}_{1}ResourceSets[] ='.format(name, resource_name)) + code.append('{ ' + ', '.join([str(res['set']) for res in data[key]]) + ', };') + code.append('') + + +def process(file, name, args, output, optimization, reflection): + spirv_path = os.path.join(output, name + '.spv') + subprocess.run(['glslangValidator', '-V', *args, '-o', spirv_path, file]) + + if optimization: + optimized_spirv_path = spirv_path + '_opt' + subprocess.run(['spirv-opt', '-Os', spirv_path, '-o', optimized_spirv_path]) + os.rename(optimized_spirv_path, spirv_path) + + spirv_hash = hash_file(spirv_path) + name = '{0}_{1}'.format(name, str(spirv_hash)) + hash_path = os.path.join(output, name + '.spv') + + if os.path.exists(hash_path): + os.remove(spirv_path) + return name, dict() + else: + os.rename(spirv_path, hash_path) + spirv_path = hash_path + + spirv = list() + with open(spirv_path, 'rb') as spirv_file: + spirv = list(spirv_file.read()) + + data = dict() + if reflection: + json_path = os.path.join(output, name + '.json') + subprocess.run(['spirv-cross', '-V', spirv_path, '--reflect', '--output', json_path]) + + with open(json_path) as json_file: + data = json.load(json_file) + + os.remove(json_path) + + code = ['// {0}.h.'.format(name), '// Auto generated by FidelityFX-SC.py.', ''] + + append_resources(code, name, data, 'separate_samplers', 'Sampler') + append_resources(code, name, data, 'combined_samplers', 'CombinedSampler') + append_resources(code, name, data, 'separate_images', 'SampledImage') + append_resources(code, name, data, 'images', 'StorageImage') + append_resources(code, name, data, 'uniform_texel_buffers', 'UniformTexelBuffer') + append_resources(code, name, data, 'storage_texel_buffers', 'StorageTexelBuffer') + append_resources(code, name, data, 'ubos', 'UniformBuffer') + append_resources(code, name, data, 'sbos', 'StorageBuffer') + append_resources(code, name, data, 'inputs', 'InputAttachment') + append_resources(code, name, data, 'acceleration_structures', 'AccelerationStructure') + + code.append('static const uint32_t g_{0}_size = {1};'.format(name, len(spirv))) + code.append('') + code.append('static const unsigned char g_{0}_data[] = '.format(name) + '{') + + for i in range(0, len(spirv), 16): + line = ','.join(map('0x{0:02x}'.format, spirv[i:i + 16])) + if i + 16 < len(spirv): + line = line + ',' + code.append(line) + + code.append('};') + code_path = os.path.join(output, name + '.h') + with open(code_path, 'w') as code_file: + code_file.write('\n'.join(code)) + + return name, data + + +def append_resources_info(code, resources_name, resource_name): + code.append('\tconst uint32_t num{0}Resources;'.format(resources_name)) + code.append('\tconst char** {0}ResourceNames;'.format(resource_name)) + code.append('\tconst uint32_t* {0}ResourceBindings;'.format(resource_name)) + code.append('\tconst uint32_t* {0}ResourceCounts;'.format(resource_name)) + code.append('\tconst uint32_t* {0}ResourceSets;'.format(resource_name)) + code.append('') + + +def append_info_resource(code, name, data, key, resource_name): + if key in data: + code.append('\t\t{0},'.format(str(len(data[key])))) + code.append('\t\tg_{0}_{1}ResourceNames,'.format(name, resource_name)) + code.append('\t\tg_{0}_{1}ResourceBindings,'.format(name, resource_name)) + code.append('\t\tg_{0}_{1}ResourceCounts,'.format(name, resource_name)) + code.append('\t\tg_{0}_{1}ResourceSets,'.format(name, resource_name)) + else: + code.append('\t\t0, 0, 0, 0, 0,') + + +def append_info(code, name, data): + code.append('\t{') + code.append('\t\tg_{0}_size,'.format(name)) + code.append('\t\tg_{0}_data,'.format(name)) + + append_info_resource(code, name, data, 'separate_samplers', 'Sampler') + append_info_resource(code, name, data, 'combined_samplers', 'CombinedSampler') + append_info_resource(code, name, data, 'separate_images', 'SampledImage') + append_info_resource(code, name, data, 'images', 'StorageImage') + append_info_resource(code, name, data, 'uniform_texel_buffers', 'UniformTexelBuffer') + append_info_resource(code, name, data, 'storage_texel_buffers', 'StorageTexelBuffer') + append_info_resource(code, name, data, 'ubos', 'UniformBuffer') + append_info_resource(code, name, data, 'ssbos', 'StorageBuffer') + append_info_resource(code, name, data, 'inputs', 'InputAttachment') + append_info_resource(code, name, data, 'acceleration_structures', 'AccelerationStructure') + + code.append('\t},') + + +def main(args): + permutations = list() + permutations.append(list()) + permutation_variables = list() + + for definition in args.definitions: + name, value = definition.split('=') + + if value[0] == '{' and value[-1] == '}': + values = value[1:-1].split(',') + new_permutations = list() + permutation_variables.append(name) + + for val in values: + for permutation in permutations: + new_permutation = permutation.copy() + new_permutation.append("-D{0}={1}".format(name, val)) + new_permutations.append(new_permutation) + + permutations = new_permutations + else: + for permutation in permutations: + permutation.append("-D{0}={1}".format(name, value)) + + for permutation in permutations: + permutation.append('-e') + permutation.append(args.entry_point) + permutation.append('-I{0}'.format(args.includes)) + permutation.append('-S') + permutation.append(args.stage) + permutation.append('--target-env') + permutation.append(args.target_env) + + if args.undefinitions is None: + continue + + for undefinition in args.undefinitions: + permutation.append("-U{0}".format(undefinition)) + + optimization = (args.optimization == 's') + for j, file in enumerate(args.files): + if len(args.files) == 1: + file_name = args.name + else: + file_name = '{0}_{1}'.format(args.name, str(j)) + + if len(permutations) > 0: + code_name = '{0}_permutations.h'.format(file_name) + else: + code_name = '{0}.h'.format(file_name) + + code = list() + code_path = os.path.join(args.output, code_name) + + names = list() + datas = list() + for i, permutation in enumerate(permutations): + name, data = process(file, file_name, permutation, args.output, optimization, args.reflection) + names.append(name) + datas.append(data) + + for name in names: + spirv_path = os.path.join(args.output, name + '.spv') + if os.path.exists(spirv_path): + os.remove(spirv_path) + + infos = list() + indices = [names.index(name) for name in names] + indirections = list() + + for i, index in enumerate(indices): + if i == index: + code.append('#include "{0}.h"'.format(names[index])) + indirections.append(len(infos)) + infos.append({ 'name': names[index], 'data': datas[index] }) + else: + indirections.append(None) + + for i, index in enumerate(indices): + if indirections[i] is None: + indirections[i] = indirections[index] + + code.append('') + code.append('typedef union {0}_PermutationKey '.format(file_name) + '{') + code.append('\tstruct {') + + for variable in permutation_variables: + code.append('\t\tuint32_t {0} : 1;'.format(variable)) + + code.append('\t};') + code.append('\tuint32_t index;') + code.append('}' + ' {0}_PermutationKey;'.format(file_name)) + code.append('') + + code.append('typedef struct {0}_PermutationInfo '.format(file_name) + '{') + code.append('\tconst uint32_t blobSize;') + code.append('\tconst unsigned char* blobData;') + code.append('') + + append_resources_info(code, 'Sampler', 'sampler') + append_resources_info(code, 'CombinedSampler', 'combinedSampler') + append_resources_info(code, 'SampledImage', 'sampledImage') + append_resources_info(code, 'StorageImage', 'storageImage') + append_resources_info(code, 'UniformTexelBuffer', 'uniformTexelBuffer') + append_resources_info(code, 'StorageTexelBuffer', 'storageTexelBuffer') + append_resources_info(code, 'UniformBuffer', 'uniformBuffer') + append_resources_info(code, 'StorageBuffer', 'storageBuffer') + append_resources_info(code, 'InputAttachment', 'inputAttachment') + append_resources_info(code, 'RTAccelerationStructure', 'rtAccelerationStructure') + + code.append('}' + ' {0}_PermutationInfo;'.format(file_name)) + code.append('') + + code.append('static const uint32_t g_{0}_IndirectionTable[] = '.format(file_name) + '{') + for index in indirections: + code.append('\t{0},'.format(index)) + code.append('};') + code.append('') + + code.append('static const {0}_PermutationInfo g_{0}_PermutationInfo[] = '.format(file_name) + '{') + for info in infos: + append_info(code, info['name'], info['data']) + code.append('};') + + with open(code_path, 'w') as code_file: + code_file.write('\n'.join(code)) + + with open(code_path + '.d', 'w') as code_file: + code_file.write('{0}:'.format(code_name)) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('files', metavar='FILE', type=str, nargs='+') + parser.add_argument('-compiler', choices=['glslang']) + parser.add_argument('-deps', choices=['gcc']) + parser.add_argument('-D', action='append', dest='definitions') + parser.add_argument('-e', dest='entry_point') + parser.add_argument('-I', dest='includes') + parser.add_argument('-name') + parser.add_argument('-O', choices=['d', 's'], dest='optimization') + parser.add_argument('-output') + parser.add_argument('-reflection', action='store_true') + parser.add_argument('-S', dest='stage') + parser.add_argument('--target-env', dest='target_env') + parser.add_argument('-U', action='append', dest='undefinitions') + main(parser.parse_args()) + diff --git a/tools/sc/FidelityFX_SC.sh b/tools/sc/FidelityFX_SC.sh index 5e20996..7765186 100755 --- a/tools/sc/FidelityFX_SC.sh +++ b/tools/sc/FidelityFX_SC.sh @@ -1,2 +1,7 @@ #!/bin/sh -wine $(dirname "$0")/FidelityFX_SC.exe $@ + +### Run the original binary via wine: +# wine $(dirname "$0")/FidelityFX_SC.exe $@ + +### Run the reverse-engineered python script: +python $(dirname $0)/FidelityFX_SC.py $@