From fffd0197ccec83e06c85ff647a6b8dc07c2166bb Mon Sep 17 00:00:00 2001 From: Aleksei Tumakaev Date: Thu, 26 Sep 2024 00:42:41 +0200 Subject: [PATCH] Changes to meet hybrid requirements --- ffx-api/CMakeLists.txt | 98 +++++--- ffx-api/include/ffx_api/dx12/ffx_api_dx12.h | 46 +++- ffx-api/include/ffx_api/dx12/ffx_api_dx12.hpp | 55 +++++ .../ffx_api/dx12/ffx_api_loader_dx12.h | 48 ++++ ffx-api/include/ffx_api/ffx_api.h | 41 +--- ffx-api/include/ffx_api/ffx_api.hpp | 86 ++----- .../ffx_api_loader_vk.h} | 27 ++- ffx-api/include/ffx_api/vk/ffx_api_vk.h | 46 +++- ffx-api/include/ffx_api/vk/ffx_api_vk.hpp | 55 +++++ ffx-api/src/dx12/ffx_api_dx12.cpp | 110 +++++++++ ...provider_framegenerationswapchain_dx12.cpp | 2 +- .../src/{ffx_api.cpp => vk/ffx_api_vk.cpp} | 16 +- ...x_provider_framegenerationswapchain_vk.cpp | 2 +- sdk/CMakeLists.txt | 54 +++-- .../FidelityFX/gpu/CMakeCompileShaders.txt | 4 +- ...meinterpolation_game_motion_vector_field.h | 2 +- .../FidelityFX/host/backends/dx12/ffx_dx12.h | 2 +- .../FidelityFX/host/backends/vk/ffx_vk.h | 2 +- sdk/include/FidelityFX/host/ffx_assert.h | 4 +- .../FrameInterpolationSwapchainDX12.cpp | 12 +- ...rameInterpolationSwapchainDX12_Helpers.cpp | 2 +- .../FrameInterpolationSwapchainDX12_Helpers.h | 2 +- ...terpolationSwapchainDX12_UiComposition.cpp | 25 ++ sdk/src/backends/dx12/ffx_dx12.cpp | 36 ++- .../FrameInterpolationSwapchainVK.cpp | 223 +++++++++++++++++- .../FrameInterpolationSwapchainVK_Helpers.cpp | 2 +- .../FrameInterpolationSwapchainVK_Helpers.h | 2 +- .../ffx_frameinterpolation.cpp | 2 +- sdk/toolchain.cmake | 7 +- 29 files changed, 808 insertions(+), 205 deletions(-) create mode 100644 ffx-api/include/ffx_api/dx12/ffx_api_loader_dx12.h rename ffx-api/include/ffx_api/{ffx_api_loader.h => vk/ffx_api_loader_vk.h} (63%) create mode 100644 ffx-api/src/dx12/ffx_api_dx12.cpp rename ffx-api/src/{ffx_api.cpp => vk/ffx_api_vk.cpp} (85%) diff --git a/ffx-api/CMakeLists.txt b/ffx-api/CMakeLists.txt index bfedd6d5..bd7b2695 100644 --- a/ffx-api/CMakeLists.txt +++ b/ffx-api/CMakeLists.txt @@ -27,14 +27,17 @@ if(POLICY CMP0147) cmake_policy(SET CMP0147 NEW) endif() -if (FFX_API_BACKEND STREQUAL VK_X64) - set(FFX_PLATFORM_NAME vk) +set(FFX_PLATFORM_NAME_VK vk) +set(FFX_PLATFORM_NAME_DX12 dx12) + +if(FFX_API_BACKEND_VK_X64 AND + FFX_API_BACKEND_DX12_X64) + project(FFX_API_${FFX_PLATFORM_NAME_VK}_${FFX_PLATFORM_NAME_DX12}) +elseif(FFX_API_BACKEND_VK_X64) + project(FFX_API_${FFX_PLATFORM_NAME_VK}) +elseif(FFX_API_BACKEND_DX12_X64) + project(FFX_API_${FFX_PLATFORM_NAME_VK}) endif() -if (FFX_API_BACKEND STREQUAL DX12_X64) - set(FFX_PLATFORM_NAME dx12) -endif() - -project(FFX_API_${FFX_PLATFORM_NAME}) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -44,19 +47,8 @@ if (MSVC) endif() set(CMAKE_CONFIGURATION_TYPES Debug Release RelWithDebInfo) -set(CMAKE_DEBUG_POSTFIX d) -set(CMAKE_RELWITHDEBINFO_POSTFIX drel) - -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_HOME_DIRECTORY}/bin) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_HOME_DIRECTORY}/bin) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_HOME_DIRECTORY}/bin) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_HOME_DIRECTORY}/bin) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_HOME_DIRECTORY}/bin) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_HOME_DIRECTORY}/bin) -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_HOME_DIRECTORY}/bin) - - +# set(CMAKE_DEBUG_POSTFIX d) +# set(CMAKE_RELWITHDEBINFO_POSTFIX drel) add_compile_definitions(FFXDLL_VERSION_MAJOR=1) add_compile_definitions(FFXDLL_VERSION_MINOR=0) @@ -75,12 +67,11 @@ file(GLOB private_ffx_api file(GLOB public_ffx_api ${CMAKE_CURRENT_SOURCE_DIR}/include/ffx_api/*.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/ffx_api/*.hpp) + ${CMAKE_CURRENT_SOURCE_DIR}/include/ffx_api/*.hpp) -if (FFX_API_BACKEND STREQUAL VK_X64) +if (FFX_API_BACKEND_VK_X64) message(WARNING "Setting FFX_BACKEND_VK") add_compile_definitions(FFXDLL_VERSION_API=VK) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS FFX_BACKEND_VK) file(GLOB private_ffx_api_backend_vk ${CMAKE_CURRENT_SOURCE_DIR}/src/vk/*.h @@ -91,10 +82,9 @@ if (FFX_API_BACKEND STREQUAL VK_X64) ${CMAKE_CURRENT_SOURCE_DIR}/include/ffx_api/vk/*.hpp) endif() -if (FFX_API_BACKEND STREQUAL DX12_X64) +if (FFX_API_BACKEND_DX12_X64) message(WARNING "Setting FFX_BACKEND_DX12") add_compile_definitions(FFXDLL_VERSION_API=DX12) - set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS FFX_BACKEND_DX12) file(GLOB private_ffx_api_backend_dx12 ${CMAKE_CURRENT_SOURCE_DIR}/src/dx12/*.h @@ -105,23 +95,47 @@ if (FFX_API_BACKEND STREQUAL DX12_X64) ${CMAKE_CURRENT_SOURCE_DIR}/include/ffx_api/dx12/*.hpp) endif() -add_library(amd_fidelityfx_${FFX_PLATFORM_NAME} SHARED ${private_ffx_api} ${private_ffx_api_backend_dx12} ${private_ffx_api_backend_vk} ${public_ffx_api} ${public_ffx_api_backend_dx12} ${public_ffx_api_backend_vk}) +if(FFX_API_BACKEND_VK_X64 AND + FFX_API_BACKEND_DX12_X64) + add_library(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} SHARED ${private_ffx_api} ${private_ffx_api_backend_vk} ${public_ffx_api} ${public_ffx_api_backend_vk}) + add_library(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} SHARED ${private_ffx_api} ${private_ffx_api_backend_dx12} ${public_ffx_api} ${public_ffx_api_backend_dx12}) + set_property(TARGET amd_fidelityfx_${FFX_PLATFORM_NAME_VK} APPEND PROPERTY COMPILE_DEFINITIONS FFX_BACKEND_VK) + set_property(TARGET amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} APPEND PROPERTY COMPILE_DEFINITIONS FFX_BACKEND_DX12) +elseif(FFX_API_BACKEND_VK_X64) + add_library(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} SHARED ${private_ffx_api} ${private_ffx_api_backend_vk} ${public_ffx_api} ${public_ffx_api_backend_vk}) + set_property(TARGET amd_fidelityfx_${FFX_PLATFORM_NAME_VK} APPEND PROPERTY COMPILE_DEFINITIONS FFX_BACKEND_VK) +elseif(FFX_API_BACKEND_DX12_X64) + add_library(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} SHARED ${private_ffx_api} ${private_ffx_api_backend_dx12} ${public_ffx_api} ${public_ffx_api_backend_dx12}) + set_property(TARGET amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} APPEND PROPERTY COMPILE_DEFINITIONS FFX_BACKEND_DX12) +endif() source_group("private_source" FILES ${private_ffx_api}) source_group("public_source" FILES ${public_ffx_api}) -if (FFX_API_BACKEND STREQUAL VK_X64) +if (FFX_API_BACKEND_VK_X64) source_group("private_source\\vk" FILES ${private_ffx_api_backend_vk}) source_group("public_source\\vk" FILES ${public_ffx_api_backend_vk}) endif() -if (FFX_API_BACKEND STREQUAL DX12_X64) +if (FFX_API_BACKEND_DX12_X64) source_group("private_source\\dx12" FILES ${private_ffx_api_backend_dx12}) source_group("public_source\\dx12" FILES ${public_ffx_api_backend_dx12}) endif() -target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../sdk/include) + +if(FFX_API_BACKEND_VK_X64 AND + FFX_API_BACKEND_DX12_X64) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../sdk/include) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../sdk/include) +elseif(FFX_API_BACKEND_VK_X64) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../sdk/include) +elseif(FFX_API_BACKEND_DX12_X64) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + target_include_directories(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../sdk/include) +endif() # FSR dependency, must be built before using BuildFidelityFXSDK.bat @@ -134,10 +148,24 @@ set(FFX_AUTO_COMPILE_SHADERS ON) set(FFX_BUILD_AS_DLL OFF) add_subdirectory(../sdk sdk) -target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME} PRIVATE ffx_fsr2_x64 ffx_fsr3upscaler_x64 ffx_opticalflow_x64 ffx_frameinterpolation_x64 DXGI) -if (FFX_API_BACKEND STREQUAL VK_X64) +if(FFX_API_BACKEND_VK_X64 AND + FFX_API_BACKEND_DX12_X64) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PRIVATE ffx_fsr2_x64 ffx_fsr3upscaler_x64 ffx_opticalflow_x64 ffx_frameinterpolation_x64 DXGI) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PRIVATE ffx_fsr2_x64 ffx_fsr3upscaler_x64 ffx_opticalflow_x64 ffx_frameinterpolation_x64 DXGI) +elseif(FFX_API_BACKEND_VK_X64) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PRIVATE ffx_fsr2_x64 ffx_fsr3upscaler_x64 ffx_opticalflow_x64 ffx_frameinterpolation_x64 DXGI) +elseif(FFX_API_BACKEND_DX12_X64) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PRIVATE ffx_fsr2_x64 ffx_fsr3upscaler_x64 ffx_opticalflow_x64 ffx_frameinterpolation_x64 DXGI) +endif() + +if(FFX_API_BACKEND_VK_X64 AND + FFX_API_BACKEND_DX12_X64) + find_package(Vulkan REQUIRED) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PRIVATE Vulkan::Headers ffx_backend_vk_x64) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PRIVATE D3D12 ffx_backend_dx12_x64) +elseif(FFX_API_BACKEND_VK_X64) find_package(Vulkan REQUIRED) - target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME} PRIVATE Vulkan::Headers ffx_backend_vk_x64) -else() # DX12 - target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME} PRIVATE D3D12 ffx_backend_dx12_x64) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_VK} PRIVATE Vulkan::Headers ffx_backend_vk_x64) +elseif(FFX_API_BACKEND_DX12_X64) + target_link_libraries(amd_fidelityfx_${FFX_PLATFORM_NAME_DX12} PRIVATE D3D12 ffx_backend_dx12_x64) endif() diff --git a/ffx-api/include/ffx_api/dx12/ffx_api_dx12.h b/ffx-api/include/ffx_api/dx12/ffx_api_dx12.h index cadfa240..5b6353ae 100644 --- a/ffx-api/include/ffx_api/dx12/ffx_api_dx12.h +++ b/ffx-api/include/ffx_api/dx12/ffx_api_dx12.h @@ -21,12 +21,56 @@ // THE SOFTWARE. #pragma once -#include "../ffx_api.h" #include "../ffx_api_types.h" #include #include #include +#if defined(__cplusplus) +extern "C" { +#endif // #if defined(__cplusplus) + +#include "../ffx_api.h" + +#define FFX_API_ENTRY __declspec(dllexport) +#include + +// Creates a FFX object context. +// Depending on the desc structures provided to this function, the context will be created with the desired version and attributes. +// Non-zero return indicates error code. +// Pointers passed in desc must remain live until ffxDestroyContext is called on the context. +// MemCb may be null; the system allocator (malloc/free) will be used in this case. +FFX_API_ENTRY ffxReturnCode_t ffxCreateContextDX12(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb); +typedef ffxReturnCode_t (*PfnFfxCreateContextDX12)(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb); + +// Destroys an FFX object context. +// Non-zero return indicates error code. +// MemCb must be compatible with the callbacks passed into ffxCreateContext. +FFX_API_ENTRY ffxReturnCode_t ffxDestroyContextDX12(ffxContext* context, const ffxAllocationCallbacks* memCb); +typedef ffxReturnCode_t (*PfnFfxDestroyContextDX12)(ffxContext* context, const ffxAllocationCallbacks* memCb); + +// Configures the provided FFX object context. +// If context is null, configure operates on any global state. +// Non-zero return indicates error code. +FFX_API_ENTRY ffxReturnCode_t ffxConfigureDX12(ffxContext* context, const ffxConfigureDescHeader* desc); +typedef ffxReturnCode_t (*PfnFfxConfigureDX12)(ffxContext* context, const ffxConfigureDescHeader* desc); + +// Queries the provided FFX object context. +// If context is null, query operates on any global state. +// Non-zero return indicates error code. +FFX_API_ENTRY ffxReturnCode_t ffxQueryDX12(ffxContext* context, ffxQueryDescHeader* desc); +typedef ffxReturnCode_t (*PfnFfxQueryDX12)(ffxContext* context, ffxQueryDescHeader* desc); + +// Dispatches work on the given FFX object context defined by the dispatch descriptor. +// Non-zero return indicates error code. +FFX_API_ENTRY ffxReturnCode_t ffxDispatchDX12(ffxContext* context, const ffxDispatchDescHeader* desc); +typedef ffxReturnCode_t (*PfnFfxDispatchDX12)(ffxContext* context, const ffxDispatchDescHeader* desc); + +#if defined(__cplusplus) +} +#endif // #if defined(__cplusplus) + + #define FFX_API_CREATE_CONTEXT_DESC_TYPE_BACKEND_DX12 0x0000002u struct ffxCreateBackendDX12Desc { diff --git a/ffx-api/include/ffx_api/dx12/ffx_api_dx12.hpp b/ffx-api/include/ffx_api/dx12/ffx_api_dx12.hpp index b4af6453..8421d8dc 100644 --- a/ffx-api/include/ffx_api/dx12/ffx_api_dx12.hpp +++ b/ffx-api/include/ffx_api/dx12/ffx_api_dx12.hpp @@ -25,11 +25,66 @@ #include "../ffx_api.hpp" #include "ffx_api_dx12.h" +#include +#include + // Helper types for header initialization. Api definition is in .h file. namespace ffx { +namespace dx12 +{ + +template +inline ReturnCode CreateContext(Context& context, ffxAllocationCallbacks* memCb, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxCreateContextDX12(&context, header, memCb)); +} + +inline ReturnCode DestroyContext(Context& context, ffxAllocationCallbacks* memCb = nullptr) +{ + return detail::ConvertReturnCode(ffxDestroyContextDX12(&context, memCb)); +} + +template +inline ReturnCode Configure(Context& context, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxConfigureDX12(&context, header)); +} + +template +inline ReturnCode Configure(Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxConfigureDX12(nullptr, header)); +} + +template +inline ReturnCode Query(Context& context, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxQueryDX12(&context, header)); +} + +template +inline ReturnCode Query(Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxQueryDX12(nullptr, header)); +} + +template +inline ReturnCode Dispatch(Context& context, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxDispatchDX12(&context, header)); +} + +} // namespace dx12 + template<> struct struct_type : std::integral_constant {}; diff --git a/ffx-api/include/ffx_api/dx12/ffx_api_loader_dx12.h b/ffx-api/include/ffx_api/dx12/ffx_api_loader_dx12.h new file mode 100644 index 00000000..dedb9762 --- /dev/null +++ b/ffx-api/include/ffx_api/dx12/ffx_api_loader_dx12.h @@ -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. + +#pragma once + +#include "ffx_api_dx12.h" +#include + +namespace dx12 +{ + +typedef struct ffxFunctions { + PfnFfxCreateContextDX12 CreateContextDX12; + PfnFfxDestroyContextDX12 DestroyContextDX12; + PfnFfxConfigureDX12 ConfigureDX12; + PfnFfxQueryDX12 QueryDX12; + PfnFfxDispatchDX12 DispatchDX12; +} ffxFunctions; + +static inline void ffxLoadFunctions(ffxFunctions* pOutFunctions, HMODULE module) +{ + pOutFunctions->CreateContextDX12 = (PfnFfxCreateContextDX12)GetProcAddress(module, "ffxCreateContextDX12"); + pOutFunctions->DestroyContextDX12 = (PfnFfxDestroyContextDX12)GetProcAddress(module, "ffxDestroyContextDX12"); + pOutFunctions->ConfigureDX12 = (PfnFfxConfigureDX12)GetProcAddress(module, "ffxConfigureDX12"); + pOutFunctions->QueryDX12 = (PfnFfxQueryDX12)GetProcAddress(module, "ffxQueryDX12"); + pOutFunctions->DispatchDX12 = (PfnFfxDispatchDX12)GetProcAddress(module, "ffxDispatchDX12"); +} + +} // namespace dx12 diff --git a/ffx-api/include/ffx_api/ffx_api.h b/ffx-api/include/ffx_api/ffx_api.h index 0b192d58..9be6d868 100644 --- a/ffx-api/include/ffx_api/ffx_api.h +++ b/ffx-api/include/ffx_api/ffx_api.h @@ -22,11 +22,6 @@ #pragma once -#if defined(__cplusplus) -extern "C" { -#endif // #if defined(__cplusplus) - -#define FFX_API_ENTRY __declspec(dllexport) #include enum FfxApiReturnCodes @@ -40,6 +35,7 @@ enum FfxApiReturnCodes FFX_API_RETURN_ERROR_PARAMETER = 6, ///< A parameter was invalid, e.g. a null pointer, empty resource or out-of-bounds enum value. }; +typedef void* ffxSwapchain; typedef void* ffxContext; typedef uint32_t ffxReturnCode_t; @@ -113,38 +109,3 @@ typedef struct ffxAllocationCallbacks ffxAlloc alloc; ffxDealloc dealloc; } ffxAllocationCallbacks; - -// Creates a FFX object context. -// Depending on the desc structures provided to this function, the context will be created with the desired version and attributes. -// Non-zero return indicates error code. -// Pointers passed in desc must remain live until ffxDestroyContext is called on the context. -// MemCb may be null; the system allocator (malloc/free) will be used in this case. -FFX_API_ENTRY ffxReturnCode_t ffxCreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb); -typedef ffxReturnCode_t (*PfnFfxCreateContext)(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb); - -// Destroys an FFX object context. -// Non-zero return indicates error code. -// MemCb must be compatible with the callbacks passed into ffxCreateContext. -FFX_API_ENTRY ffxReturnCode_t ffxDestroyContext(ffxContext* context, const ffxAllocationCallbacks* memCb); -typedef ffxReturnCode_t (*PfnFfxDestroyContext)(ffxContext* context, const ffxAllocationCallbacks* memCb); - -// Configures the provided FFX object context. -// If context is null, configure operates on any global state. -// Non-zero return indicates error code. -FFX_API_ENTRY ffxReturnCode_t ffxConfigure(ffxContext* context, const ffxConfigureDescHeader* desc); -typedef ffxReturnCode_t (*PfnFfxConfigure)(ffxContext* context, const ffxConfigureDescHeader* desc); - -// Queries the provided FFX object context. -// If context is null, query operates on any global state. -// Non-zero return indicates error code. -FFX_API_ENTRY ffxReturnCode_t ffxQuery(ffxContext* context, ffxQueryDescHeader* desc); -typedef ffxReturnCode_t (*PfnFfxQuery)(ffxContext* context, ffxQueryDescHeader* desc); - -// Dispatches work on the given FFX object context defined by the dispatch descriptor. -// Non-zero return indicates error code. -FFX_API_ENTRY ffxReturnCode_t ffxDispatch(ffxContext* context, const ffxDispatchDescHeader* desc); -typedef ffxReturnCode_t (*PfnFfxDispatch)(ffxContext* context, const ffxDispatchDescHeader* desc); - -#if defined(__cplusplus) -} -#endif // #if defined(__cplusplus) diff --git a/ffx-api/include/ffx_api/ffx_api.hpp b/ffx-api/include/ffx_api/ffx_api.hpp index caa384f3..38e6d258 100644 --- a/ffx-api/include/ffx_api/ffx_api.hpp +++ b/ffx-api/include/ffx_api/ffx_api.hpp @@ -30,6 +30,8 @@ namespace ffx { +typedef void* FfxSwapchain; +using Swapchain = FfxSwapchain; using Context = ffxContext; enum class ReturnCode : uint32_t @@ -78,64 +80,23 @@ Header* LinkHeaders(Header& hdr) return &hdr; } -template -inline ReturnCode CreateContext(Context& context, ffxAllocationCallbacks* memCb, Desc&... desc) -{ - auto header = LinkHeaders(desc.header...); - return detail::ConvertReturnCode(ffxCreateContext(&context, header, memCb)); -} - -inline ReturnCode DestroyContext(Context& context, ffxAllocationCallbacks* memCb = nullptr) -{ - return detail::ConvertReturnCode(ffxDestroyContext(&context, memCb)); -} - -template -inline ReturnCode Configure(Context &context, Desc&... desc) -{ - auto header = LinkHeaders(desc.header...); - return detail::ConvertReturnCode(ffxConfigure(&context, header)); -} - -template -inline ReturnCode Configure(Desc&... desc) -{ - auto header = LinkHeaders(desc.header...); - return detail::ConvertReturnCode(ffxConfigure(nullptr, header)); -} +template +struct struct_type; -template -inline ReturnCode Query(Context &context, Desc&... desc) +template <> +struct struct_type : std::integral_constant { - auto header = LinkHeaders(desc.header...); - return detail::ConvertReturnCode(ffxQuery(&context, header)); -} +}; -template -inline ReturnCode Query(Desc&... desc) +template <> +struct struct_type : std::integral_constant { - auto header = LinkHeaders(desc.header...); - return detail::ConvertReturnCode(ffxQuery(nullptr, header)); -} +}; -template -inline ReturnCode Dispatch(Context &context, Desc&... desc) +template <> +struct struct_type : std::integral_constant { - auto header = LinkHeaders(desc.header...); - return detail::ConvertReturnCode(ffxDispatch(&context, header)); -} - -template -struct struct_type; - -template<> -struct struct_type : std::integral_constant {}; - -template<> -struct struct_type : std::integral_constant {}; - -template<> -struct struct_type : std::integral_constant {}; +}; template ::value> struct InitHelper : public Inner @@ -143,33 +104,36 @@ struct InitHelper : public Inner InitHelper() { this->header.pNext = nullptr; - this->header.type = type; + this->header.type = type; } }; struct ConfigureDescGlobalDebug1 : public InitHelper -{}; +{ +}; struct CreateContextDescOverrideVersion : public InitHelper -{}; +{ +}; struct QueryDescGetVersions : public InitHelper -{}; +{ +}; -template -const T* DynamicCast(const ffxApiHeader *hdr) +template +const T* DynamicCast(const ffxApiHeader* hdr) { if (hdr->type == struct_type::value) return reinterpret_cast(hdr); return nullptr; } -template -T* DynamicCast(ffxApiHeader *hdr) +template +T* DynamicCast(ffxApiHeader* hdr) { if (hdr->type == struct_type::value) return reinterpret_cast(hdr); return nullptr; } -} +} // namespace ffx diff --git a/ffx-api/include/ffx_api/ffx_api_loader.h b/ffx-api/include/ffx_api/vk/ffx_api_loader_vk.h similarity index 63% rename from ffx-api/include/ffx_api/ffx_api_loader.h rename to ffx-api/include/ffx_api/vk/ffx_api_loader_vk.h index 9df9ac32..d930b9ae 100644 --- a/ffx-api/include/ffx_api/ffx_api_loader.h +++ b/ffx-api/include/ffx_api/vk/ffx_api_loader_vk.h @@ -22,22 +22,27 @@ #pragma once -#include "ffx_api.h" +#include "ffx_api_vk.h" #include +namespace vk +{ + typedef struct ffxFunctions { - PfnFfxCreateContext CreateContext; - PfnFfxDestroyContext DestroyContext; - PfnFfxConfigure Configure; - PfnFfxQuery Query; - PfnFfxDispatch Dispatch; + PfnFfxCreateContextVK CreateContextVK; + PfnFfxDestroyContextVK DestroyContextVK; + PfnFfxConfigureVK ConfigureVK; + PfnFfxQueryVK QueryVK; + PfnFfxDispatchVK DispatchVK; } ffxFunctions; static inline void ffxLoadFunctions(ffxFunctions* pOutFunctions, HMODULE module) { - pOutFunctions->CreateContext = (PfnFfxCreateContext )GetProcAddress(module, "ffxCreateContext"); - pOutFunctions->DestroyContext = (PfnFfxDestroyContext)GetProcAddress(module, "ffxDestroyContext"); - pOutFunctions->Configure = (PfnFfxConfigure )GetProcAddress(module, "ffxConfigure"); - pOutFunctions->Query = (PfnFfxQuery )GetProcAddress(module, "ffxQuery"); - pOutFunctions->Dispatch = (PfnFfxDispatch )GetProcAddress(module, "ffxDispatch"); + pOutFunctions->CreateContextVK = (PfnFfxCreateContextVK)GetProcAddress(module, "ffxCreateContextVK"); + pOutFunctions->DestroyContextVK = (PfnFfxDestroyContextVK)GetProcAddress(module, "ffxDestroyContextVK"); + pOutFunctions->ConfigureVK = (PfnFfxConfigureVK)GetProcAddress(module, "ffxConfigureVK"); + pOutFunctions->QueryVK = (PfnFfxQueryVK)GetProcAddress(module, "ffxQueryVK"); + pOutFunctions->DispatchVK = (PfnFfxDispatchVK)GetProcAddress(module, "ffxDispatchVK"); } + +} // namespace vk diff --git a/ffx-api/include/ffx_api/vk/ffx_api_vk.h b/ffx-api/include/ffx_api/vk/ffx_api_vk.h index 6865a62a..d3b36b64 100644 --- a/ffx-api/include/ffx_api/vk/ffx_api_vk.h +++ b/ffx-api/include/ffx_api/vk/ffx_api_vk.h @@ -21,10 +21,54 @@ // THE SOFTWARE. #pragma once -#include "../ffx_api.h" #include "../ffx_api_types.h" #include +#if defined(__cplusplus) +extern "C" { +#endif // #if defined(__cplusplus) + +#include "../ffx_api.h" + +#define FFX_API_ENTRY __declspec(dllexport) +#include + +// Creates a FFX object context. +// Depending on the desc structures provided to this function, the context will be created with the desired version and attributes. +// Non-zero return indicates error code. +// Pointers passed in desc must remain live until ffxDestroyContext is called on the context. +// MemCb may be null; the system allocator (malloc/free) will be used in this case. +FFX_API_ENTRY ffxReturnCode_t ffxCreateContextVK(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb); +typedef ffxReturnCode_t (*PfnFfxCreateContextVK)(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb); + +// Destroys an FFX object context. +// Non-zero return indicates error code. +// MemCb must be compatible with the callbacks passed into ffxCreateContext. +FFX_API_ENTRY ffxReturnCode_t ffxDestroyContextVK(ffxContext* context, const ffxAllocationCallbacks* memCb); +typedef ffxReturnCode_t (*PfnFfxDestroyContextVK)(ffxContext* context, const ffxAllocationCallbacks* memCb); + +// Configures the provided FFX object context. +// If context is null, configure operates on any global state. +// Non-zero return indicates error code. +FFX_API_ENTRY ffxReturnCode_t ffxConfigureVK(ffxContext* context, const ffxConfigureDescHeader* desc); +typedef ffxReturnCode_t (*PfnFfxConfigureVK)(ffxContext* context, const ffxConfigureDescHeader* desc); + +// Queries the provided FFX object context. +// If context is null, query operates on any global state. +// Non-zero return indicates error code. +FFX_API_ENTRY ffxReturnCode_t ffxQueryVK(ffxContext* context, ffxQueryDescHeader* desc); +typedef ffxReturnCode_t (*PfnFfxQueryVK)(ffxContext* context, ffxQueryDescHeader* desc); + +// Dispatches work on the given FFX object context defined by the dispatch descriptor. +// Non-zero return indicates error code. +FFX_API_ENTRY ffxReturnCode_t ffxDispatchVK(ffxContext* context, const ffxDispatchDescHeader* desc); +typedef ffxReturnCode_t (*PfnFfxDispatchVK)(ffxContext* context, const ffxDispatchDescHeader* desc); + +#if defined(__cplusplus) +} +#endif // #if defined(__cplusplus) + + /// FFX specific callback type when submitting a command buffer to a queue. typedef VkResult (*PFN_vkQueueSubmitFFXAPI)(uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence); diff --git a/ffx-api/include/ffx_api/vk/ffx_api_vk.hpp b/ffx-api/include/ffx_api/vk/ffx_api_vk.hpp index ebffa738..79a81a26 100644 --- a/ffx-api/include/ffx_api/vk/ffx_api_vk.hpp +++ b/ffx-api/include/ffx_api/vk/ffx_api_vk.hpp @@ -25,11 +25,66 @@ #include "../ffx_api.hpp" #include "ffx_api_vk.h" +#include +#include + // Helper types for header initialization. Api definition is in .h file. namespace ffx { +namespace vk +{ + +template +inline ReturnCode CreateContext(Context& context, ffxAllocationCallbacks* memCb, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxCreateContextVK(&context, header, memCb)); +} + +inline ReturnCode DestroyContext(Context& context, ffxAllocationCallbacks* memCb = nullptr) +{ + return detail::ConvertReturnCode(ffxDestroyContextVK(&context, memCb)); +} + +template +inline ReturnCode Configure(Context& context, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxConfigureVK(&context, header)); +} + +template +inline ReturnCode Configure(Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxConfigureVK(nullptr, header)); +} + +template +inline ReturnCode Query(Context& context, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxQueryVK(&context, header)); +} + +template +inline ReturnCode Query(Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxQueryVK(nullptr, header)); +} + +template +inline ReturnCode Dispatch(Context& context, Desc&... desc) +{ + auto header = LinkHeaders(desc.header...); + return detail::ConvertReturnCode(ffxDispatchVK(&context, header)); +} + +} // namespace vk + template<> struct struct_type : std::integral_constant {}; diff --git a/ffx-api/src/dx12/ffx_api_dx12.cpp b/ffx-api/src/dx12/ffx_api_dx12.cpp new file mode 100644 index 00000000..37989440 --- /dev/null +++ b/ffx-api/src/dx12/ffx_api_dx12.cpp @@ -0,0 +1,110 @@ +// 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 +#include +#include +#include "../ffx_provider.h" +#include "../backends.h" + +static uint64_t GetVersionOverride(const ffxApiHeader* header) +{ + for (auto it = header; it; it = it->pNext) + { + if (auto versionDesc = ffx::DynamicCast(it)) + { + return versionDesc->versionId; + } + } + return 0; +} + +FFX_API_ENTRY ffxReturnCode_t ffxCreateContextDX12(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb) +{ + VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + + *context = nullptr; + + const ffxProvider* provider = GetffxProvider(desc->type, GetVersionOverride(desc), GetDevice(desc)); + VERIFY(provider != nullptr, FFX_API_RETURN_NO_PROVIDER); + + Allocator alloc{memCb}; + return provider->CreateContext(context, desc, alloc); +} + +FFX_API_ENTRY ffxReturnCode_t ffxDestroyContextDX12(ffxContext* context, const ffxAllocationCallbacks* memCb) +{ + VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + + Allocator alloc{memCb}; + return GetAssociatedProvider(context)->DestroyContext(context, alloc); +} + +FFX_API_ENTRY ffxReturnCode_t ffxConfigureDX12(ffxContext* context, const ffxConfigureDescHeader* desc) +{ + VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + + return GetAssociatedProvider(context)->Configure(context, desc); +} + +FFX_API_ENTRY ffxReturnCode_t ffxQueryDX12(ffxContext* context, ffxQueryDescHeader* header) +{ + VERIFY(header != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + + if (context == nullptr) + { + if (auto desc = ffx::DynamicCast(header)) + { + // if output count is zero or no other pointer passed, count providers only + if (desc->outputCount && (*desc->outputCount == 0 || (!desc->versionIds && !desc->versionNames))) + { + *desc->outputCount = GetProviderCount(desc->createDescType, desc->device); + } + else if (desc->outputCount && *desc->outputCount > 0) + { + uint64_t capacity = *desc->outputCount; + *desc->outputCount = GetProviderVersions(desc->createDescType, desc->device, capacity, desc->versionIds, desc->versionNames); + } + return FFX_API_RETURN_OK; + } + else if (auto provider = GetffxProvider(header->type, GetVersionOverride(header), GetDevice(header))) + { + return provider->Query(nullptr, header); + } + else + { + return FFX_API_RETURN_NO_PROVIDER; + } + } + + return GetAssociatedProvider(context)->Query(context, header); +} + +FFX_API_ENTRY ffxReturnCode_t ffxDispatchDX12(ffxContext* context, const ffxDispatchDescHeader* desc) +{ + VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); + + return GetAssociatedProvider(context)->Dispatch(context, desc); +} diff --git a/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.cpp b/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.cpp index 4e541c0f..60749f81 100644 --- a/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.cpp +++ b/ffx-api/src/dx12/ffx_provider_framegenerationswapchain_dx12.cpp @@ -174,7 +174,7 @@ ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_DX12::Dispatch(ffxContext* InternalFgScContext* internal_context = reinterpret_cast(*context); if (auto desc = ffx::DynamicCast(header)) { - ffxWaitForPresents(internal_context->fiSwapChain); + ffxWaitForPresentsDX12(internal_context->fiSwapChain); return FFX_API_RETURN_OK; } else diff --git a/ffx-api/src/ffx_api.cpp b/ffx-api/src/vk/ffx_api_vk.cpp similarity index 85% rename from ffx-api/src/ffx_api.cpp rename to ffx-api/src/vk/ffx_api_vk.cpp index aad9a429..8e644e6e 100644 --- a/ffx-api/src/ffx_api.cpp +++ b/ffx-api/src/vk/ffx_api_vk.cpp @@ -22,9 +22,9 @@ #include #include -#include -#include "ffx_provider.h" -#include "backends.h" +#include +#include "../ffx_provider.h" +#include "../backends.h" static uint64_t GetVersionOverride(const ffxApiHeader* header) { @@ -38,7 +38,7 @@ static uint64_t GetVersionOverride(const ffxApiHeader* header) return 0; } -FFX_API_ENTRY ffxReturnCode_t ffxCreateContext(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb) +FFX_API_ENTRY ffxReturnCode_t ffxCreateContextVK(ffxContext* context, ffxCreateContextDescHeader* desc, const ffxAllocationCallbacks* memCb) { VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER); VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); @@ -52,7 +52,7 @@ FFX_API_ENTRY ffxReturnCode_t ffxCreateContext(ffxContext* context, ffxCreateCon return provider->CreateContext(context, desc, alloc); } -FFX_API_ENTRY ffxReturnCode_t ffxDestroyContext(ffxContext* context, const ffxAllocationCallbacks* memCb) +FFX_API_ENTRY ffxReturnCode_t ffxDestroyContextVK(ffxContext* context, const ffxAllocationCallbacks* memCb) { VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); @@ -60,7 +60,7 @@ FFX_API_ENTRY ffxReturnCode_t ffxDestroyContext(ffxContext* context, const ffxAl return GetAssociatedProvider(context)->DestroyContext(context, alloc); } -FFX_API_ENTRY ffxReturnCode_t ffxConfigure(ffxContext* context, const ffxConfigureDescHeader* desc) +FFX_API_ENTRY ffxReturnCode_t ffxConfigureVK(ffxContext* context, const ffxConfigureDescHeader* desc) { VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER); VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); @@ -68,7 +68,7 @@ FFX_API_ENTRY ffxReturnCode_t ffxConfigure(ffxContext* context, const ffxConfigu return GetAssociatedProvider(context)->Configure(context, desc); } -FFX_API_ENTRY ffxReturnCode_t ffxQuery(ffxContext* context, ffxQueryDescHeader* header) +FFX_API_ENTRY ffxReturnCode_t ffxQueryVK(ffxContext* context, ffxQueryDescHeader* header) { VERIFY(header != nullptr, FFX_API_RETURN_ERROR_PARAMETER); @@ -101,7 +101,7 @@ FFX_API_ENTRY ffxReturnCode_t ffxQuery(ffxContext* context, ffxQueryDescHeader* return GetAssociatedProvider(context)->Query(context, header); } -FFX_API_ENTRY ffxReturnCode_t ffxDispatch(ffxContext* context, const ffxDispatchDescHeader* desc) +FFX_API_ENTRY ffxReturnCode_t ffxDispatchVK(ffxContext* context, const ffxDispatchDescHeader* desc) { VERIFY(desc != nullptr, FFX_API_RETURN_ERROR_PARAMETER); VERIFY(context != nullptr, FFX_API_RETURN_ERROR_PARAMETER); diff --git a/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.cpp b/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.cpp index 76b9bbf7..fcf30f2f 100644 --- a/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.cpp +++ b/ffx-api/src/vk/ffx_provider_framegenerationswapchain_vk.cpp @@ -235,7 +235,7 @@ ffxReturnCode_t ffxProvider_FrameGenerationSwapChain_VK::Dispatch(ffxContext* co InternalFgScContext* internal_context = reinterpret_cast(*context); if (auto desc = ffx::DynamicCast(header)) { - ffxWaitForPresents(internal_context->fiSwapChain); + ffxWaitForPresentsVK(internal_context->fiSwapChain); return FFX_API_RETURN_OK; } else diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index 8e261f1e..3ef8380d 100644 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -30,12 +30,15 @@ endif() # Clean a bit before unset(FFX_GDK CACHE) -message(STATUS "FFX_API_BACKEND is ${FFX_API_BACKEND}") +message(STATUS "FFX_API_BACKEND_VK_X64 is ${FFX_API_BACKEND_VK_X64}") +message(STATUS "FFX_API_BACKEND_DX12_X64 is ${FFX_API_BACKEND_DX12_X64}") +message(STATUS "FFX_API_BACKEND_GDK_DESKTOP_X64 is ${FFX_API_BACKEND_GDK_DESKTOP_X64}") +message(STATUS "FFX_API_BACKEND_GDK_SCARLETT_X64 is ${FFX_API_BACKEND_GDK_SCARLETT_X64}") -if(FFX_API_BACKEND STREQUAL VK_X64 OR - FFX_API_BACKEND STREQUAL DX12_X64 OR - FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64 OR - FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64) +if(FFX_API_BACKEND_VK_X64 OR + FFX_API_BACKEND_DX12_X64 OR + FFX_API_BACKEND_GDK_DESKTOP_X64 OR + FFX_API_BACKEND_GDK_SCARLETT_X64) set(FFX_CUSTOM_API OFF) else() set(FFX_CUSTOM_API ON) @@ -45,7 +48,8 @@ endif() if (NOT FFX_CUSTOM_API) # Are we buiding the GDK? - if (FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64 OR FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64) + if (FFX_API_BACKEND_GDK_DESKTOP_X64 OR + FFX_API_BACKEND_GDK_SCARLETT_X64) set(FFX_GDK ON) endif() @@ -54,18 +58,22 @@ if (NOT FFX_CUSTOM_API) # If we are NOT building the GDK, queue up DX12/VK solution for building if (NOT FFX_GDK) - if (FFX_API_BACKEND STREQUAL DX12_X64) + if (FFX_API_BACKEND_DX12_X64) message(STATUS "Building FidelityFX SDK with DX12 backend") - elseif(FFX_API_BACKEND STREQUAL VK_X64) + endif() + if (FFX_API_BACKEND_VK_X64) message(STATUS "Building FidelityFX SDK with VK backend") endif() else() # List the API we are building for - if(FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64) + if(FFX_API_BACKEND_GDK_DESKTOP_X64) message(STATUS "Building FidelityFX SDK with GDK Gaming.Desktop.x64 backend") - elseif(FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64) + endif() + if(FFX_API_BACKEND_GDK_SCARLETT_X64) message(STATUS "Building FidelityFX SDK with GDK Gaming.Scarlett.x64 backend") - else() + endif() + if(NOT FFX_API_BACKEND_GDK_DESKTOP_X64 AND + NOT FFX_API_BACKEND_GDK_SCARLETT_X64) message(FATAL_ERROR "Requesting unsupported GDK build of FidelityFX SDK!") endif() endif() @@ -193,19 +201,26 @@ set(FFX_PUBLIC_SHADER_SOURCES "${FFX_GPU_PATH}/ffx_core_hlsl.h" "${FFX_GPU_PATH}/ffx_core_portability.h") -if (FFX_API_BACKEND STREQUAL DX12_X64) +if (FFX_API_BACKEND_DX12_X64) message(STATUS "Creating project FidelityFX-SDK_DX12_x64") project (FidelityFX-SDK_DX12_x64) -elseif (FFX_API_BACKEND STREQUAL VK_X64) +endif() +if (FFX_API_BACKEND_VK_X64) message(STATUS "Creating project FidelityFX-SDK_VK_x64") project (FidelityFX-SDK_VK_x64) -elseif(FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64) +endif() +if(FFX_API_BACKEND_GDK_DESKTOP_X64) message(STATUS "Creating project FidelityFX-SDK_GDK_Desktop_x64") project (FidelityFX-SDK_GDK_Desktop_x64) -elseif(FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64) +endif() +if(FFX_API_BACKEND_GDK_SCARLETT_X64) message(STATUS "Creating project FidelityFX-SDK_GDK_Scarlett_x64") project (FidelityFX-SDK_GDK_Scarlett_x64) -else() +endif() +if(NOT FFX_API_BACKEND_DX12_X64 AND + NOT FFX_API_BACKEND_VK_X64 AND + NOT FFX_API_BACKEND_GDK_DESKTOP_X64 AND + NOT FFX_API_BACKEND_GDK_SCARLETT_X64) # This is likely a custom include project (FidelityFX-SDK) endif() @@ -234,16 +249,17 @@ add_subdirectory(${FFX_COMPONENTS_PATH}/classifier) add_subdirectory(${FFX_COMPONENTS_PATH}/breadcrumbs) # Add appropriate graphics backend if requested -if(FFX_API_BACKEND STREQUAL DX12_X64) +if(FFX_API_BACKEND_DX12_X64) add_subdirectory(${FFX_LIB_PATH}/pix) add_subdirectory(${FFX_SRC_BACKENDS_PATH}/dx12) endif() -if (FFX_API_BACKEND STREQUAL VK_X64) +if (FFX_API_BACKEND_VK_X64) add_subdirectory(${FFX_SRC_BACKENDS_PATH}/vk) endif() -if(FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64 OR FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64) +if(FFX_API_BACKEND_GDK_DESKTOP_X64 OR + FFX_API_BACKEND_GDK_SCARLETT_X64) # TODO when we have the right lib to include #add_subdirectory(${FFX_LIB_PATH}/pix) add_subdirectory(${FFX_SRC_BACKENDS_PATH}/gdk) diff --git a/sdk/include/FidelityFX/gpu/CMakeCompileShaders.txt b/sdk/include/FidelityFX/gpu/CMakeCompileShaders.txt index ac1088d0..1b7b061c 100644 --- a/sdk/include/FidelityFX/gpu/CMakeCompileShaders.txt +++ b/sdk/include/FidelityFX/gpu/CMakeCompileShaders.txt @@ -66,9 +66,9 @@ function(compile_shaders_with_depfile list(APPEND COMPILE_INCLUDE_ARGS "-I${INCLUDE_SPACE}${INC}") endforeach(INC) - if (FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64) + if (FFX_API_BACKEND_GDK_DESKTOP_X64) set(FFX_GDK_OPTION -compiler=gdk.desktop.x64) - elseif (FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64) + elseif (FFX_API_BACKEND_GDK_SCARLETT_X64) set(FFX_GDK_OPTION -compiler=gdk.scarlett.x64) else() set(FFX_GDK_OPTION ) diff --git a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h index bc909961..f49284ad 100644 --- a/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h +++ b/sdk/include/FidelityFX/gpu/frameinterpolation/ffx_frameinterpolation_game_motion_vector_field.h @@ -48,7 +48,7 @@ void computeGameFieldMvs(FfxInt32x2 iPxPos) const FfxUInt32 uHighPriorityFactorPrimary = getPriorityFactorFromViewSpaceDepth(fViewSpaceDepth); FfxFloat32x3 prevBackbufferCol = SamplePreviousBackbuffer(fUvInInterpolationRect).xyz; - FfxFloat32x3 curBackbufferCol = SamplePreviousBackbuffer(fUvInInterpolationRect + fGameMotionVector * fUvLetterBoxScale).xyz; + FfxFloat32x3 curBackbufferCol = SampleCurrentBackbuffer(fUvInInterpolationRect + fGameMotionVector * fUvLetterBoxScale).xyz; FfxFloat32 prevLuma = 0.001f + RawRGBToLuminance(prevBackbufferCol); FfxFloat32 currLuma = 0.001f + RawRGBToLuminance(curBackbufferCol); diff --git a/sdk/include/FidelityFX/host/backends/dx12/ffx_dx12.h b/sdk/include/FidelityFX/host/backends/dx12/ffx_dx12.h index 13abf0e5..57207ad9 100644 --- a/sdk/include/FidelityFX/host/backends/dx12/ffx_dx12.h +++ b/sdk/include/FidelityFX/host/backends/dx12/ffx_dx12.h @@ -258,7 +258,7 @@ FFX_API FfxErrorCode ffxCreateFrameinterpolationSwapchainForHwndDX12(HWND hWnd, /// FFX_ERROR_INVALID_ARGUMENT Could not query the interface for the frame interpolation swap chain. /// /// @ingroup DX12FrameInterpolation -FFX_API FfxErrorCode ffxWaitForPresents(FfxSwapchain gameSwapChain); +FFX_API FfxErrorCode ffxWaitForPresentsDX12(FfxSwapchain gameSwapChain); /// Registers a FfxResource to use for UI with the provided FfxSwapchain. /// diff --git a/sdk/include/FidelityFX/host/backends/vk/ffx_vk.h b/sdk/include/FidelityFX/host/backends/vk/ffx_vk.h index 180fbbf4..fbcf82ab 100644 --- a/sdk/include/FidelityFX/host/backends/vk/ffx_vk.h +++ b/sdk/include/FidelityFX/host/backends/vk/ffx_vk.h @@ -249,7 +249,7 @@ FFX_API FfxErrorCode ffxReplaceSwapchainForFrameinterpolationVK(FfxCommandQueue /// FFX_ERROR_INVALID_ARGUMENT Could not query the interface for the frame interpolation swap chain. /// /// @ingroup VKFrameInterpolation -FFX_API FfxErrorCode ffxWaitForPresents(FfxSwapchain gameSwapChain); +FFX_API FfxErrorCode ffxWaitForPresentsVK(FfxSwapchain gameSwapChain); /// Registers a FfxResource to use for UI with the provided FfxSwapchain. /// diff --git a/sdk/include/FidelityFX/host/ffx_assert.h b/sdk/include/FidelityFX/host/ffx_assert.h index ab554c33..0303bbc8 100644 --- a/sdk/include/FidelityFX/host/ffx_assert.h +++ b/sdk/include/FidelityFX/host/ffx_assert.h @@ -22,8 +22,8 @@ #pragma once -#include -#include +#include "FidelityFX/host/ffx_types.h" +#include "FidelityFX/host/ffx_util.h" #ifdef __cplusplus extern "C" { diff --git a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12.cpp b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12.cpp index d4012005..50f1c4e9 100644 --- a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12.cpp +++ b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12.cpp @@ -213,7 +213,7 @@ FfxErrorCode ffxCreateFrameinterpolationSwapchainForHwndDX12(HWND return err; } -FfxErrorCode ffxWaitForPresents(FfxSwapchain gameSwapChain) +FfxErrorCode ffxWaitForPresentsDX12(FfxSwapchain gameSwapChain) { IDXGISwapChain4* swapChain = ffxGetDX12SwapchainPtr(gameSwapChain); @@ -355,7 +355,7 @@ DWORD WINAPI presenterThread(LPVOID param) // pacing without composition waitForFenceValue(presenter->compositionFence, frameInfo.presentIndex); - waitForPerformanceCount(previousPresentQpc + frameInfo.presentQpcDelta); + waitForPerformanceCountDX12(previousPresentQpc + frameInfo.presentQpcDelta); QueryPerformanceCounter(reinterpret_cast(&previousPresentQpc)); presentToSwapChain(presenter, &entry, (PacingData::FrameType)frameType); } @@ -373,7 +373,7 @@ DWORD WINAPI presenterThread(LPVOID param) return 0; } -DWORD WINAPI interpolationThread(LPVOID param) +DWORD WINAPI interpolationThreadDX12(LPVOID param) { FrameinterpolationPresentInfo* presenter = static_cast(param); @@ -742,7 +742,7 @@ bool FrameInterpolationSwapChainDX12::spawnPresenterThread() if (interpolationThreadHandle == NULL) { presentInfo.shutdown = false; - interpolationThreadHandle = CreateThread(nullptr, 0, interpolationThread, reinterpret_cast(&presentInfo), 0, nullptr); + interpolationThreadHandle = CreateThread(nullptr, 0, interpolationThreadDX12, reinterpret_cast(&presentInfo), 0, nullptr); FFX_ASSERT(interpolationThreadHandle != NULL); @@ -1072,6 +1072,7 @@ void FrameInterpolationSwapChainDX12::presentPassthrough(UINT SyncInterval, UINT barriers[1].Transition.pResource = dx12ResourceDst; barriers[1].Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; + //OutputDebugStringA("FrameInterpolationSwapChainDX12::copyUiResource 1\n"); list->ResourceBarrier(_countof(barriers), barriers); list->CopyResource(dx12ResourceDst, dx12ResourceSrc); @@ -1083,6 +1084,7 @@ void FrameInterpolationSwapChainDX12::presentPassthrough(UINT SyncInterval, UINT barriers[i].Transition.StateAfter = tmpStateBefore; } + //OutputDebugStringA("FrameInterpolationSwapChainDX12::copyUiResource 2\n"); list->ResourceBarrier(_countof(barriers), barriers); passthroughList->execute(true); @@ -1371,6 +1373,7 @@ void FrameInterpolationSwapChainDX12::copyUiResource() barriers[1].Transition.pResource = dx12ResourceDst; barriers[1].Transition.StateBefore = ffxGetDX12StateFromResourceState(presentInfo.currentUiSurface.state); barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; + //OutputDebugStringA("FrameInterpolationSwapChainDX12::copyUiResource 3\n"); dx12List->ResourceBarrier(_countof(barriers), barriers); dx12List->CopyResource(dx12ResourceDst, dx12ResourceSrc); @@ -1382,6 +1385,7 @@ void FrameInterpolationSwapChainDX12::copyUiResource() barriers[i].Transition.StateAfter = tmpStateBefore; } + //OutputDebugStringA("FrameInterpolationSwapChainDX12::copyUiResource 4\n"); dx12List->ResourceBarrier(_countof(barriers), barriers); copyList->execute(true); diff --git a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.cpp b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.cpp index 2cc265a7..a308385f 100644 --- a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.cpp +++ b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.cpp @@ -39,7 +39,7 @@ IDXGIFactory* getDXGIFactoryFromSwapChain(IDXGISwapChain* swapChain) return factory; } -void waitForPerformanceCount(const int64_t targetCount) +void waitForPerformanceCountDX12(const int64_t targetCount) { int64_t currentCount = 0; do diff --git a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.h b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.h index 32643375..8aaefc96 100644 --- a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.h +++ b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_Helpers.h @@ -33,7 +33,7 @@ IDXGIFactory* getDXGIFactoryFromSwapChain(IDXGISwapChain* swapChain); bool isExclusiveFullscreen(IDXGISwapChain* swapChain); -void waitForPerformanceCount(const int64_t targetCount); +void waitForPerformanceCountDX12(const int64_t targetCount); bool waitForFenceValue(ID3D12Fence* fence, UINT64 value, DWORD dwMilliseconds = INFINITE); bool isTearingSupported(IDXGIFactory* dxgiFactory); bool getMonitorLuminanceRange(IDXGISwapChain* swapChain, float* outMinLuminance, float* outMaxLuminance); diff --git a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_UiComposition.cpp b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_UiComposition.cpp index 507bb397..f0efb85d 100644 --- a/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_UiComposition.cpp +++ b/sdk/src/backends/dx12/FrameInterpolationSwapchain/FrameInterpolationSwapchainDX12_UiComposition.cpp @@ -25,6 +25,8 @@ #include "FrameInterpolationSwapchainDX12_Helpers.h" #include "FrameInterpolationSwapchainDX12_UiComposition.h" +#include + namespace UiCompositionShaders { #include "FrameInterpolationSwapchainUiCompositionVS.h" @@ -296,6 +298,7 @@ FFX_API FfxErrorCode ffxFrameInterpolationUiComposition(const FfxPresentCallback barriers[1].Transition.pResource = pRtResource; barriers[1].Transition.StateBefore = ffxGetDX12StateFromResourceState(params->outputSwapChainBuffer.state); barriers[1].Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_DEST; + //OutputDebugStringA("ffxFrameInterpolationUiComposition 3\n"); pCmdList->ResourceBarrier(_countof(barriers), barriers); pCmdList->CopyResource(pRtResource, pResBackbuffer); @@ -307,6 +310,7 @@ FFX_API FfxErrorCode ffxFrameInterpolationUiComposition(const FfxPresentCallback barriers[i].Transition.StateAfter = tmpStateBefore; } + //OutputDebugStringA("ffxFrameInterpolationUiComposition 4\n"); pCmdList->ResourceBarrier(_countof(barriers), barriers); } else @@ -337,6 +341,22 @@ FFX_API FfxErrorCode ffxFrameInterpolationUiComposition(const FfxPresentCallback { ++barrierCount; } + /* { + std::stringstream stream; + stream << "ffxFrameInterpolationUiComposition pResBackbuffer " << std::hex << reinterpret_cast(pResBackbuffer) + << '\n'; + OutputDebugStringA(stream.str().c_str()); + } + { + std::stringstream stream; + stream << "ffxFrameInterpolationUiComposition pResUI " << std::hex << reinterpret_cast(pResUI) << '\n'; + OutputDebugStringA(stream.str().c_str()); + } + { + std::stringstream stream; + stream << "ffxFrameInterpolationUiComposition pRtResource " << std::hex << reinterpret_cast(pRtResource) << '\n'; + OutputDebugStringA(stream.str().c_str()); + }*/ pCmdList->ResourceBarrier(barrierCount, barriers); // set root signature @@ -401,6 +421,11 @@ FFX_API FfxErrorCode ffxFrameInterpolationUiComposition(const FfxPresentCallback barriers[i].Transition.StateAfter = tmpStateBefore; } + /* { + std::stringstream stream; + stream << "ffxFrameInterpolationUiComposition pResBackbuffer reverced" << '\n'; + OutputDebugStringA(stream.str().c_str()); + }*/ pCmdList->ResourceBarrier(barrierCount, barriers); } diff --git a/sdk/src/backends/dx12/ffx_dx12.cpp b/sdk/src/backends/dx12/ffx_dx12.cpp index fbae4eb2..258c2381 100644 --- a/sdk/src/backends/dx12/ffx_dx12.cpp +++ b/sdk/src/backends/dx12/ffx_dx12.cpp @@ -31,6 +31,7 @@ #include // for VirtualAlloc #include #include // std::ignore +#include // Disable this to remove the dll load of PIX and PIX tracing #define ENABLE_PIX_CAPTURES 1 @@ -42,6 +43,7 @@ #define USE_PIX // Should enable it at anytime, as we already have a runtime switch for this purpose #endif // #ifndef USE_PIX #include "pix/pix3.h" +#include static bool s_PIXDLLLoaded = false; @@ -492,29 +494,41 @@ D3D12_RESOURCE_STATES ffxGetDX12StateFromResourceState(FfxResourceStates state) switch (state) { case FFX_RESOURCE_STATE_GENERIC_READ: + //OutputDebugStringA("FFX_RESOURCE_STATE_GENERIC_READ\n"); return D3D12_RESOURCE_STATE_GENERIC_READ; case FFX_RESOURCE_STATE_UNORDERED_ACCESS: + //OutputDebugStringA("D3D12_RESOURCE_STATE_UNORDERED_ACCESS\n"); return D3D12_RESOURCE_STATE_UNORDERED_ACCESS; case FFX_RESOURCE_STATE_PIXEL_COMPUTE_READ: + //OutputDebugStringA("D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE\n"); return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; case FFX_RESOURCE_STATE_COMPUTE_READ: + //OutputDebugStringA("D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE\n"); return D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; case FFX_RESOURCE_STATE_PIXEL_READ: + //OutputDebugStringA("D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE\n"); return D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; case FFX_RESOURCE_STATE_COPY_SRC: + //OutputDebugStringA("D3D12_RESOURCE_STATE_COPY_SOURCE\n"); return D3D12_RESOURCE_STATE_COPY_SOURCE; case FFX_RESOURCE_STATE_COPY_DEST: + //OutputDebugStringA("D3D12_RESOURCE_STATE_COPY_DEST\n"); return D3D12_RESOURCE_STATE_COPY_DEST; case FFX_RESOURCE_STATE_INDIRECT_ARGUMENT: + //OutputDebugStringA("D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT\n"); return D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT; case FFX_RESOURCE_STATE_PRESENT: + //OutputDebugStringA("D3D12_RESOURCE_STATE_PRESENT\n"); return D3D12_RESOURCE_STATE_PRESENT; case FFX_RESOURCE_STATE_COMMON: + //OutputDebugStringA("D3D12_RESOURCE_STATE_COMMON\n"); return D3D12_RESOURCE_STATE_COMMON; case FFX_RESOURCE_STATE_RENDER_TARGET: + //OutputDebugStringA("D3D12_RESOURCE_STATE_RENDER_TARGET\n"); return D3D12_RESOURCE_STATE_RENDER_TARGET; default: FFX_ASSERT_MESSAGE(false, "Resource state not yet supported"); + //OutputDebugStringA("D3D12_RESOURCE_STATE_COMMON\n"); return D3D12_RESOURCE_STATE_COMMON; } } @@ -832,6 +846,13 @@ void addBarrier(BackendContext_DX12* backendContext, FfxResourceInternal* resour FfxResourceStates* currentState = &backendContext->pResources[resource->internalIndex].currentState; if ((*currentState & newState) != newState) { + + /* { + std::stringstream stream; + stream << "addBarrier " << std::hex << ffxGetDX12StateFromResourceState(*currentState) << "->" << ffxGetDX12StateFromResourceState(newState) << " " << + reinterpret_cast(dx12Resource) << '\n'; + OutputDebugStringA(stream.str().c_str()); + }*/ *barrier = CD3DX12_RESOURCE_BARRIER::Transition( dx12Resource, @@ -855,10 +876,19 @@ void flushBarriers(BackendContext_DX12* backendContext, ID3D12GraphicsCommandLis FFX_ASSERT(NULL != dx12CommandList); if (backendContext->barrierCount > 0) { - + //OutputDebugStringA("flushBarriers\n"); dx12CommandList->ResourceBarrier(backendContext->barrierCount, backendContext->barriers); backendContext->barrierCount = 0; } + + /* for (size_t i = 0; i != backendContext->barrierCount; ++i) + { + { + std::stringstream stream; + stream << "flushBarriers " << i << ' ' << std::hex << reinterpret_cast(backendContext->barriers[i].Transition.pResource) << '\n'; + OutputDebugStringA(stream.str().c_str()); + } + }*/ } ////////////////////////////////////////////////////////////////////////// @@ -3111,6 +3141,10 @@ static FfxErrorCode executeGpuJobCompute(BackendContext_DX12* backendConte if (job->computeJobDescriptor.srvTextures[currentPipelineSrvIndex].resource.internalIndex == 0) break; + /* if (currentPipelineSrvIndex == 1) + { + OutputDebugStringA("Resource 40->8"); + }*/ addBarrier(backendContext, &job->computeJobDescriptor.srvTextures[currentPipelineSrvIndex].resource, FFX_RESOURCE_STATE_COMPUTE_READ); const FfxResourceBinding binding = job->computeJobDescriptor.pipeline.srvTextureBindings[currentPipelineSrvIndex]; diff --git a/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK.cpp b/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK.cpp index e3726052..41cb9b0d 100644 --- a/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK.cpp +++ b/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK.cpp @@ -26,6 +26,9 @@ #include "FrameInterpolationSwapchainVK_UiComposition.h" #include +#include +#include +#include // enable manually what is needed // this mode will compose the UI on the graphics queue in the present call on the main thread @@ -638,6 +641,7 @@ FfxErrorCode ffxReplaceSwapchainForFrameinterpolationVK(FfxCommandQueue } // as per Vulkan documentation, oldSwapchain is retired - even if creation of the new swapchain fails. + //OutputDebugStringA("DestroySwapchainKHR D\n"); vkDestroySwapchainKHR(frameInterpolationInfo->device, gameSwapchain, pAllocator); gameSwapChain = reinterpret_cast(pSwapChainVK); @@ -645,7 +649,7 @@ FfxErrorCode ffxReplaceSwapchainForFrameinterpolationVK(FfxCommandQueue return status; } -FfxErrorCode ffxWaitForPresents(FfxSwapchain gameSwapChain) +FfxErrorCode ffxWaitForPresentsVK(FfxSwapchain gameSwapChain) { FrameInterpolationSwapChainVK* frameinterpolationSwapchain = reinterpret_cast(gameSwapChain); @@ -659,6 +663,8 @@ FfxErrorCode ffxWaitForPresents(FfxSwapchain gameSwapChain) ////////////////////////////////////////////// VkResult presentToSwapChain(FrameinterpolationPresentInfo* pPresenter, uint32_t imageIndex, uint32_t semaphoreIndex = 0) { + //std::string semaphoreIndexValue = "-presentToSwapChain START sem: " + std::to_string(semaphoreIndex) + " img: " + std::to_string(imageIndex) + "\n "; + //OutputDebugStringA(semaphoreIndexValue.c_str()); VkPresentInfoKHR presentInfoKHR = {}; presentInfoKHR.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfoKHR.pNext = nullptr; @@ -669,11 +675,16 @@ VkResult presentToSwapChain(FrameinterpolationPresentInfo* pPresenter, uint32_t presentInfoKHR.pImageIndices = &imageIndex; presentInfoKHR.pResults = nullptr; // Optional + //std::stringstream stream; + //stream << "Present " << semaphoreIndex << " " << std::hex << reinterpret_cast(pPresenter->frameRenderedSemaphores[semaphoreIndex]) << '\n'; + //OutputDebugStringA(stream.str().c_str()); + EnterCriticalSection(&pPresenter->swapchainCriticalSection); VkResult res = vkQueuePresentKHR(pPresenter->presentQueue.queue, &presentInfoKHR); LeaveCriticalSection(&pPresenter->swapchainCriticalSection); ++(pPresenter->realPresentCount); + //OutputDebugStringA("-presentToSwapChain END\n"); return res; } @@ -793,16 +804,31 @@ VkResult compositeSwapChainFrame(FrameinterpolationPresentInfo* pPresenter, postCopyBarriers.record(compositeCommandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT); #endif + { + for (size_t i = 0; i != semaphoresToSignal.count; ++i) + { + //std::stringstream stream; + //stream << "SignalA " << i << " " << std::hex << reinterpret_cast(semaphoresToSignal.semaphores[i]) << '\n'; + //OutputDebugStringA(stream.str().c_str()); + } + } return compositeCommandList->execute(semaphoresToWait, semaphoresToSignal); } else { + for (size_t i = 0; i != semaphoresToSignal.count; ++i) + { + //std::stringstream stream; + //stream << "SignalB " << i << " " << std::hex << reinterpret_cast(semaphoresToSignal.semaphores[i]) << '\n'; + //OutputDebugStringA(stream.str().c_str()); + } return pPresenter->presentQueue.submit(VK_NULL_HANDLE, semaphoresToWait, semaphoresToSignal); } } DWORD WINAPI copyAndPresent_presenterThread(LPVOID pParam) { + //OutputDebugStringA("-copyAndPresent_presenterThread START\n"); FrameinterpolationPresentInfo* presenter = static_cast(pParam); if (presenter) @@ -812,8 +838,13 @@ DWORD WINAPI copyAndPresent_presenterThread(LPVOID pParam) while (!presenter->shutdown) { + OutputDebugStringA("Presenting Thread ASleep\n"); WaitForSingleObject(presenter->pacerEvent, INFINITE); + OutputDebugStringA("Presenting Thread AWake\n"); + //static size_t counter = 0; + //std::string message1 = "__copyAndPresent_presenterThread START " + std::to_string(counter) + '\n'; + //OutputDebugStringA(message1.c_str()); if (!presenter->shutdown) { EnterCriticalSection(&presenter->scheduledFrameCriticalSection); @@ -827,6 +858,9 @@ DWORD WINAPI copyAndPresent_presenterThread(LPVOID pParam) { // we might have dropped entries so have to update here, otherwise we might deadlock // we need to track the latest signaled value to avoid validation warnings + + //std::string indexValue = "PA i=" + std::to_string(entry.numFramesSentForPresentationBase) + '\n'; + //OutputDebugStringA(indexValue.c_str()); if (presenter->lastPresentSemaphoreValue != entry.numFramesSentForPresentationBase) { presenter->presentQueue.submit(VK_NULL_HANDLE, presenter->presentSemaphore, entry.numFramesSentForPresentationBase); @@ -838,9 +872,14 @@ DWORD WINAPI copyAndPresent_presenterThread(LPVOID pParam) const PacingData::FrameInfo& frameInfo = entry.frames[frameType]; if (frameInfo.doPresent) { + uint32_t imageIndex = 0; VkSemaphore imageAvailableSemaphore = VK_NULL_HANDLE; VkResult res = presenter->acquireNextRealImage(imageIndex, imageAvailableSemaphore); + + //std::string semaphoreIndexValue = "-copyAndPresent_presenterThread doPresent sem: " + std::to_string(imageIndex) + " START\n "; + //OutputDebugStringA(semaphoreIndexValue.c_str()); + FFX_ASSERT_MESSAGE_FORMAT(res == VK_SUCCESS || res == VK_SUBOPTIMAL_KHR, "[copyAndPresent_presenterThread] failed to acquire swapchain image"); auto presentCommandList = presenter->commandPool.get(presenter->device, presenter->presentQueue, "presentCommandList"); @@ -888,8 +927,33 @@ DWORD WINAPI copyAndPresent_presenterThread(LPVOID pParam) SubmissionSemaphores toWait; toWait.add(presenter->compositionSemaphore, frameInfo.presentIndex); // composition to finish + + /* { + VkSemaphoreWaitInfo waitInfo; + waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO; + waitInfo.pNext = NULL; + waitInfo.flags = 0; + waitInfo.semaphoreCount = 1; + waitInfo.pSemaphores = &presenter->compositionSemaphore; + waitInfo.pValues = NULL; + + vkWaitSemaphores(presenter->device, &waitInfo, UINT64_MAX); + }*/ + toWait.add(imageAvailableSemaphore); // swapchain image to be available + /* { + VkSemaphoreWaitInfo waitInfo; + waitInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO; + waitInfo.pNext = NULL; + waitInfo.flags = 0; + waitInfo.semaphoreCount = 1; + waitInfo.pSemaphores = &imageAvailableSemaphore; + waitInfo.pValues = NULL; + + vkWaitSemaphores(presenter->device, &waitInfo, UINT64_MAX); + }*/ + SubmissionSemaphores toSignal; toSignal.add(presenter->frameRenderedSemaphores[imageIndex]); // frame ready for present. Not a timeline semaphore @@ -908,27 +972,60 @@ DWORD WINAPI copyAndPresent_presenterThread(LPVOID pParam) presenter->lastPresentSemaphoreValue = frameInfo.presentIndex; } + //std::string indexValue = "signal i=" + std::to_string(frameInfo.presentIndex) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + + //std::stringstream stream; + //stream << "SignalC " << imageIndex << " " << std::hex << reinterpret_cast(presenter->frameRenderedSemaphores[imageIndex]) + // << '\n'; + //OutputDebugStringA(stream.str().c_str()); + res = presentCommandList->execute(toWait, toSignal); - waitForPerformanceCount(previousPresentQpc + frameInfo.presentQpcDelta); + //if (res != VK_SUCCESS) + //{ + // OutputDebugStringA("ERROR1\n"); + //} + + waitForPerformanceCountVK(previousPresentQpc + frameInfo.presentQpcDelta); QueryPerformanceCounter(reinterpret_cast(&previousPresentQpc)); + + OutputDebugStringA(" presentToSwapChain START\n"); res = presentToSwapChain(presenter, imageIndex, imageIndex); + OutputDebugStringA(" presentToSwapChain END\n"); // VK_SUBOPTIMAL_KHR & VK_ERROR_OUT_OF_DATE_KHR: the swapchain has been recreated FFX_ASSERT_MESSAGE_FORMAT(res == VK_SUCCESS || res == VK_SUBOPTIMAL_KHR || res == VK_ERROR_OUT_OF_DATE_KHR, "presentToSwapChain failed with error %d", res); + + if (res != VK_SUCCESS) + { + //OutputDebugStringA("RESIZED\n"); + } + + //OutputDebugStringA("-copyAndPresent_presenterThread doPresent END\n"); } } numFramesSentForPresentation = entry.numFramesSentForPresentationBase + entry.numFramesToPresent; + //std::string index3Value = "PB i=" + std::to_string(numFramesSentForPresentation) + '\n'; + //OutputDebugStringA(index3Value.c_str()); } } + + //std::string message2 = "__copyAndPresent_presenterThread END " + std::to_string(counter) + '\n'; + //OutputDebugStringA(message2.c_str()); + //++counter; } + //std::string indexValue = "PC i=" + std::to_string(numFramesSentForPresentation) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + waitForSemaphoreValue(presenter->device, presenter->presentSemaphore, numFramesSentForPresentation); } + //OutputDebugStringA("-copyAndPresent_presenterThread END\n"); return 0; } @@ -970,6 +1067,7 @@ DWORD WINAPI composeAndPresent_presenterThread(LPVOID pParam) bool uiSurfaceTransfered = (entry.uiSurface.resource == nullptr) || (presenter->gameQueue.familyIndex == presenter->presentQueue.familyIndex); + //OutputDebugStringA("-composeAndPresent_presenterThread START\n"); for (uint32_t frameType = 0; frameType < PacingData::FrameType::Count; frameType++) { const PacingData::FrameInfo& frameInfo = entry.frames[frameType]; @@ -999,10 +1097,13 @@ DWORD WINAPI composeAndPresent_presenterThread(LPVOID pParam) VkResult res = presenter->acquireNextRealImage(realSwapchainImageIndex, acquireSemaphore); toWait.add(acquireSemaphore); + //std::stringstream stream; + //stream << "SignalD " << 0 << " " << std::hex << reinterpret_cast(presenter->frameRenderedSemaphores[0]) << '\n'; + //OutputDebugStringA(stream.str().c_str()); res = compositeSwapChainFrame(presenter, &entry, (PacingData::FrameType)frameType, realSwapchainImageIndex, presenter->presentQueue, toWait, toSignal, uiSurfaceTransfered); FFX_ASSERT_MESSAGE_FORMAT(res == VK_SUCCESS, "compositeSwapChainFrame failed with error %d", res); - waitForPerformanceCount(previousPresentQpc + frameInfo.presentQpcDelta); + waitForPerformanceCountVK(previousPresentQpc + frameInfo.presentQpcDelta); QueryPerformanceCounter(reinterpret_cast(&previousPresentQpc)); res = presentToSwapChain(presenter, realSwapchainImageIndex); @@ -1012,6 +1113,7 @@ DWORD WINAPI composeAndPresent_presenterThread(LPVOID pParam) res); } } + //OutputDebugStringA("-composeAndPresent_presenterThread END\n"); // if no frame was presented, we still need to update the semaphore if (toWait.count > 0) @@ -1030,7 +1132,7 @@ DWORD WINAPI composeAndPresent_presenterThread(LPVOID pParam) return 0; } -DWORD WINAPI interpolationThread(LPVOID param) +DWORD WINAPI interpolationThreadVK(LPVOID param) { FrameinterpolationPresentInfo* presenter = static_cast(param); @@ -1055,8 +1157,13 @@ DWORD WINAPI interpolationThread(LPVOID param) while (!presenter->shutdown) { + OutputDebugStringA("Interpolation Thread ASleep\n"); WaitForSingleObject(presenter->presentEvent, INFINITE); + OutputDebugStringA("Interpolation Thread AWake\n"); + //static size_t counter = 0; + //std::string message1 = "__interpolationThreadVK START " + std::to_string(counter) + '\n'; + //OutputDebugStringA(message1.c_str()); if (!presenter->shutdown) { EnterCriticalSection(&presenter->scheduledFrameCriticalSection); @@ -1069,6 +1176,8 @@ DWORD WINAPI interpolationThread(LPVOID param) waitForSemaphoreValue(presenter->device, presenter->interpolationSemaphore, entry.frames[PacingData::FrameType::Interpolated_1].interpolationCompletedSemaphoreValue); + + OutputDebugStringA("Wake the Main Thread\n"); SetEvent(presenter->interpolationEvent); // unlocks the queuePresent method int64_t currentQpc = 0; @@ -1103,11 +1212,17 @@ DWORD WINAPI interpolationThread(LPVOID param) EnterCriticalSection(&presenter->scheduledFrameCriticalSection); presenter->scheduledPresents = entry; LeaveCriticalSection(&presenter->scheduledFrameCriticalSection); + OutputDebugStringA("Interpolation Thread -> Wake Presenting Thread 1\n"); SetEvent(presenter->pacerEvent); } + + //std::string message2 = "__interpolationThreadVK END " + std::to_string(counter) + '\n'; + //OutputDebugStringA(message2.c_str()); + //++counter; } // signal event to allow thread to finish + OutputDebugStringA("Interpolation Thread -> Wake Presenting Thread 2\n"); SetEvent(presenter->pacerEvent); WaitForSingleObject(presenterThreadHandle, INFINITE); SafeCloseHandle(presenterThreadHandle); @@ -1166,6 +1281,10 @@ VkResult FrameInterpolationSwapChainVK::acquireNextImage(VkDevice device, VkSwap SubmissionSemaphores toWait; SubmissionSemaphores toSignal; + //std::string indexValue = + // "A i=" + std::to_string(*pImageIndex) + " ai=" + std::to_string(replacementSwapBuffers[*pImageIndex].availabilitySemaphoreValue) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + toWait.add(presentInfo.replacementBufferSemaphore, replacementSwapBuffers[*pImageIndex].availabilitySemaphoreValue); if (semaphore != VK_NULL_HANDLE) @@ -1476,6 +1595,8 @@ void FrameInterpolationSwapChainVK::destroySwapchain(VkDevice device, const VkAl waitForPresents(); killPresenterThread(); + //OutputDebugStringA("FrameInterpolationSwapChainVK::destroySwapchain\n"); + FFX_ASSERT_MESSAGE(device == presentInfo.device, "Attempting to destroy Frame interpolation swapchain with another device"); if (device == VK_NULL_HANDLE) @@ -1515,6 +1636,7 @@ void FrameInterpolationSwapChainVK::destroySwapchain(VkDevice device, const VkAl SafeCloseHandle(presentInfo.pacerEvent); // delete real swapchain + //OutputDebugStringA("DestroySwapchainKHR E\n"); vkDestroySwapchainKHR(device, presentInfo.realSwapchain, pAllocator); presentInfo.realSwapchain = VK_NULL_HANDLE; @@ -1653,9 +1775,12 @@ void FrameInterpolationSwapChainVK::setFrameGenerationConfig(FfxFrameGenerationC bool FrameInterpolationSwapChainVK::waitForPresents() { + OutputDebugStringA("FrameInterpolationSwapChainVK::waitForPresents\n"); // wait for interpolation to finish bool waitRes = waitForSemaphoreValue(presentInfo.device, presentInfo.gameSemaphore, gameSemaphoreValue); waitRes &= waitForSemaphoreValue(presentInfo.device, presentInfo.interpolationSemaphore, interpolationSemaphoreValue); + //std::string indexValue = "waitForPresents i=" + std::to_string(framesSentForPresentation) + '\n'; + //OutputDebugStringA(indexValue.c_str()); waitRes &= waitForSemaphoreValue(presentInfo.device, presentInfo.presentSemaphore, framesSentForPresentation); FFX_ASSERT(waitRes); @@ -1708,6 +1833,16 @@ void FrameInterpolationSwapChainVK::dispatchInterpolationCommands(uint32_t semaphoresToWait.add(presentInfo.presentSemaphore, interpolationOutputs[interpolationBufferIndex].availabilitySemaphoreValue); #endif + //std::string indexValue = "FrameInterpolationSwapChainVK::dispatchInterpolationCommands index " + std::to_string(interpolationBufferIndex) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + //std::string avValue = "FrameInterpolationSwapChainVK::dispatchInterpolationCommands availabilitySemaphoreValue " + + // std::to_string(replacementSwapBuffers[interpolationBufferIndex].availabilitySemaphoreValue) + '\n'; + //OutputDebugStringA(avValue.c_str()); + + //std::string indexValue = "B i=" + std::to_string(interpolationBufferIndex) + + // " ai=" + std::to_string(interpolationOutputs[interpolationBufferIndex].availabilitySemaphoreValue) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + // check necessary transitions ImageBarrierHelper preInterpolationBarriers; if (presentInfo.gameQueue.familyIndex != presentInfo.interpolationQueue.familyIndex) @@ -1920,6 +2055,9 @@ void FrameInterpolationSwapChainVK::presentInterpolated(const VkPresentInfoKHR* { entry.uiSurface = presentInfo.currentUiSurface; } + + //std::string indexValue = "F i=" + std::to_string(framesSentForPresentation) + '\n'; + //OutputDebugStringA(indexValue.c_str()); entry.presentMode = presentMode; entry.numFramesSentForPresentationBase = framesSentForPresentation; entry.gameSemaphoreValue = gameSemaphoreValue; @@ -1933,6 +2071,9 @@ void FrameInterpolationSwapChainVK::presentInterpolated(const VkPresentInfoKHR* fiInterpolated.doPresent = true; fiInterpolated.resource = interpolatedFrame; fiInterpolated.interpolationCompletedSemaphoreValue = interpolationSemaphoreValue; + + //std::string indexValue = "G1 i=" + std::to_string(framesSentForPresentation + 1) + '\n'; + //OutputDebugStringA(indexValue.c_str()); fiInterpolated.presentIndex = ++framesSentForPresentation; } @@ -1945,15 +2086,30 @@ void FrameInterpolationSwapChainVK::presentInterpolated(const VkPresentInfoKHR* fiReal.doPresent = true; fiReal.resource = realFrame; fiReal.interpolationCompletedSemaphoreValue = interpolationSemaphoreValue; + + //std::string indexValue = "G2 i=" + std::to_string(framesSentForPresentation + 1) + '\n'; + //OutputDebugStringA(indexValue.c_str()); fiReal.presentIndex = ++framesSentForPresentation; } } + //std::string index2Value = "H i=" + std::to_string(framesSentForPresentation + 1) + '\n'; + //OutputDebugStringA(index2Value.c_str()); entry.replacementBufferSemaphoreSignal = framesSentForPresentation; entry.numFramesToPresent = static_cast(framesSentForPresentation - entry.numFramesSentForPresentationBase); interpolationOutputs[interpolationBufferIndex].availabilitySemaphoreValue = entry.numFramesSentForPresentationBase + fiInterpolated.doPresent; + //std::string indexValue = "FrameInterpolationSwapChainVK::presentInterpolated index " + std::to_string(interpolationBufferIndex) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + //std::string avValue = "FrameInterpolationSwapChainVK::presentInterpolated availabilitySemaphoreValue " + + // std::to_string(replacementSwapBuffers[interpolationBufferIndex].availabilitySemaphoreValue) + '\n'; + //OutputDebugStringA(avValue.c_str()); + + //std::string indexValue = "C i=" + std::to_string(interpolationBufferIndex) + + // " ai=" + std::to_string(interpolationOutputs[interpolationBufferIndex].availabilitySemaphoreValue) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + #if FFX_COMPOSITION_MODE == FFX_COMPOSE_IN_VKQUEUEPRESENT_ACQUIRE_IN_PRESENTTHREAD // launch composition now that PacingData has been set submitCompositionOnGameQueue(entry); @@ -1964,6 +2120,7 @@ void FrameInterpolationSwapChainVK::presentInterpolated(const VkPresentInfoKHR* LeaveCriticalSection(&presentInfo.scheduledFrameCriticalSection); // Set event to kick off async CPU present thread + OutputDebugStringA("Main Thread -> Wake Interpolation Thread\n"); SetEvent(presentInfo.presentEvent); } @@ -1981,6 +2138,11 @@ void FrameInterpolationSwapChainVK::registerUiResource(FfxResource uiResource, u VkResult FrameInterpolationSwapChainVK::queuePresentNonInterpolated(VkCommands* pCommands, uint32_t imageIndex, SubmissionSemaphores& semaphoresToWait) { + //OutputDebugStringA("FrameInterpolationSwapChainVK::queuePresentNonInterpolated START\n"); + + //std::string indexValue = "A i=" + std::to_string(framesSentForPresentation + 1) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + SubmissionSemaphores semaphoresToSignal; semaphoresToSignal.add(presentInfo.replacementBufferSemaphore, ++framesSentForPresentation); semaphoresToSignal.add(presentInfo.frameRenderedSemaphores[imageIndex]); // not a timeline semaphore @@ -1988,6 +2150,9 @@ VkResult FrameInterpolationSwapChainVK::queuePresentNonInterpolated(VkCommands* semaphoresToSignal.add(presentInfo.presentSemaphore, framesSentForPresentation); presentInfo.lastPresentSemaphoreValue = framesSentForPresentation; + //std::stringstream stream; + //stream << "SignalE " << imageIndex << " " << std::hex << reinterpret_cast(presentInfo.frameRenderedSemaphores[imageIndex]) << '\n'; + //OutputDebugStringA(stream.str().c_str()); pCommands->execute(semaphoresToWait, semaphoresToSignal); VkResult res = presentToSwapChain(&presentInfo, imageIndex, imageIndex); @@ -1997,6 +2162,8 @@ VkResult FrameInterpolationSwapChainVK::queuePresentNonInterpolated(VkCommands* res = presentInfo.gameQueue.submit(VK_NULL_HANDLE, semaphoresToWait, semaphoresToSignal); FFX_ASSERT_MESSAGE_FORMAT(res == VK_SUCCESS, "[queuePresentNonInterpolated] game queue submit failed with error %d", res); + //OutputDebugStringA("FrameInterpolationSwapChainVK::queuePresentNonInterpolated END\n"); + return res; } @@ -2179,6 +2346,7 @@ VkResult FrameInterpolationSwapChainVK::presentNonInterpolatedWithUiCompositionO SubmissionSemaphores& presentQueueWait, bool needUICopy) { + //OutputDebugStringA("FrameInterpolationSwapChainVK::presentNonInterpolatedWithUiCompositionOnGameQueue START\n"); auto uiCompositionList = presentInfo.commandPool.get(presentInfo.device, presentInfo.gameQueue, "uiCompositionList"); VkCommandBuffer uiCompositionCommandBuffer = uiCompositionList->reset(); @@ -2217,6 +2385,9 @@ VkResult FrameInterpolationSwapChainVK::presentNonInterpolatedWithUiCompositionO desc.frameID = currentFrameID; presentCallback(&desc, presentCallbackContext); + //std::string indexValue = "B i=" + std::to_string(framesSentForPresentation + 1) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + gameQueueSignal.add(presentInfo.replacementBufferSemaphore, ++framesSentForPresentation); ImageBarrierHelper presentQueueBarriers; @@ -2235,6 +2406,10 @@ VkResult FrameInterpolationSwapChainVK::presentNonInterpolatedWithUiCompositionO else { gameQueueSignal.add(presentInfo.frameRenderedSemaphores[imageIndex]); // not a timeline semaphore + + //std::stringstream stream; + //stream << "SignalG " << imageIndex << " " << std::hex << reinterpret_cast(presentInfo.frameRenderedSemaphores[imageIndex]) << '\n'; + //OutputDebugStringA(stream.str().c_str()); } // cannot signal after present on the present queue, so signal here @@ -2253,6 +2428,11 @@ VkResult FrameInterpolationSwapChainVK::presentNonInterpolatedWithUiCompositionO SubmissionSemaphores presentQueueSignal; presentQueueSignal.add(presentInfo.frameRenderedSemaphores[imageIndex]); // not a timeline semaphore + + //std::stringstream stream; + //stream << "SignalF " << imageIndex << " " << std::hex << reinterpret_cast(presentInfo.frameRenderedSemaphores[imageIndex]) << '\n'; + //OutputDebugStringA(stream.str().c_str()); + res = ownershipList->execute(presentQueueWait, presentQueueSignal); FFX_ASSERT_MESSAGE_FORMAT(res == VK_SUCCESS, "[queuePresentNonInterpolated] queue family ownership transfer to present queue failed with error %d", res); } @@ -2265,6 +2445,7 @@ VkResult FrameInterpolationSwapChainVK::presentNonInterpolatedWithUiCompositionO semaphoresToWait.add(presentInfo.presentSemaphore, framesSentForPresentation); res = presentInfo.gameQueue.submit(VK_NULL_HANDLE, semaphoresToWait, semaphoresToSignal); FFX_ASSERT_MESSAGE_FORMAT(res == VK_SUCCESS, "[queuePresentNonInterpolated] game queue submit failed with error %d", res); + //OutputDebugStringA("FrameInterpolationSwapChainVK::presentNonInterpolatedWithUiCompositionOnGameQueue END\n"); return res; } @@ -2316,8 +2497,9 @@ VkResult FrameInterpolationSwapChainVK::queuePresent(VkQueue queue, const VkPres if (runInterpolation) { + OutputDebugStringA("Main thread ASleep\n"); WaitForSingleObject(presentInfo.interpolationEvent, INFINITE); - + OutputDebugStringA("Main thread AWake\n"); presentInterpolated(pPresentInfo, currentBackBufferIndex, needUICopy); } else @@ -2374,7 +2556,9 @@ VkResult FrameInterpolationSwapChainVK::queuePresent(VkQueue queue, const VkPres previousFrameWasInterpolated = runInterpolation; - replacementSwapBuffers[currentBackBufferIndex].availabilitySemaphoreValue = framesSentForPresentation; + //replacementSwapBuffers[currentBackBufferIndex].availabilitySemaphoreValue = framesSentForPresentation; + //std::string framesSentForPresentationValue = "framesSentForPresentation " + std::to_string(framesSentForPresentation) + '\n'; + //OutputDebugStringA(framesSentForPresentationValue.c_str()); // Unregister any potential command list registeredInterpolationCommandLists[currentBackBufferIndex] = nullptr; @@ -2384,6 +2568,23 @@ VkResult FrameInterpolationSwapChainVK::queuePresent(VkQueue queue, const VkPres // update active backbuffer and block when no buffer is available replacementSwapBufferIndex = presentCount % gameBufferCount; + //std::string previousFrameWasInterpolatedValue = "previousFrameWasInterpolated " + std::to_string(previousFrameWasInterpolated) + '\n'; + //std::string currentBackBufferIndexValue = "currentBackBufferIndex " + std::to_string(currentBackBufferIndex) + '\n'; + //std::string interpolationBufferIndexValue = "interpolationBufferIndex " + std::to_string(interpolationBufferIndex) + '\n'; + //std::string replacementSwapBufferIndexValue = "replacementSwapBufferIndex " + std::to_string(replacementSwapBufferIndex) + '\n'; + //std::string replacementSwapBufferIndexSemaphoreValue = + // "replacementSwapBufferIndexValue " + std::to_string(replacementSwapBuffers[replacementSwapBufferIndex].availabilitySemaphoreValue) + '\n'; + + //OutputDebugStringA(previousFrameWasInterpolatedValue.c_str()); + //OutputDebugStringA(currentBackBufferIndexValue.c_str()); + //OutputDebugStringA(interpolationBufferIndexValue.c_str()); + //OutputDebugStringA(replacementSwapBufferIndexValue.c_str()); + //OutputDebugStringA(replacementSwapBufferIndexSemaphoreValue.c_str()); + + //std::string indexValue = "D i=" + std::to_string(replacementSwapBufferIndex) + + // " ai=" + std::to_string(replacementSwapBuffers[replacementSwapBufferIndex].availabilitySemaphoreValue) + '\n'; + //OutputDebugStringA(indexValue.c_str()); + LeaveCriticalSection(&criticalSection); waitForSemaphoreValue( @@ -2397,7 +2598,7 @@ bool FrameInterpolationSwapChainVK::spawnPresenterThread() if (interpolationThreadHandle == NULL) { presentInfo.shutdown = false; - interpolationThreadHandle = CreateThread(nullptr, 0, interpolationThread, reinterpret_cast(&presentInfo), 0, nullptr); + interpolationThreadHandle = CreateThread(nullptr, 0, interpolationThreadVK, reinterpret_cast(&presentInfo), 0, nullptr); FFX_ASSERT(interpolationThreadHandle != NULL); if (interpolationThreadHandle != 0) @@ -2420,6 +2621,7 @@ bool FrameInterpolationSwapChainVK::killPresenterThread() presentInfo.shutdown = true; // signal event to allow thread to finish + OutputDebugStringA("Main Thread -> Wake Interpolation Thread #2\n"); SetEvent(presentInfo.presentEvent); WaitForSingleObject(interpolationThreadHandle, INFINITE); SafeCloseHandle(interpolationThreadHandle); @@ -2522,6 +2724,10 @@ bool FrameInterpolationSwapChainVK::verifyUiDuplicateResource() VkImage uiResource = static_cast(presentInfo.currentUiSurface.resource); FfxResourceDescription uiResourceDesc = presentInfo.currentUiSurface.description; + + + //std::string indexValue = "C i=" + std::to_string(framesSentForPresentation) + '\n'; + //OutputDebugStringA(indexValue.c_str()); if ((0 == (presentInfo.uiCompositionFlags & FFX_UI_COMPOSITION_FLAG_ENABLE_INTERNAL_UI_DOUBLE_BUFFERING)) || (VK_NULL_HANDLE == uiResource)) { @@ -2586,6 +2792,9 @@ VkImageMemoryBarrier FrameInterpolationSwapChainVK::copyUiResource(VkCommandBuff SubmissionSemaphores& gameQueueWait, bool transferToPresentQueue) { + //std::string indexValue = "C i=" + std::to_string(framesSentForPresentation) + '\n'; + + //OutputDebugStringA(indexValue.c_str()); if ((previousFrameWasInterpolated) && (uiReplacementBuffer.image != VK_NULL_HANDLE)) { // if doublebuffering is enabled and uiReplacementbuffer has been used last frame diff --git a/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.cpp b/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.cpp index 326bb598..5a9cc2d8 100644 --- a/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.cpp +++ b/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.cpp @@ -26,7 +26,7 @@ #include #endif // #ifdef _WIN32 -void waitForPerformanceCount(const int64_t targetCount) +void waitForPerformanceCountVK(const int64_t targetCount) { int64_t currentCount = 0; do diff --git a/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.h b/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.h index 8775dcc1..e392e002 100644 --- a/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.h +++ b/sdk/src/backends/vk/FrameInterpolationSwapchain/FrameInterpolationSwapchainVK_Helpers.h @@ -31,7 +31,7 @@ #include -void waitForPerformanceCount(const int64_t targetCount); +void waitForPerformanceCountVK(const int64_t targetCount); struct SubmissionSemaphores diff --git a/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp b/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp index 982905a0..a9040d1d 100644 --- a/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp +++ b/sdk/src/components/frameinterpolation/ffx_frameinterpolation.cpp @@ -1052,7 +1052,7 @@ FFX_API FfxErrorCode ffxFrameInterpolationDispatch(FfxFrameInterpolationContext* barrier.barrierDescriptor.resource = contextPrivate->srvResources[currentSurfaceDescription->id]; barrier.barrierDescriptor.subResourceID = 0; barrier.barrierDescriptor.newState = initialState; - barrier.barrierDescriptor.barrierType = FFX_BARRIER_TYPE_TRANSITION; + barrier.barrierDescriptor.barrierType = FFX_BARRIER_TYPE_TRANSITION; contextPrivate->contextDescription.backendInterface.fpScheduleGpuJob(&contextPrivate->contextDescription.backendInterface, &barrier); } diff --git a/sdk/toolchain.cmake b/sdk/toolchain.cmake index 2fe26549..1bc79851 100644 --- a/sdk/toolchain.cmake +++ b/sdk/toolchain.cmake @@ -46,7 +46,8 @@ if (MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /GR- /fp:fast /GS /Gy") endif() -if (FFX_API_BACKEND STREQUAL DX12_X64 OR FFX_API_BACKEND STREQUAL VK_X64) +if (FFX_API_BACKEND_DX12_X64 OR + FFX_API_BACKEND_VK_X64) set(CMAKE_RELWITHDEBINFO_POSTFIX drel) set(CMAKE_SYSTEM_NAME WINDOWS) @@ -58,7 +59,7 @@ if (FFX_API_BACKEND STREQUAL DX12_X64 OR FFX_API_BACKEND STREQUAL VK_X64) # Ensure our platform toolset is x64 set(CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE "x64" CACHE STRING "" FORCE) -elseif(FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64) +elseif(FFX_API_BACKEND_GDK_DESKTOP_X64) # On GDK, RELWITHDEBINFO is Profile set(CMAKE_RELWITHDEBINFO_POSTFIX _profile) @@ -91,7 +92,7 @@ elseif(FFX_API_BACKEND STREQUAL GDK_DESKTOP_X64) set(CMAKE_CXX_FLAGS_INIT "$ENV{CFLAGS} ${CMAKE_CXX_FLAGS_INIT} -D_GAMING_DESKTOP -DWINAPI_FAMILY=WINAPI_FAMILY_DESKTOP_APP" CACHE STRING "" FORCE) -elseif(FFX_API_BACKEND STREQUAL GDK_SCARLETT_X64) +elseif(FFX_API_BACKEND_GDK_SCARLETT_X64) # On GDK, RELWITHDEBINFO is Profile set(CMAKE_RELWITHDEBINFO_POSTFIX _profile)