diff --git a/core/os/os.h b/core/os/os.h index 4ad91a77ea0..140449c8984 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -365,9 +365,11 @@ public: // This is invoked by the GDExtensionManager after loading GDExtensions specified by the project. virtual void load_platform_gdextensions() const {} +#ifdef TOOLS_ENABLED // Tests OpenGL context and Rendering Device simultaneous creation. This function is expected to crash on some NVIDIA drivers. virtual bool _test_create_rendering_device_and_gl(const String &p_display_driver) const { return true; } virtual bool _test_create_rendering_device(const String &p_display_driver) const { return true; } +#endif OS(); virtual ~OS(); diff --git a/drivers/d3d12/SCsub b/drivers/d3d12/SCsub index 8e325c5a1b7..bbe932d227d 100644 --- a/drivers/d3d12/SCsub +++ b/drivers/d3d12/SCsub @@ -41,6 +41,12 @@ if env["use_pix"]: env_d3d12_rdd.Append(CPPEXTPATH=[env["pix_path"] + "/Include"]) +# Direct composition. + +if "dcomp" in env.get("supported", []): + env_d3d12_rdd.Append(CPPDEFINES=["DCOMP_ENABLED"]) + + # Mesa (SPIR-V to DXIL functionality). mesa_libs = env["mesa_libs"] diff --git a/drivers/d3d12/rendering_context_driver_d3d12.cpp b/drivers/d3d12/rendering_context_driver_d3d12.cpp index 10699e75765..fbb66c3183d 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_context_driver_d3d12.cpp @@ -78,9 +78,11 @@ RenderingContextDriverD3D12::~RenderingContextDriverD3D12() { if (lib_dxgi) { FreeLibrary(lib_dxgi); } +#ifdef DCOMP_ENABLED if (lib_dcomp) { FreeLibrary(lib_dcomp); } +#endif } Error RenderingContextDriverD3D12::_init_device_factory() { @@ -93,8 +95,10 @@ Error RenderingContextDriverD3D12::_init_device_factory() { lib_dxgi = LoadLibraryW(L"DXGI.dll"); ERR_FAIL_NULL_V(lib_dxgi, ERR_CANT_CREATE); +#ifdef DCOMP_ENABLED lib_dcomp = LoadLibraryW(L"Dcomp.dll"); ERR_FAIL_NULL_V(lib_dcomp, ERR_CANT_CREATE); +#endif // Note: symbol is not available in MinGW import library. PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetInterface"); diff --git a/drivers/d3d12/rendering_context_driver_d3d12.h b/drivers/d3d12/rendering_context_driver_d3d12.h index 234517d9ec7..7ffe5afb803 100644 --- a/drivers/d3d12/rendering_context_driver_d3d12.h +++ b/drivers/d3d12/rendering_context_driver_d3d12.h @@ -41,6 +41,7 @@ #undef AS #endif +#ifdef DCOMP_ENABLED #if (WINVER < _WIN32_WINNT_WIN8) && defined(_MSC_VER) #pragma push_macro("NTDDI_VERSION") #pragma push_macro("WINVER") @@ -54,6 +55,7 @@ #else #include #endif +#endif #include #include @@ -104,14 +106,18 @@ public: uint32_t height = 0; DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED; bool needs_resize = false; +#ifdef DCOMP_ENABLED ComPtr composition_device; ComPtr composition_target; ComPtr composition_visual; +#endif }; HMODULE lib_d3d12 = nullptr; HMODULE lib_dxgi = nullptr; +#ifdef DCOMP_ENABLED HMODULE lib_dcomp = nullptr; +#endif IDXGIAdapter1 *create_adapter(uint32_t p_adapter_index) const; ID3D12DeviceFactory *device_factory_get() const; diff --git a/drivers/d3d12/rendering_device_driver_d3d12.cpp b/drivers/d3d12/rendering_device_driver_d3d12.cpp index cda97726e2c..a7208c5af9e 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.cpp +++ b/drivers/d3d12/rendering_device_driver_d3d12.cpp @@ -2609,7 +2609,16 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue, swap_chain_desc.Height = surface->height; ComPtr swap_chain_1; +#ifdef DCOMP_ENABLED res = context_driver->dxgi_factory_get()->CreateSwapChainForComposition(command_queue->d3d_queue.Get(), &swap_chain_desc, nullptr, swap_chain_1.GetAddressOf()); +#else + res = context_driver->dxgi_factory_get()->CreateSwapChainForHwnd(command_queue->d3d_queue.Get(), surface->hwnd, &swap_chain_desc, nullptr, nullptr, swap_chain_1.GetAddressOf()); + if (!SUCCEEDED(res) && swap_chain_desc.AlphaMode != DXGI_ALPHA_MODE_IGNORE) { + swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE; + has_comp_alpha[(uint64_t)p_cmd_queue.id] = false; + res = context_driver->dxgi_factory_get()->CreateSwapChainForHwnd(command_queue->d3d_queue.Get(), surface->hwnd, &swap_chain_desc, nullptr, nullptr, swap_chain_1.GetAddressOf()); + } +#endif ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); swap_chain_1.As(&swap_chain->d3d_swap_chain); @@ -2619,6 +2628,7 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue, ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); } +#ifdef DCOMP_ENABLED if (surface->composition_device.Get() == nullptr) { using PFN_DCompositionCreateDevice = HRESULT(WINAPI *)(IDXGIDevice *, REFIID, void **); PFN_DCompositionCreateDevice pfn_DCompositionCreateDevice = (PFN_DCompositionCreateDevice)(void *)GetProcAddress(context_driver->lib_dcomp, "DCompositionCreateDevice"); @@ -2648,6 +2658,7 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue, res = surface->composition_device->Commit(); ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); } +#endif res = swap_chain->d3d_swap_chain->GetDesc1(&swap_chain_desc); ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE); diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 8b02d089e22..91958cb7633 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -1197,6 +1197,7 @@ String OS_LinuxBSD::get_system_ca_certificates() { return f->get_as_text(); } +#ifdef TOOLS_ENABLED bool OS_LinuxBSD::_test_create_rendering_device(const String &p_display_driver) const { // Tests Rendering Device creation. @@ -1263,6 +1264,7 @@ bool OS_LinuxBSD::_test_create_rendering_device_and_gl(const String &p_display_d #endif return _test_create_rendering_device(p_display_driver); } +#endif OS_LinuxBSD::OS_LinuxBSD() { main_loop = nullptr; diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index 736b03232b0..50bc0910283 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -137,8 +137,10 @@ public: virtual String get_system_ca_certificates() override; +#ifdef TOOLS_ENABLED virtual bool _test_create_rendering_device_and_gl(const String &p_display_driver) const override; virtual bool _test_create_rendering_device(const String &p_display_driver) const override; +#endif OS_LinuxBSD(); ~OS_LinuxBSD(); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index de97685b858..1e7ca0ca036 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -241,7 +241,7 @@ def get_flags(): return { "arch": arch, - "supported": ["d3d12", "mono", "xaudio2"], + "supported": ["d3d12", "dcomp", "mono", "xaudio2"], } diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index b54a821cd80..10958317091 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -281,6 +281,7 @@ void OS_Windows::initialize() { QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second); QueryPerformanceCounter((LARGE_INTEGER *)&ticks_start); +#if WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP // set minimum resolution for periodic timers, otherwise Sleep(n) may wait at least as // long as the windows scheduler resolution (~16-30ms) even for calls like Sleep(1) TIMECAPS time_caps; @@ -292,6 +293,9 @@ void OS_Windows::initialize() { delay_resolution = 1000; timeBeginPeriod(1); } +#else + delay_resolution = 1000; +#endif process_map = memnew((HashMap)); @@ -374,7 +378,9 @@ void OS_Windows::finalize_core() { FileAccessWindows::finalize(); +#if WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP timeEndPeriod(1); +#endif memdelete(process_map); NetSocketWinSock::cleanup(); @@ -2564,6 +2570,7 @@ void OS_Windows::add_frame_delay(bool p_can_draw) { } } +#ifdef TOOLS_ENABLED bool OS_Windows::_test_create_rendering_device(const String &p_display_driver) const { // Tests Rendering Device creation. @@ -2656,6 +2663,7 @@ bool OS_Windows::_test_create_rendering_device_and_gl(const String &p_display_dr UnregisterClassW(L"Engine probe window", GetModuleHandle(nullptr)); return ok; } +#endif OS_Windows::OS_Windows(HINSTANCE _hInstance) { hInstance = _hInstance; diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index bc820facd56..1f762c06296 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -257,8 +257,10 @@ public: void set_main_window(HWND p_main_window) { main_window = p_main_window; } +#ifdef TOOLS_ENABLED virtual bool _test_create_rendering_device_and_gl(const String &p_display_driver) const override; virtual bool _test_create_rendering_device(const String &p_display_driver) const override; +#endif HINSTANCE get_hinstance() { return hInstance; } OS_Windows(HINSTANCE _hInstance);