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")
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 $<TARGET_PROPERTY:Microsoft::DirectX12-Core,IMPORTED_LOCATION_RELEASE> ${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

View file

@ -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<RenderInterface> CreateD3D12Interface();
#endif
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<RenderDevice> g_device;
@ -1062,6 +1073,8 @@ static GuestShader* g_csdShader;
static std::unique_ptr<GuestShader> 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<GuestShader> 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<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)
{
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<uint32_t, ComPtr<IDxcBlob>> g_compiledSpecConstantLibraryBlobs;
thread_local ComPtr<IDxcCompiler3> s_dxcCompiler;
thread_local ComPtr<IDxcLinker> s_dxcLinker;
thread_local ComPtr<IDxcUtils> s_dxcUtils;
@ -2916,6 +2944,7 @@ static RenderShader* GetOrLinkShader(GuestShader* guestShader, uint32_t specCons
shader = linkedShader.get();
}
}
#endif
return shader;
}

View file

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

View file

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

View file

@ -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);

View file

@ -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 }
};