Ver Fonte

[Windows] Make D3D12 loading dynamic to support pre Windows 10 versions.

bruvzg há 1 ano atrás
pai
commit
f4ca6a856a

+ 27 - 7
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<ID3D12Debug> 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.

+ 3 - 0
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;

+ 14 - 5
drivers/d3d12/rendering_device_driver_d3d12.cpp

@@ -3201,7 +3201,7 @@ Vector<uint8_t> 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<ID3DBlob> 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<uint8_t>(),
 				"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()));
 
@@ -3462,7 +3462,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;
 
@@ -5927,17 +5930,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()) {

+ 10 - 2
platform/windows/detect.py

@@ -421,6 +421,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",
@@ -485,7 +489,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.
@@ -650,6 +654,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"])
 
@@ -710,7 +718,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"]):

+ 2 - 0
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
 

+ 25 - 5
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;

+ 82 - 0
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;