mirror of
https://github.com/stenzek/duckstation.git
synced 2025-07-18 16:10:07 +00:00
D3DCommon: Load d3d12.dll dynamically
This commit is contained in:
parent
4ead72747b
commit
3bb67c785e
@ -241,7 +241,7 @@ if(WIN32)
|
||||
xinput_source.h
|
||||
)
|
||||
target_link_libraries(util PRIVATE d3d12ma)
|
||||
target_link_libraries(util PRIVATE d3d12.lib winmm.lib Dwmapi.lib winhttp.lib)
|
||||
target_link_libraries(util PRIVATE winmm.lib Dwmapi.lib winhttp.lib)
|
||||
|
||||
if(CMAKE_BUILD_TYPE MATCHES "Debug|Devel")
|
||||
target_link_libraries(util PRIVATE WinPixEventRuntime::WinPixEventRuntime)
|
||||
|
@ -129,28 +129,10 @@ D3D12Device::~D3D12Device()
|
||||
Assert(s_pipeline_cache_data.empty());
|
||||
}
|
||||
|
||||
D3D12Device::ComPtr<ID3DBlob> D3D12Device::SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc, Error* error)
|
||||
{
|
||||
ComPtr<ID3DBlob> blob;
|
||||
ComPtr<ID3DBlob> error_blob;
|
||||
const HRESULT hr =
|
||||
D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1, blob.GetAddressOf(), error_blob.GetAddressOf());
|
||||
if (FAILED(hr)) [[unlikely]]
|
||||
{
|
||||
Error::SetHResult(error, "D3D12SerializeRootSignature() failed: ", hr);
|
||||
if (error_blob)
|
||||
ERROR_LOG(static_cast<const char*>(error_blob->GetBufferPointer()));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
D3D12Device::ComPtr<ID3D12RootSignature> D3D12Device::CreateRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc,
|
||||
Error* error)
|
||||
{
|
||||
ComPtr<ID3DBlob> blob = SerializeRootSignature(desc, error);
|
||||
ComPtr<ID3DBlob> blob = D3DCommon::SerializeRootSignature(desc, error);
|
||||
if (!blob)
|
||||
return {};
|
||||
|
||||
@ -186,7 +168,7 @@ bool D3D12Device::CreateDeviceAndMainSwapChain(std::string_view adapter, Feature
|
||||
if (m_debug_device)
|
||||
{
|
||||
ComPtr<ID3D12Debug> debug12;
|
||||
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(debug12.GetAddressOf()))))
|
||||
if (D3DCommon::GetD3D12DebugInterface(&debug12, nullptr))
|
||||
{
|
||||
INFO_LOG("Enabling debug layer.");
|
||||
debug12->EnableDebugLayer();
|
||||
@ -217,18 +199,14 @@ bool D3D12Device::CreateDeviceAndMainSwapChain(std::string_view adapter, Feature
|
||||
D3D_FEATURE_LEVEL feature_level = D3D_FEATURE_LEVEL_1_0_CORE;
|
||||
for (D3D_FEATURE_LEVEL try_feature_level : {D3D_FEATURE_LEVEL_12_0, D3D_FEATURE_LEVEL_11_0})
|
||||
{
|
||||
hr = D3D12CreateDevice(m_adapter.Get(), try_feature_level, IID_PPV_ARGS(&m_device));
|
||||
if (SUCCEEDED(hr))
|
||||
if (D3DCommon::CreateD3D12Device(m_adapter.Get(), try_feature_level, &m_device, error))
|
||||
{
|
||||
feature_level = try_feature_level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Error::SetHResult(error, "Failed to create D3D12 device: ", hr);
|
||||
if (!m_device)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_adapter)
|
||||
{
|
||||
|
@ -162,7 +162,6 @@ public:
|
||||
ID3D12GraphicsCommandList4* GetInitCommandList();
|
||||
|
||||
// Root signature access.
|
||||
ComPtr<ID3DBlob> SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc, Error* error);
|
||||
ComPtr<ID3D12RootSignature> CreateRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc, Error* error);
|
||||
|
||||
/// Fence value for current command list.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
#include <d3d12.h>
|
||||
#include <d3dcompiler.h>
|
||||
#include <dxcapi.h>
|
||||
#include <dxgi1_5.h>
|
||||
@ -39,6 +40,10 @@ struct Libs
|
||||
decltype(&CreateDXGIFactory2) CreateDXGIFactory2;
|
||||
DynamicLibrary d3d11_library;
|
||||
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
|
||||
DynamicLibrary d3d12_library;
|
||||
PFN_D3D12_CREATE_DEVICE D3D12CreateDevice;
|
||||
PFN_D3D12_GET_DEBUG_INTERFACE D3D12GetDebugInterface;
|
||||
PFN_D3D12_SERIALIZE_ROOT_SIGNATURE D3D12SerializeRootSignature;
|
||||
DynamicLibrary d3dcompiler_library;
|
||||
pD3DCompile D3DCompile;
|
||||
DynamicLibrary dxcompiler_library;
|
||||
@ -53,6 +58,7 @@ static std::optional<DynamicHeapArray<u8>> CompileShaderWithFXC(u32 shader_model
|
||||
static std::optional<DynamicHeapArray<u8>> CompileShaderWithDXC(u32 shader_model, bool debug_device,
|
||||
GPUShaderStage stage, std::string_view source,
|
||||
const char* entry_point, Error* error);
|
||||
static bool LoadD3D12Library(Error* error);
|
||||
static bool LoadD3DCompilerLibrary(Error* error);
|
||||
static bool LoadDXCompilerLibrary(Error* error);
|
||||
|
||||
@ -201,6 +207,80 @@ bool D3DCommon::CreateD3D11Device(IDXGIAdapter* adapter, UINT create_flags, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3DCommon::LoadD3D12Library(Error* error)
|
||||
{
|
||||
if (s_libs.d3d12_library.IsOpen())
|
||||
return true;
|
||||
|
||||
// double check, another thread may have opened it
|
||||
const std::unique_lock lock(s_libs.load_mutex);
|
||||
if (s_libs.d3d12_library.IsOpen())
|
||||
return true;
|
||||
|
||||
if (!s_libs.d3d12_library.Open("d3d12.dll", error))
|
||||
return false;
|
||||
|
||||
if (!s_libs.d3d12_library.GetSymbol("D3D12CreateDevice", &s_libs.D3D12CreateDevice) ||
|
||||
!s_libs.d3d12_library.GetSymbol("D3D12GetDebugInterface", &s_libs.D3D12GetDebugInterface) ||
|
||||
!s_libs.d3d12_library.GetSymbol("D3D12SerializeRootSignature", &s_libs.D3D12SerializeRootSignature))
|
||||
{
|
||||
Error::SetStringView(error, "Failed to load one or more required functions from d3d12.dll");
|
||||
s_libs.d3d12_library.Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3DCommon::GetD3D12DebugInterface(Microsoft::WRL::ComPtr<ID3D12Debug>* debug, Error* error)
|
||||
{
|
||||
if (!LoadD3D12Library(error))
|
||||
return false;
|
||||
|
||||
const HRESULT hr = s_libs.D3D12GetDebugInterface(IID_PPV_ARGS(debug->ReleaseAndGetAddressOf()));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Error::SetHResult(error, "D3D12GetDebugInterface() failed: ", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool D3DCommon::CreateD3D12Device(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL feature_level,
|
||||
Microsoft::WRL::ComPtr<ID3D12Device1>* device, Error* error)
|
||||
{
|
||||
if (!LoadD3D12Library(error))
|
||||
return false;
|
||||
|
||||
const HRESULT hr = s_libs.D3D12CreateDevice(adapter, feature_level, IID_PPV_ARGS(device->ReleaseAndGetAddressOf()));
|
||||
if (FAILED(hr))
|
||||
{
|
||||
Error::SetHResult(error, "D3D12CreateDevice() failed: ", hr);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Microsoft::WRL::ComPtr<ID3DBlob> D3DCommon::SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc, Error* error)
|
||||
{
|
||||
Microsoft::WRL::ComPtr<ID3DBlob> blob;
|
||||
Microsoft::WRL::ComPtr<ID3DBlob> error_blob;
|
||||
const HRESULT hr = s_libs.D3D12SerializeRootSignature(desc, D3D_ROOT_SIGNATURE_VERSION_1, blob.GetAddressOf(),
|
||||
error_blob.GetAddressOf());
|
||||
if (FAILED(hr)) [[unlikely]]
|
||||
{
|
||||
Error::SetHResult(error, "D3D12SerializeRootSignature() failed: ", hr);
|
||||
if (error_blob)
|
||||
ERROR_LOG(static_cast<const char*>(error_blob->GetBufferPointer()));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
||||
static std::string FixupDuplicateAdapterNames(const GPUDevice::AdapterInfoList& adapter_names, std::string adapter_name)
|
||||
{
|
||||
if (std::any_of(adapter_names.begin(), adapter_names.end(),
|
||||
|
@ -21,12 +21,16 @@ class Error;
|
||||
|
||||
enum class GPUDriverType : u16;
|
||||
|
||||
struct D3D12_ROOT_SIGNATURE_DESC;
|
||||
|
||||
struct IDXGIFactory5;
|
||||
struct IDXGIAdapter;
|
||||
struct IDXGIAdapter1;
|
||||
struct IDXGIOutput;
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
struct ID3D12Debug;
|
||||
struct ID3D12Device1;
|
||||
|
||||
namespace D3DCommon {
|
||||
|
||||
@ -49,6 +53,12 @@ bool CreateD3D11Device(IDXGIAdapter* adapter, UINT create_flags, const D3D_FEATU
|
||||
D3D_FEATURE_LEVEL* out_feature_level,
|
||||
Microsoft::WRL::ComPtr<ID3D11DeviceContext>* immediate_context, Error* error);
|
||||
|
||||
// D3D12 functions
|
||||
bool GetD3D12DebugInterface(Microsoft::WRL::ComPtr<ID3D12Debug>* debug, Error* error);
|
||||
bool CreateD3D12Device(IDXGIAdapter* adapter, D3D_FEATURE_LEVEL feature_level,
|
||||
Microsoft::WRL::ComPtr<ID3D12Device1>* device, Error* error);
|
||||
Microsoft::WRL::ComPtr<ID3DBlob> SerializeRootSignature(const D3D12_ROOT_SIGNATURE_DESC* desc, Error* error);
|
||||
|
||||
// returns a list of all adapter names
|
||||
GPUDevice::AdapterInfoList GetAdapterInfoList();
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<ItemDefinitionGroup>
|
||||
<Link>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);d3d12.lib;Dwmapi.lib;winhttp.lib</AdditionalDependencies>
|
||||
<AdditionalDependencies>%(AdditionalDependencies);Dwmapi.lib;winhttp.lib</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user