Make D3D12 support optional.

This commit is contained in:
Dario 2024-12-14 11:54:33 -03:00
parent 7f45cb942d
commit 27c95d108d
6 changed files with 79 additions and 23 deletions

View file

@ -1,6 +1,10 @@
project("UnleashedRecomp") project("UnleashedRecomp")
set(TARGET_NAME "SWA") 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) option(SWA_XAUDIO2 "Use XAudio2 for audio playback" OFF)
function(BIN2C) function(BIN2C)
@ -95,7 +99,7 @@ set(SWA_GPU_CXX_SOURCES
"gpu/rhi/plume_vulkan.cpp" "gpu/rhi/plume_vulkan.cpp"
) )
if (WIN32) if (SWA_D3D12)
list(APPEND SWA_GPU_CXX_SOURCES list(APPEND SWA_GPU_CXX_SOURCES
"gpu/rhi/plume_d3d12.cpp" "gpu/rhi/plume_d3d12.cpp"
) )
@ -211,10 +215,11 @@ endif()
set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME}) set_target_properties(UnleashedRecomp PROPERTIES OUTPUT_NAME ${TARGET_NAME})
if (WIN32) if (SWA_D3D12)
find_package(directx-headers CONFIG REQUIRED) find_package(directx-headers CONFIG REQUIRED)
find_package(directx12-agility CONFIG REQUIRED) find_package(directx12-agility CONFIG REQUIRED)
find_package(d3d12-memory-allocator CONFIG REQUIRED) find_package(d3d12-memory-allocator CONFIG REQUIRED)
target_compile_definitions(UnleashedRecomp PRIVATE SWA_D3D12)
endif() endif()
find_package(SDL2 CONFIG REQUIRED) find_package(SDL2 CONFIG REQUIRED)
@ -236,7 +241,7 @@ find_package(nfd CONFIG REQUIRED)
find_package(Vorbis CONFIG REQUIRED) find_package(Vorbis CONFIG REQUIRED)
find_package(fmt CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED)
if (WIN32) if (SWA_D3D12)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/D3D12)
add_custom_command(TARGET UnleashedRecomp POST_BUILD add_custom_command(TARGET UnleashedRecomp POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/D3D12 COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${CMAKE_CURRENT_BINARY_DIR}/D3D12
@ -252,8 +257,13 @@ if (WIN32)
Microsoft::DirectX12-Agility Microsoft::DirectX12-Agility
Microsoft::DirectXShaderCompiler Microsoft::DirectXShaderCompiler
unofficial::D3D12MemoryAllocator unofficial::D3D12MemoryAllocator
comctl32
dxgi dxgi
)
endif()
if (WIN32)
target_link_libraries(UnleashedRecomp PRIVATE
comctl32
ntdll ntdll
winmm winmm
Synchronization Synchronization
@ -300,7 +310,7 @@ target_precompile_headers(UnleashedRecomp PUBLIC ${SWA_PRECOMPILED_HEADERS})
function(compile_shader FILE_PATH TARGET_NAME) function(compile_shader FILE_PATH TARGET_NAME)
set(FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/gpu/shader/${FILE_PATH}.hlsl) set(FILE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/gpu/shader/${FILE_PATH}.hlsl)
cmake_path(GET FILE_PATH STEM VARIABLE_NAME) cmake_path(GET FILE_PATH STEM VARIABLE_NAME)
if (WIN32) if (SWA_D3D12)
add_custom_command( add_custom_command(
OUTPUT ${FILE_PATH}.dxil.h 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 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

View file

@ -35,35 +35,39 @@
#endif #endif
#include "../../tools/ShaderRecomp/ShaderRecomp/shader_common.h" #include "../../tools/ShaderRecomp/ShaderRecomp/shader_common.h"
#if defined(SWA_D3D12)
#include "shader/copy_vs.hlsl.dxil.h" #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.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.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.dxil.h"
#include "shader/gamma_correction_ps.hlsl.spirv.h"
#include "shader/gaussian_blur_3x3.hlsl.dxil.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.dxil.h"
#include "shader/gaussian_blur_5x5.hlsl.spirv.h"
#include "shader/gaussian_blur_7x7.hlsl.dxil.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.dxil.h"
#include "shader/gaussian_blur_9x9.hlsl.spirv.h"
#include "shader/imgui_ps.hlsl.dxil.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.dxil.h"
#include "shader/imgui_vs.hlsl.spirv.h"
#include "shader/movie_ps.hlsl.dxil.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.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.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.dxil.h"
#include "shader/resolve_msaa_depth_4x.hlsl.spirv.h"
#include "shader/resolve_msaa_depth_8x.hlsl.dxil.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" #include "shader/resolve_msaa_depth_8x.hlsl.spirv.h"
extern "C" extern "C"
@ -74,7 +78,9 @@ extern "C"
namespace plume namespace plume
{ {
#if defined(SWA_D3D12)
extern std::unique_ptr<RenderInterface> CreateD3D12Interface(); extern std::unique_ptr<RenderInterface> CreateD3D12Interface();
#endif
extern std::unique_ptr<RenderInterface> CreateVulkanInterface(); extern std::unique_ptr<RenderInterface> 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<RenderInterface> g_interface; static std::unique_ptr<RenderInterface> g_interface;
static std::unique_ptr<RenderDevice> g_device; static std::unique_ptr<RenderDevice> g_device;
@ -1062,6 +1073,8 @@ static GuestShader* g_csdShader;
static std::unique_ptr<GuestShader> g_enhancedMotionBlurShader; static std::unique_ptr<GuestShader> g_enhancedMotionBlurShader;
#if defined(SWA_D3D12)
#define CREATE_SHADER(NAME) \ #define CREATE_SHADER(NAME) \
g_device->createShader( \ g_device->createShader( \
g_vulkan ? g_##NAME##_spirv : g_##NAME##_dxil, \ g_vulkan ? g_##NAME##_spirv : g_##NAME##_dxil, \
@ -1069,6 +1082,13 @@ static std::unique_ptr<GuestShader> g_enhancedMotionBlurShader;
"main", \ "main", \
g_vulkan ? RenderShaderFormat::SPIRV : RenderShaderFormat::DXIL) 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() static bool DetectWine()
{ {
HMODULE dllHandle = GetModuleHandle("ntdll.dll"); HMODULE dllHandle = GetModuleHandle("ntdll.dll");
@ -1288,11 +1308,18 @@ void Video::CreateHostDevice()
Window::Init(); Window::Init();
#if defined(SWA_D3D12)
g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan; g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan;
#endif
LoadEmbeddedResources(); LoadEmbeddedResources();
#if defined(SWA_D3D12)
g_interface = g_vulkan ? CreateVulkanInterface() : CreateD3D12Interface(); g_interface = g_vulkan ? CreateVulkanInterface() : CreateD3D12Interface();
#else
g_interface = CreateVulkanInterface();
#endif
g_device = g_interface->createDevice(); g_device = g_interface->createDevice();
g_triangleFanSupported = g_device->getCapabilities().triangleFan; g_triangleFanSupported = g_device->getCapabilities().triangleFan;
@ -2765,9 +2792,6 @@ static void ProcSetScissorRect(const RenderCommand& cmd)
SetDirtyValue<int32_t>(g_dirtyStates.scissorRect, g_scissorRect.right, args.right); SetDirtyValue<int32_t>(g_dirtyStates.scissorRect, g_scissorRect.right, args.right);
} }
static Mutex g_compiledSpecConstantLibraryBlobMutex;
static ankerl::unordered_dense::map<uint32_t, ComPtr<IDxcBlob>> g_compiledSpecConstantLibraryBlobs;
static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specConstants) static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specConstants)
{ {
if (g_vulkan || if (g_vulkan ||
@ -2808,8 +2832,12 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons
shader = guestShader->linkedShaders[specConstants].get(); shader = guestShader->linkedShaders[specConstants].get();
} }
#if defined(SWA_D3D12)
if (shader == nullptr) if (shader == nullptr)
{ {
static Mutex g_compiledSpecConstantLibraryBlobMutex;
static ankerl::unordered_dense::map<uint32_t, ComPtr<IDxcBlob>> g_compiledSpecConstantLibraryBlobs;
thread_local ComPtr<IDxcCompiler3> s_dxcCompiler; thread_local ComPtr<IDxcCompiler3> s_dxcCompiler;
thread_local ComPtr<IDxcLinker> s_dxcLinker; thread_local ComPtr<IDxcLinker> s_dxcLinker;
thread_local ComPtr<IDxcUtils> s_dxcUtils; thread_local ComPtr<IDxcUtils> s_dxcUtils;
@ -2916,6 +2944,7 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons
shader = linkedShader.get(); shader = linkedShader.get();
} }
} }
#endif
return shader; return shader;
} }

View file

@ -274,8 +274,10 @@ struct GuestShader : GuestResource
std::unique_ptr<RenderShader> shader; std::unique_ptr<RenderShader> shader;
struct ShaderCacheEntry* shaderCacheEntry = nullptr; struct ShaderCacheEntry* shaderCacheEntry = nullptr;
ankerl::unordered_dense::map<uint32_t, std::unique_ptr<RenderShader>> linkedShaders; ankerl::unordered_dense::map<uint32_t, std::unique_ptr<RenderShader>> linkedShaders;
#if defined(SWA_D3D12)
std::vector<ComPtr<IDxcBlob>> shaderBlobs; std::vector<ComPtr<IDxcBlob>> shaderBlobs;
ComPtr<IDxcBlobEncoding> libraryBlob; ComPtr<IDxcBlobEncoding> libraryBlob;
#endif
#ifdef ASYNC_PSO_DEBUG #ifdef ASYNC_PSO_DEBUG
const char* name = "<unknown>"; const char* name = "<unknown>";
#endif #endif

View file

@ -2,8 +2,14 @@
#define NOMINMAX #define NOMINMAX
#if defined(_WIN32)
#include <windows.h> #include <windows.h>
#endif
#if defined(SWA_D3D12)
#include <dxcapi.h> #include <dxcapi.h>
#endif
#include <ShlObj_core.h> #include <ShlObj_core.h>
#include <algorithm> #include <algorithm>
#include <mutex> #include <mutex>

View file

@ -28,7 +28,12 @@ public:
CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false);
CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true); CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true);
#if defined(SWA_D3D12)
CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::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, WindowX, WINDOWPOS_CENTRED);
CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED); CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED);
CONFIG_DEFINE("Video", int32_t, WindowWidth, 1280); CONFIG_DEFINE("Video", int32_t, WindowWidth, 1280);

View file

@ -95,13 +95,17 @@ CONFIG_DEFINE_ENUM_TEMPLATE(EVoiceLanguage)
enum class EGraphicsAPI : uint32_t enum class EGraphicsAPI : uint32_t
{ {
#if defined(SWA_D3D12)
D3D12, D3D12,
#endif
Vulkan Vulkan
}; };
CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI) CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI)
{ {
#if defined(SWA_D3D12)
{ "D3D12", EGraphicsAPI::D3D12 }, { "D3D12", EGraphicsAPI::D3D12 },
#endif
{ "Vulkan", EGraphicsAPI::Vulkan } { "Vulkan", EGraphicsAPI::Vulkan }
}; };