diff --git a/drivers/d3d12/rendering_context_driver_d3d12.cpp b/drivers/d3d12/rendering_context_driver_d3d12.cpp index ad3b793305e4..1bd6483bfd25 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_context_driver_d3d12.cpp @@ -83,17 +83,28 @@ RenderingContextDriverD3D12::RenderingContextDriverD3D12() { } RenderingContextDriverD3D12::~RenderingContextDriverD3D12() { + if (lib_d3d12) { + FreeLibrary(lib_d3d12); + } + if (lib_dxgi) { + FreeLibrary(lib_dxgi); + } } Error RenderingContextDriverD3D12::_init_device_factory() { uint32_t agility_sdk_version = GLOBAL_GET("rendering/rendering_device/d3d12/agility_sdk_version"); String agility_sdk_path = String(".\\") + Engine::get_singleton()->get_architecture_name(); + lib_d3d12 = LoadLibraryW(L"D3D12.dll"); + ERR_FAIL_NULL_V(lib_d3d12, ERR_CANT_CREATE); + + lib_dxgi = LoadLibraryW(L"DXGI.dll"); + ERR_FAIL_NULL_V(lib_dxgi, ERR_CANT_CREATE); + // Note: symbol is not available in MinGW import library. - PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)GetProcAddress(LoadLibraryW(L"D3D12.dll"), "D3D12GetInterface"); - if (d3d_D3D12GetInterface == nullptr) { - // FIXME: Is it intended for this to silently return when it fails to find the symbol? - return OK; + PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetInterface"); + if (!d3d_D3D12GetInterface) { + return OK; // Fallback to the system loader. } ID3D12SDKConfiguration *sdk_config = nullptr; @@ -109,18 +120,22 @@ Error RenderingContextDriverD3D12::_init_device_factory() { } sdk_config->Release(); } - return OK; } Error RenderingContextDriverD3D12::_initialize_debug_layers() { ComPtr debug_controller; HRESULT res; + if (device_factory) { res = device_factory->GetConfigurationInterface(CLSID_D3D12DebugGodot, IID_PPV_ARGS(&debug_controller)); } else { - res = D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)); + PFN_D3D12_GET_DEBUG_INTERFACE d3d_D3D12GetDebugInterface = (PFN_D3D12_GET_DEBUG_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetDebugInterface"); + ERR_FAIL_NULL_V(d3d_D3D12GetDebugInterface, ERR_CANT_CREATE); + + res = d3d_D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)); } + ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_QUERY_FAILED); debug_controller->EnableDebugLayer(); return OK; @@ -128,7 +143,12 @@ Error RenderingContextDriverD3D12::_initialize_debug_layers() { Error RenderingContextDriverD3D12::_initialize_devices() { const UINT dxgi_factory_flags = use_validation_layers() ? DXGI_CREATE_FACTORY_DEBUG : 0; - HRESULT res = CreateDXGIFactory2(dxgi_factory_flags, IID_PPV_ARGS(&dxgi_factory)); + + typedef HRESULT(WINAPI * PFN_DXGI_CREATE_DXGI_FACTORY2)(UINT, REFIID, void **); + PFN_DXGI_CREATE_DXGI_FACTORY2 dxgi_CreateDXGIFactory2 = (PFN_DXGI_CREATE_DXGI_FACTORY2)(void *)GetProcAddress(lib_dxgi, "CreateDXGIFactory2"); + ERR_FAIL_NULL_V(dxgi_CreateDXGIFactory2, ERR_CANT_CREATE); + + HRESULT res = dxgi_CreateDXGIFactory2(dxgi_factory_flags, IID_PPV_ARGS(&dxgi_factory)); ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); // Enumerate all possible adapters. diff --git a/drivers/d3d12/rendering_context_driver_d3d12.h b/drivers/d3d12/rendering_context_driver_d3d12.h index 694d0b3e4ccc..f74105ed3d8f 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.h +++ b/drivers/d3d12/rendering_context_driver_d3d12.h @@ -107,6 +107,9 @@ public: bool needs_resize = false; }; + HMODULE lib_d3d12 = nullptr; + HMODULE lib_dxgi = nullptr; + IDXGIAdapter1 *create_adapter(uint32_t p_adapter_index) const; ID3D12DeviceFactory *device_factory_get() const; IDXGIFactory2 *dxgi_factory_get() const; diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index b4bbc44d9374..287726f4dba8 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -3222,7 +3222,7 @@ Vector RenderingDeviceDriverD3D12::shader_compile_binary_from_spirv(Vec root_sig_desc.Init_1_1(root_params.size(), root_params.ptr(), 0, nullptr, root_sig_flags); ComPtr error_blob; - HRESULT res = D3DX12SerializeVersionedRootSignature(&root_sig_desc, D3D_ROOT_SIGNATURE_VERSION_1_1, root_sig_blob.GetAddressOf(), error_blob.GetAddressOf()); + HRESULT res = D3DX12SerializeVersionedRootSignature(context_driver->lib_d3d12, &root_sig_desc, D3D_ROOT_SIGNATURE_VERSION_1_1, root_sig_blob.GetAddressOf(), error_blob.GetAddressOf()); ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), Vector(), "Serialization of root signature failed with error " + vformat("0x%08ux", (uint64_t)res) + " and the following message:\n" + String((char *)error_blob->GetBufferPointer(), error_blob->GetBufferSize())); @@ -3483,7 +3483,10 @@ RDD::ShaderID RenderingDeviceDriverD3D12::shader_create_from_bytecode(const Vect const uint8_t *root_sig_data_ptr = binptr + read_offset; - HRESULT res = D3D12CreateRootSignatureDeserializer(root_sig_data_ptr, binary_data.root_signature_len, IID_PPV_ARGS(shader_info_in.root_signature_deserializer.GetAddressOf())); + PFN_D3D12_CREATE_ROOT_SIGNATURE_DESERIALIZER d3d_D3D12CreateRootSignatureDeserializer = (PFN_D3D12_CREATE_ROOT_SIGNATURE_DESERIALIZER)(void *)GetProcAddress(context_driver->lib_d3d12, "D3D12CreateRootSignatureDeserializer"); + ERR_FAIL_NULL_V(d3d_D3D12CreateRootSignatureDeserializer, ShaderID()); + + HRESULT res = d3d_D3D12CreateRootSignatureDeserializer(root_sig_data_ptr, binary_data.root_signature_len, IID_PPV_ARGS(shader_info_in.root_signature_deserializer.GetAddressOf())); ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ShaderID(), "D3D12CreateRootSignatureDeserializer failed with error " + vformat("0x%08ux", (uint64_t)res) + "."); read_offset += binary_data.root_signature_len; @@ -6033,17 +6036,23 @@ Error RenderingDeviceDriverD3D12::_initialize_device() { HRESULT res; if (is_in_developer_mode()) { + typedef HRESULT(WINAPI * PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(_In_ UINT, _In_count_(NumFeatures) const IID *, _In_opt_count_(NumFeatures) void *, _In_opt_count_(NumFeatures) UINT *); + PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES d3d_D3D12EnableExperimentalFeatures = (PFN_D3D12_ENABLE_EXPERIMENTAL_FEATURES)(void *)GetProcAddress(context_driver->lib_d3d12, "D3D12EnableExperimentalFeatures"); + ERR_FAIL_NULL_V(d3d_D3D12EnableExperimentalFeatures, ERR_CANT_CREATE); + UUID experimental_features[] = { D3D12ExperimentalShaderModels }; - D3D12EnableExperimentalFeatures(1, experimental_features, nullptr, nullptr); + d3d_D3D12EnableExperimentalFeatures(1, experimental_features, nullptr, nullptr); } ID3D12DeviceFactory *device_factory = context_driver->device_factory_get(); if (device_factory != nullptr) { res = device_factory->CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf())); } else { - res = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf())); - } + PFN_D3D12_CREATE_DEVICE d3d_D3D12CreateDevice = (PFN_D3D12_CREATE_DEVICE)(void *)GetProcAddress(context_driver->lib_d3d12, "D3D12CreateDevice"); + ERR_FAIL_NULL_V(d3d_D3D12CreateDevice, ERR_CANT_CREATE); + res = d3d_D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(device.GetAddressOf())); + } ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "D3D12CreateDevice failed with error " + vformat("0x%08ux", (uint64_t)res) + "."); if (context_driver->use_validation_layers()) { diff --git a/platform/windows/detect.py b/platform/windows/detect.py index ca81bb615e81..b9a772cf4817 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -437,6 +437,10 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config): else: print("Missing environment variable: WindowsSdkDir") + if int(env["target_win_version"], 16) < 0x0601: + print("`target_win_version` should be 0x0601 or higher (Windows 7).") + sys.exit(255) + env.AppendUnique( CPPDEFINES=[ "WINDOWS_ENABLED", @@ -501,7 +505,7 @@ def configure_msvc(env: "SConsEnvironment", vcvars_msvc_config): sys.exit(255) env.AppendUnique(CPPDEFINES=["D3D12_ENABLED", "RD_ENABLED"]) - LIBS += ["d3d12", "dxgi", "dxguid"] + LIBS += ["dxgi", "dxguid"] LIBS += ["version"] # Mesa dependency. # Needed for avoiding C1128. @@ -666,6 +670,10 @@ def configure_mingw(env: "SConsEnvironment"): ## Compile flags + if int(env["target_win_version"], 16) < 0x0601: + print("`target_win_version` should be 0x0601 or higher (Windows 7).") + sys.exit(255) + if not env["use_llvm"]: env.Append(CCFLAGS=["-mwindows"]) @@ -726,7 +734,7 @@ def configure_mingw(env: "SConsEnvironment"): sys.exit(255) env.AppendUnique(CPPDEFINES=["D3D12_ENABLED", "RD_ENABLED"]) - env.Append(LIBS=["d3d12", "dxgi", "dxguid"]) + env.Append(LIBS=["dxgi", "dxguid"]) # PIX if not env["arch"] in ["x86_64", "arm64"] or env["pix_path"] == "" or not os.path.exists(env["pix_path"]): diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 81cddec49f56..052331a45f9c 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -192,6 +192,7 @@ typedef UINT32 PEN_MASK; #define POINTER_MESSAGE_FLAG_FIRSTBUTTON 0x00000010 #endif +#if WINVER < 0x0602 enum tagPOINTER_INPUT_TYPE { PT_POINTER = 0x00000001, PT_TOUCH = 0x00000002, @@ -242,6 +243,7 @@ typedef struct tagPOINTER_PEN_INFO { INT32 tiltX; INT32 tiltY; } POINTER_PEN_INFO; +#endif #endif //POINTER_STRUCTURES diff --git a/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h b/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h index 572efed85243..a83d9d017c7a 100644 --- a/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h +++ b/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h @@ -996,6 +996,9 @@ struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE // two code paths for building root signatures, this helper method reconstructs a 1.0 signature when // 1.1 is not supported. inline HRESULT D3DX12SerializeVersionedRootSignature( +/* GODOT start */ + _In_ HMODULE pLibD3D12, +/* GODOT end */ _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION MaxVersion, _Outptr_ ID3DBlob** ppBlob, @@ -1006,13 +1009,22 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( *ppErrorBlob = nullptr; } + /* GODOT start */ + PFN_D3D12_SERIALIZE_ROOT_SIGNATURE d3d_D3D12SerializeRootSignature = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)(void *)GetProcAddress(pLibD3D12, "D3D12SerializeRootSignature"); + if (d3d_D3D12SerializeRootSignature == nullptr) { + return E_INVALIDARG; + } + PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE d3d_D3D12SerializeVersionedRootSignature = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)(void *)GetProcAddress(pLibD3D12, "D3D12SerializeVersionedRootSignature"); + /* GODOT end */ switch (MaxVersion) { case D3D_ROOT_SIGNATURE_VERSION_1_0: switch (pRootSignatureDesc->Version) { case D3D_ROOT_SIGNATURE_VERSION_1_0: - return D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); +/* GODOT start */ + return d3d_D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); +/* GODOT end */ case D3D_ROOT_SIGNATURE_VERSION_1_1: #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609) @@ -1114,7 +1126,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( if (SUCCEEDED(hr)) { const CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, pStaticSamplers == nullptr ? desc_1_1.pStaticSamplers : pStaticSamplers, desc_1_1.Flags); - hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); +/* GODOT start */ + hr = d3d_D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); +/* GODOT end */ } if (pParameters) @@ -1145,7 +1159,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( { case D3D_ROOT_SIGNATURE_VERSION_1_0: case D3D_ROOT_SIGNATURE_VERSION_1_1: - return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); +/* GODOT start */ + return d3d_D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); +/* GODOT end */ #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609) case D3D_ROOT_SIGNATURE_VERSION_1_2: @@ -1181,7 +1197,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( if (SUCCEEDED(hr)) { const CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC desc(desc_1_1.NumParameters, desc_1_1.pParameters, desc_1_1.NumStaticSamplers, pStaticSamplers == nullptr ? desc_1_1.pStaticSamplers : pStaticSamplers, desc_1_1.Flags); - hr = D3D12SerializeVersionedRootSignature(&desc, ppBlob, ppErrorBlob); +/* GODOT start */ + hr = d3d_D3D12SerializeVersionedRootSignature(&desc, ppBlob, ppErrorBlob); +/* GODOT end */ } if (pStaticSamplers) @@ -1197,7 +1215,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609) case D3D_ROOT_SIGNATURE_VERSION_1_2: #endif - return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); +/* GODOT start */ + return d3d_D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); +/* GODOT end */ } return E_INVALIDARG; diff --git a/thirdparty/directx_headers/patches/patch_d3d12_dynamic_load.diff b/thirdparty/directx_headers/patches/patch_d3d12_dynamic_load.diff new file mode 100644 index 000000000000..d520a4417219 --- /dev/null +++ b/thirdparty/directx_headers/patches/patch_d3d12_dynamic_load.diff @@ -0,0 +1,82 @@ +diff --git a/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h b/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h +index 572efed852..18efa7a0cb 100644 +--- a/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h ++++ b/thirdparty/directx_headers/include/directx/d3dx12_root_signature.h +@@ -996,6 +996,9 @@ struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE + // two code paths for building root signatures, this helper method reconstructs a 1.0 signature when + // 1.1 is not supported. + inline HRESULT D3DX12SerializeVersionedRootSignature( ++/* GODOT start */ ++ _In_ HMODULE pLibD3D12, ++/* GODOT end */ + _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignatureDesc, + D3D_ROOT_SIGNATURE_VERSION MaxVersion, + _Outptr_ ID3DBlob** ppBlob, +@@ -1006,13 +1009,22 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( + *ppErrorBlob = nullptr; + } + ++ /* GODOT start */ ++ PFN_D3D12_SERIALIZE_ROOT_SIGNATURE d3d_D3D12SerializeRootSignature = (PFN_D3D12_SERIALIZE_ROOT_SIGNATURE)(void *)GetProcAddress(pLibD3D12, "D3D12SerializeRootSignature"); ++ if (d3d_D3D12SerializeRootSignature == nullptr) { ++ return E_INVALIDARG; ++ } ++ PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE d3d_D3D12SerializeVersionedRootSignature = (PFN_D3D12_SERIALIZE_VERSIONED_ROOT_SIGNATURE)(void *)GetProcAddress(pLibD3D12, "D3D12SerializeVersionedRootSignature"); ++ /* GODOT end */ + switch (MaxVersion) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + switch (pRootSignatureDesc->Version) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: +- return D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); ++/* GODOT start */ ++ return d3d_D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); ++/* GODOT end */ + + case D3D_ROOT_SIGNATURE_VERSION_1_1: + #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609) +@@ -1114,7 +1126,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( + if (SUCCEEDED(hr)) + { + const CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, pStaticSamplers == nullptr ? desc_1_1.pStaticSamplers : pStaticSamplers, desc_1_1.Flags); +- hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); ++/* GODOT start */ ++ hr = d3d_D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); ++/* GODOT end */ + } + + if (pParameters) +@@ -1145,7 +1159,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + case D3D_ROOT_SIGNATURE_VERSION_1_1: +- return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); ++/* GODOT start */ ++ return d3d_D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); ++/* GODOT end */ + + #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609) + case D3D_ROOT_SIGNATURE_VERSION_1_2: +@@ -1181,7 +1197,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( + if (SUCCEEDED(hr)) + { + const CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC desc(desc_1_1.NumParameters, desc_1_1.pParameters, desc_1_1.NumStaticSamplers, pStaticSamplers == nullptr ? desc_1_1.pStaticSamplers : pStaticSamplers, desc_1_1.Flags); +- hr = D3D12SerializeVersionedRootSignature(&desc, ppBlob, ppErrorBlob); ++/* GODOT start */ ++ hr = d3d_D3D12SerializeVersionedRootSignature(&desc, ppBlob, ppErrorBlob); ++/* GODOT end */ + } + + if (pStaticSamplers) +@@ -1197,7 +1215,9 @@ inline HRESULT D3DX12SerializeVersionedRootSignature( + #if defined(D3D12_SDK_VERSION) && (D3D12_SDK_VERSION >= 609) + case D3D_ROOT_SIGNATURE_VERSION_1_2: + #endif +- return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); ++/* GODOT start */ ++ return d3d_D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); ++/* GODOT end */ + } + + return E_INVALIDARG;