From 27c95d108d8d8441bb70856b6361a7f3cd8bf373 Mon Sep 17 00:00:00 2001 From: Dario Date: Sat, 14 Dec 2024 11:54:33 -0300 Subject: [PATCH] Make D3D12 support optional. --- UnleashedRecomp/CMakeLists.txt | 20 ++++++--- UnleashedRecomp/gpu/video.cpp | 65 ++++++++++++++++++++-------- UnleashedRecomp/gpu/video.h | 2 + UnleashedRecomp/stdafx.h | 6 +++ UnleashedRecomp/user/config.h | 5 +++ UnleashedRecomp/user/config_detail.h | 4 ++ 6 files changed, 79 insertions(+), 23 deletions(-) diff --git a/UnleashedRecomp/CMakeLists.txt b/UnleashedRecomp/CMakeLists.txt index 42bb1c10..691fbf61 100644 --- a/UnleashedRecomp/CMakeLists.txt +++ b/UnleashedRecomp/CMakeLists.txt @@ -1,6 +1,10 @@ project("UnleashedRecomp") set(TARGET_NAME "SWA") +if (WIN32) + option(SWA_D3D12 "Add D3D12 support for rendering" ON) +endif() + option(SWA_XAUDIO2 "Use XAudio2 for audio playback" OFF) function(BIN2C) @@ -95,7 +99,7 @@ set(SWA_GPU_CXX_SOURCES "gpu/rhi/plume_vulkan.cpp" ) -if (WIN32) +if (SWA_D3D12) list(APPEND SWA_GPU_CXX_SOURCES "gpu/rhi/plume_d3d12.cpp" ) @@ -211,10 +215,11 @@ endif() set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) -if (WIN32) +if (SWA_D3D12) find_package(directx-headers CONFIG REQUIRED) find_package(directx12-agility CONFIG REQUIRED) find_package(d3d12-memory-allocator CONFIG REQUIRED) + target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12) endif() find_package(SDL2 CONFIG REQUIRED) @@ -236,7 +241,7 @@ find_package(nfd CONFIG REQUIRED) find_package(Vorbis CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED) -if (WIN32) +if (SWA_D3D12) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) add_custom_command(TARGET UnleashedRecomp POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${CMAKE_CURRENT_BINARY_DIR}/D3D12 @@ -252,8 +257,13 @@ if (WIN32) Microsoft::DirectX12-Agility Microsoft::DirectXShaderCompiler unofficial::D3D12MemoryAllocator - comctl32 dxgi + ) +endif() + +if (WIN32) + target_link_libraries(UnleashedRecomp PRIVATE + comctl32 ntdll winmm Synchronization @@ -300,7 +310,7 @@ target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS}) function(compile_shader FILE_PATH TARGET_NAME) set(FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/gpu/shader/${FILE_PATH}.hlsl) cmake_path(GET FILE_PATH STEM VARIABLE_NAME) - if (WIN32) + if (SWA_D3D12) add_custom_command( OUTPUT ${FILE_PATH}.dxil.h COMMAND ${DIRECTX_DXC_TOOL} -T ${TARGET_NAME} -HV 2021 -all-resources-bound -Wno-ignored-attributes -Fh ${FILE_PATH}.dxil.h ${FILE_PATH} -Vn g_${VARIABLE_NAME}_dxil diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 0220a6a4..7b8d3f33 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -35,35 +35,39 @@ #endif #include "../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" + +#if defined(SWA_D3D12) #include "shader/copy_vs.hlsl.dxil.h" -#include "shader/copy_vs.hlsl.spirv.h" #include "shader/csd_filter_ps.hlsl.dxil.h" -#include "shader/csd_filter_ps.hlsl.spirv.h" #include "shader/enhanced_motion_blur_ps.hlsl.dxil.h" -#include "shader/enhanced_motion_blur_ps.hlsl.spirv.h" #include "shader/gamma_correction_ps.hlsl.dxil.h" -#include "shader/gamma_correction_ps.hlsl.spirv.h" #include "shader/gaussian_blur_3x3.hlsl.dxil.h" -#include "shader/gaussian_blur_3x3.hlsl.spirv.h" #include "shader/gaussian_blur_5x5.hlsl.dxil.h" -#include "shader/gaussian_blur_5x5.hlsl.spirv.h" #include "shader/gaussian_blur_7x7.hlsl.dxil.h" -#include "shader/gaussian_blur_7x7.hlsl.spirv.h" #include "shader/gaussian_blur_9x9.hlsl.dxil.h" -#include "shader/gaussian_blur_9x9.hlsl.spirv.h" #include "shader/imgui_ps.hlsl.dxil.h" -#include "shader/imgui_ps.hlsl.spirv.h" #include "shader/imgui_vs.hlsl.dxil.h" -#include "shader/imgui_vs.hlsl.spirv.h" #include "shader/movie_ps.hlsl.dxil.h" -#include "shader/movie_ps.hlsl.spirv.h" #include "shader/movie_vs.hlsl.dxil.h" -#include "shader/movie_vs.hlsl.spirv.h" #include "shader/resolve_msaa_depth_2x.hlsl.dxil.h" -#include "shader/resolve_msaa_depth_2x.hlsl.spirv.h" #include "shader/resolve_msaa_depth_4x.hlsl.dxil.h" -#include "shader/resolve_msaa_depth_4x.hlsl.spirv.h" #include "shader/resolve_msaa_depth_8x.hlsl.dxil.h" +#endif + +#include "shader/copy_vs.hlsl.spirv.h" +#include "shader/csd_filter_ps.hlsl.spirv.h" +#include "shader/enhanced_motion_blur_ps.hlsl.spirv.h" +#include "shader/gamma_correction_ps.hlsl.spirv.h" +#include "shader/gaussian_blur_3x3.hlsl.spirv.h" +#include "shader/gaussian_blur_5x5.hlsl.spirv.h" +#include "shader/gaussian_blur_7x7.hlsl.spirv.h" +#include "shader/gaussian_blur_9x9.hlsl.spirv.h" +#include "shader/imgui_ps.hlsl.spirv.h" +#include "shader/imgui_vs.hlsl.spirv.h" +#include "shader/movie_ps.hlsl.spirv.h" +#include "shader/movie_vs.hlsl.spirv.h" +#include "shader/resolve_msaa_depth_2x.hlsl.spirv.h" +#include "shader/resolve_msaa_depth_4x.hlsl.spirv.h" #include "shader/resolve_msaa_depth_8x.hlsl.spirv.h" extern "C" @@ -74,7 +78,9 @@ extern "C" namespace plume { +#if defined(SWA_D3D12) extern std::unique_ptr CreateD3D12Interface(); +#endif extern std::unique_ptr CreateVulkanInterface(); } @@ -174,7 +180,12 @@ static FORCEINLINE void SetDirtyValue(bool& dirtyState, T& dest, const T& src) } } -static bool g_vulkan; +#if defined(SWA_D3D12) +static bool g_vulkan = false; +#else +static constexpr bool g_vulkan = true; +#endif + static std::unique_ptr g_interface; static std::unique_ptr g_device; @@ -1062,6 +1073,8 @@ static GuestShader* g_csdShader; static std::unique_ptr g_enhancedMotionBlurShader; +#if defined(SWA_D3D12) + #define CREATE_SHADER(NAME) \ g_device->createShader( \ g_vulkan ? g_##NAME##_spirv : g_##NAME##_dxil, \ @@ -1069,6 +1082,13 @@ static std::unique_ptr g_enhancedMotionBlurShader; "main", \ g_vulkan ? RenderShaderFormat::SPIRV : RenderShaderFormat::DXIL) +#else + +#define CREATE_SHADER(NAME) \ + g_device->createShader(g_##NAME##_spirv, sizeof(g_##NAME##_spirv), "main", RenderShaderFormat::SPIRV); + +#endif + static bool DetectWine() { HMODULE dllHandle = GetModuleHandle("ntdll.dll"); @@ -1288,11 +1308,18 @@ void Video::CreateHostDevice() Window::Init(); +#if defined(SWA_D3D12) g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan; +#endif LoadEmbeddedResources(); +#if defined(SWA_D3D12) g_interface = g_vulkan ? CreateVulkanInterface() : CreateD3D12Interface(); +#else + g_interface = CreateVulkanInterface(); +#endif + g_device = g_interface->createDevice(); g_triangleFanSupported = g_device->getCapabilities().triangleFan; @@ -2765,9 +2792,6 @@ static void ProcSetScissorRect(const RenderCommand& cmd) SetDirtyValue(g_dirtyStates.scissorRect, g_scissorRect.right, args.right); } -static Mutex g_compiledSpecConstantLibraryBlobMutex; -static ankerl::unordered_dense::map> g_compiledSpecConstantLibraryBlobs; - static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specConstants) { if (g_vulkan || @@ -2808,8 +2832,12 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons shader = guestShader->linkedShaders[specConstants].get(); } +#if defined(SWA_D3D12) if (shader == nullptr) { + static Mutex g_compiledSpecConstantLibraryBlobMutex; + static ankerl::unordered_dense::map> g_compiledSpecConstantLibraryBlobs; + thread_local ComPtr s_dxcCompiler; thread_local ComPtr s_dxcLinker; thread_local ComPtr s_dxcUtils; @@ -2916,6 +2944,7 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons shader = linkedShader.get(); } } +#endif return shader; } diff --git a/UnleashedRecomp/gpu/video.h b/UnleashedRecomp/gpu/video.h index 135a7dfa..1471bc02 100644 --- a/UnleashedRecomp/gpu/video.h +++ b/UnleashedRecomp/gpu/video.h @@ -274,8 +274,10 @@ struct GuestShader : GuestResource std::unique_ptr shader; struct ShaderCacheEntry* shaderCacheEntry = nullptr; ankerl::unordered_dense::map> linkedShaders; +#if defined(SWA_D3D12) std::vector> shaderBlobs; ComPtr libraryBlob; +#endif #ifdef ASYNC_PSO_DEBUG const char* name = ""; #endif diff --git a/UnleashedRecomp/stdafx.h b/UnleashedRecomp/stdafx.h index 16e8508a..5b00b817 100644 --- a/UnleashedRecomp/stdafx.h +++ b/UnleashedRecomp/stdafx.h @@ -2,8 +2,14 @@ #define NOMINMAX +#if defined(_WIN32) #include +#endif + +#if defined(SWA_D3D12) #include +#endif + #include #include #include diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index 502d8546..de2355bb 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -28,7 +28,12 @@ public: CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true); +#if defined(SWA_D3D12) CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::D3D12); +#else + CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Vulkan); +#endif + CONFIG_DEFINE("Video", int32_t, WindowX, WINDOWPOS_CENTRED); CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED); CONFIG_DEFINE("Video", int32_t, WindowWidth, 1280); diff --git a/UnleashedRecomp/user/config_detail.h b/UnleashedRecomp/user/config_detail.h index 5133ccad..fb0543a3 100644 --- a/UnleashedRecomp/user/config_detail.h +++ b/UnleashedRecomp/user/config_detail.h @@ -95,13 +95,17 @@ CONFIG_DEFINE_ENUM_TEMPLATE(EVoiceLanguage) enum class EGraphicsAPI : uint32_t { +#if defined(SWA_D3D12) D3D12, +#endif Vulkan }; CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI) { +#if defined(SWA_D3D12) { "D3D12", EGraphicsAPI::D3D12 }, +#endif { "Vulkan", EGraphicsAPI::Vulkan } };