diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 56e041be1b98..0e9638a625c5 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -1484,6 +1484,8 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF_RST("rendering/rendering_device/d3d12/max_misc_descriptors_per_frame", 512); custom_prop_info["rendering/rendering_device/d3d12/max_misc_descriptors_per_frame"] = PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/max_misc_descriptors_per_frame", PROPERTY_HINT_RANGE, "32,4096"); + GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/agility_sdk_version"), 610); + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Linear Mipmap,Nearest Mipmap"), 1); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, "Disable,Enable,Mirror"), 0); diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index ab92916320d9..09008905ceef 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2616,6 +2616,9 @@ Override for [member rendering/renderer/rendering_method] on web. + + Version code of the Direct3D 12 Agility SDK to use ([code]D3D12SDKVersion[/code]). + The number of entries in the miscellaneous descriptors heap the Direct3D 12 rendering driver uses each frame, used for various operations like clearing a texture. Depending on the complexity of scenes, this value may be lowered or may need to be raised. diff --git a/drivers/d3d12/d3d12_context.cpp b/drivers/d3d12/d3d12_context.cpp index 36492b198b14..97f5d91f3a8e 100644 --- a/drivers/d3d12/d3d12_context.cpp +++ b/drivers/d3d12/d3d12_context.cpp @@ -55,27 +55,14 @@ #include #include +#ifndef CLSID_D3D12DeviceFactory +// Note: symbol is not available in MinGW import library. +const CLSID CLSID_D3D12DeviceFactory = __uuidof(ID3D12DeviceFactory); +#endif #endif extern "C" { char godot_nir_arch_name[32]; - -#ifdef AGILITY_SDK_ENABLED -__declspec(dllexport) extern const UINT D3D12SDKVersion = 610; -#ifdef AGILITY_SDK_MULTIARCH_ENABLED -#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\arm64"; -#elif defined(__arm__) || defined(_M_ARM) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\arm32"; -#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64__) || defined(_M_X64) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\x86_64"; -#elif defined(__i386) || defined(__i386__) || defined(_M_IX86) -__declspec(dllexport) extern const char *D3D12SDKPath = "\\.\\x86_32"; -#endif -#else -__declspec(dllexport) extern const char *D3D12SDKPath = "\\."; -#endif // AGILITY_SDK_MULTIARCH -#endif // AGILITY_SDK_ENABLED } #ifdef PIX_ENABLED @@ -295,7 +282,12 @@ Error D3D12Context::_check_capabilities() { Error D3D12Context::_initialize_debug_layers() { ComPtr debug_controller; - HRESULT res = D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)); + HRESULT res; + if (device_factory) { + res = device_factory->GetConfigurationInterface(CLSID_D3D12Debug, IID_PPV_ARGS(&debug_controller)); + } else { + res = D3D12GetDebugInterface(IID_PPV_ARGS(&debug_controller)); + } ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_QUERY_FAILED); debug_controller->EnableDebugLayer(); return OK; @@ -501,7 +493,12 @@ void D3D12Context::_dump_adapter_info(int p_index) { } Error D3D12Context::_create_device(DeviceBasics &r_basics) { - HRESULT res = D3D12CreateDevice(gpu.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(r_basics.device.GetAddressOf())); + HRESULT res; + if (device_factory) { + res = device_factory->CreateDevice(gpu.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(r_basics.device.GetAddressOf())); + } else { + res = D3D12CreateDevice(gpu.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(r_basics.device.GetAddressOf())); + } ERR_FAIL_COND_V_MSG(!SUCCEEDED(res), ERR_CANT_CREATE, "D3D12CreateDevice failed with error " + vformat("0x%08ux", (uint64_t)res) + "."); // Create direct command queue. @@ -808,7 +805,32 @@ Error D3D12Context::_update_swap_chain(Window *window) { return OK; } +void D3D12Context::_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(); + + // 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"); + ERR_FAIL_COND(!d3d_D3D12GetInterface); + + ID3D12SDKConfiguration *sdk_config = nullptr; + if (SUCCEEDED(d3d_D3D12GetInterface(CLSID_D3D12SDKConfiguration, IID_PPV_ARGS(&sdk_config)))) { + ID3D12SDKConfiguration1 *sdk_config1 = nullptr; + if (SUCCEEDED(sdk_config->QueryInterface(&sdk_config1))) { + if (SUCCEEDED(sdk_config1->CreateDeviceFactory(agility_sdk_version, agility_sdk_path.ascii().get_data(), IID_PPV_ARGS(device_factory.GetAddressOf())))) { + d3d_D3D12GetInterface(CLSID_D3D12DeviceFactory, IID_PPV_ARGS(device_factory.GetAddressOf())); + } else if (SUCCEEDED(sdk_config1->CreateDeviceFactory(agility_sdk_version, ".\\", IID_PPV_ARGS(device_factory.GetAddressOf())))) { + d3d_D3D12GetInterface(CLSID_D3D12DeviceFactory, IID_PPV_ARGS(device_factory.GetAddressOf())); + } + sdk_config1->Release(); + } + sdk_config->Release(); + } +} + Error D3D12Context::initialize() { + _init_device_factory(); + if (_use_validation_layers()) { Error err = _initialize_debug_layers(); ERR_FAIL_COND_V(err, ERR_CANT_CREATE); diff --git a/drivers/d3d12/d3d12_context.h b/drivers/d3d12/d3d12_context.h index ec4bc832b656..27ec93bb7d99 100644 --- a/drivers/d3d12/d3d12_context.h +++ b/drivers/d3d12/d3d12_context.h @@ -110,6 +110,7 @@ class D3D12Context : public ApiContextRD { IMAGE_COUNT = FRAME_LAG + 1, }; + ComPtr device_factory; ComPtr dxgi_factory; ComPtr gpu; DeviceLimits gpu_limits = {}; @@ -181,6 +182,7 @@ class D3D12Context : public ApiContextRD { void *p_context); Error _initialize_debug_layers(); + void _init_device_factory(); Error _select_adapter(int &r_index); void _dump_adapter_info(int p_index);