You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Merge pull request #106400 from RandomShaper/win_compat
Improve platform compatibility of Windows and Direct3D 12
This commit is contained in:
@@ -365,9 +365,11 @@ public:
|
|||||||
// This is invoked by the GDExtensionManager after loading GDExtensions specified by the project.
|
// This is invoked by the GDExtensionManager after loading GDExtensions specified by the project.
|
||||||
virtual void load_platform_gdextensions() const {}
|
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.
|
// 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_and_gl(const String &p_display_driver) const { return true; }
|
||||||
virtual bool _test_create_rendering_device(const String &p_display_driver) const { return true; }
|
virtual bool _test_create_rendering_device(const String &p_display_driver) const { return true; }
|
||||||
|
#endif
|
||||||
|
|
||||||
OS();
|
OS();
|
||||||
virtual ~OS();
|
virtual ~OS();
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ if env["use_pix"]:
|
|||||||
env_d3d12_rdd.Append(CPPEXTPATH=[env["pix_path"] + "/Include"])
|
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 (SPIR-V to DXIL functionality).
|
||||||
|
|
||||||
mesa_libs = env["mesa_libs"]
|
mesa_libs = env["mesa_libs"]
|
||||||
|
|||||||
@@ -78,9 +78,11 @@ RenderingContextDriverD3D12::~RenderingContextDriverD3D12() {
|
|||||||
if (lib_dxgi) {
|
if (lib_dxgi) {
|
||||||
FreeLibrary(lib_dxgi);
|
FreeLibrary(lib_dxgi);
|
||||||
}
|
}
|
||||||
|
#ifdef DCOMP_ENABLED
|
||||||
if (lib_dcomp) {
|
if (lib_dcomp) {
|
||||||
FreeLibrary(lib_dcomp);
|
FreeLibrary(lib_dcomp);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Error RenderingContextDriverD3D12::_init_device_factory() {
|
Error RenderingContextDriverD3D12::_init_device_factory() {
|
||||||
@@ -93,8 +95,10 @@ Error RenderingContextDriverD3D12::_init_device_factory() {
|
|||||||
lib_dxgi = LoadLibraryW(L"DXGI.dll");
|
lib_dxgi = LoadLibraryW(L"DXGI.dll");
|
||||||
ERR_FAIL_NULL_V(lib_dxgi, ERR_CANT_CREATE);
|
ERR_FAIL_NULL_V(lib_dxgi, ERR_CANT_CREATE);
|
||||||
|
|
||||||
|
#ifdef DCOMP_ENABLED
|
||||||
lib_dcomp = LoadLibraryW(L"Dcomp.dll");
|
lib_dcomp = LoadLibraryW(L"Dcomp.dll");
|
||||||
ERR_FAIL_NULL_V(lib_dcomp, ERR_CANT_CREATE);
|
ERR_FAIL_NULL_V(lib_dcomp, ERR_CANT_CREATE);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Note: symbol is not available in MinGW import library.
|
// Note: symbol is not available in MinGW import library.
|
||||||
PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetInterface");
|
PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetInterface");
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#undef AS
|
#undef AS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef DCOMP_ENABLED
|
||||||
#if (WINVER < _WIN32_WINNT_WIN8) && defined(_MSC_VER)
|
#if (WINVER < _WIN32_WINNT_WIN8) && defined(_MSC_VER)
|
||||||
#pragma push_macro("NTDDI_VERSION")
|
#pragma push_macro("NTDDI_VERSION")
|
||||||
#pragma push_macro("WINVER")
|
#pragma push_macro("WINVER")
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <dcomp.h>
|
#include <dcomp.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <d3dx12.h>
|
#include <d3dx12.h>
|
||||||
#include <dxgi1_6.h>
|
#include <dxgi1_6.h>
|
||||||
@@ -104,14 +106,18 @@ public:
|
|||||||
uint32_t height = 0;
|
uint32_t height = 0;
|
||||||
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
|
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
|
||||||
bool needs_resize = false;
|
bool needs_resize = false;
|
||||||
|
#ifdef DCOMP_ENABLED
|
||||||
ComPtr<IDCompositionDevice> composition_device;
|
ComPtr<IDCompositionDevice> composition_device;
|
||||||
ComPtr<IDCompositionTarget> composition_target;
|
ComPtr<IDCompositionTarget> composition_target;
|
||||||
ComPtr<IDCompositionVisual> composition_visual;
|
ComPtr<IDCompositionVisual> composition_visual;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
HMODULE lib_d3d12 = nullptr;
|
HMODULE lib_d3d12 = nullptr;
|
||||||
HMODULE lib_dxgi = nullptr;
|
HMODULE lib_dxgi = nullptr;
|
||||||
|
#ifdef DCOMP_ENABLED
|
||||||
HMODULE lib_dcomp = nullptr;
|
HMODULE lib_dcomp = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
IDXGIAdapter1 *create_adapter(uint32_t p_adapter_index) const;
|
IDXGIAdapter1 *create_adapter(uint32_t p_adapter_index) const;
|
||||||
ID3D12DeviceFactory *device_factory_get() const;
|
ID3D12DeviceFactory *device_factory_get() const;
|
||||||
|
|||||||
@@ -2609,7 +2609,16 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
|
|||||||
swap_chain_desc.Height = surface->height;
|
swap_chain_desc.Height = surface->height;
|
||||||
|
|
||||||
ComPtr<IDXGISwapChain1> swap_chain_1;
|
ComPtr<IDXGISwapChain1> 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());
|
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);
|
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
||||||
|
|
||||||
swap_chain_1.As(&swap_chain->d3d_swap_chain);
|
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);
|
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DCOMP_ENABLED
|
||||||
if (surface->composition_device.Get() == nullptr) {
|
if (surface->composition_device.Get() == nullptr) {
|
||||||
using PFN_DCompositionCreateDevice = HRESULT(WINAPI *)(IDXGIDevice *, REFIID, void **);
|
using PFN_DCompositionCreateDevice = HRESULT(WINAPI *)(IDXGIDevice *, REFIID, void **);
|
||||||
PFN_DCompositionCreateDevice pfn_DCompositionCreateDevice = (PFN_DCompositionCreateDevice)(void *)GetProcAddress(context_driver->lib_dcomp, "DCompositionCreateDevice");
|
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();
|
res = surface->composition_device->Commit();
|
||||||
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
res = swap_chain->d3d_swap_chain->GetDesc1(&swap_chain_desc);
|
res = swap_chain->d3d_swap_chain->GetDesc1(&swap_chain_desc);
|
||||||
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
|
||||||
|
|||||||
@@ -1197,6 +1197,7 @@ String OS_LinuxBSD::get_system_ca_certificates() {
|
|||||||
return f->get_as_text();
|
return f->get_as_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TOOLS_ENABLED
|
||||||
bool OS_LinuxBSD::_test_create_rendering_device(const String &p_display_driver) const {
|
bool OS_LinuxBSD::_test_create_rendering_device(const String &p_display_driver) const {
|
||||||
// Tests Rendering Device creation.
|
// Tests Rendering Device creation.
|
||||||
|
|
||||||
@@ -1263,6 +1264,7 @@ bool OS_LinuxBSD::_test_create_rendering_device_and_gl(const String &p_display_d
|
|||||||
#endif
|
#endif
|
||||||
return _test_create_rendering_device(p_display_driver);
|
return _test_create_rendering_device(p_display_driver);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
OS_LinuxBSD::OS_LinuxBSD() {
|
OS_LinuxBSD::OS_LinuxBSD() {
|
||||||
main_loop = nullptr;
|
main_loop = nullptr;
|
||||||
|
|||||||
@@ -137,8 +137,10 @@ public:
|
|||||||
|
|
||||||
virtual String get_system_ca_certificates() override;
|
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_and_gl(const String &p_display_driver) const override;
|
||||||
virtual bool _test_create_rendering_device(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();
|
||||||
~OS_LinuxBSD();
|
~OS_LinuxBSD();
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ def get_flags():
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
"arch": arch,
|
"arch": arch,
|
||||||
"supported": ["d3d12", "mono", "xaudio2"],
|
"supported": ["d3d12", "dcomp", "mono", "xaudio2"],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -281,6 +281,7 @@ void OS_Windows::initialize() {
|
|||||||
QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second);
|
QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second);
|
||||||
QueryPerformanceCounter((LARGE_INTEGER *)&ticks_start);
|
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
|
// 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)
|
// long as the windows scheduler resolution (~16-30ms) even for calls like Sleep(1)
|
||||||
TIMECAPS time_caps;
|
TIMECAPS time_caps;
|
||||||
@@ -292,6 +293,9 @@ void OS_Windows::initialize() {
|
|||||||
delay_resolution = 1000;
|
delay_resolution = 1000;
|
||||||
timeBeginPeriod(1);
|
timeBeginPeriod(1);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
delay_resolution = 1000;
|
||||||
|
#endif
|
||||||
|
|
||||||
process_map = memnew((HashMap<ProcessID, ProcessInfo>));
|
process_map = memnew((HashMap<ProcessID, ProcessInfo>));
|
||||||
|
|
||||||
@@ -374,7 +378,9 @@ void OS_Windows::finalize_core() {
|
|||||||
|
|
||||||
FileAccessWindows::finalize();
|
FileAccessWindows::finalize();
|
||||||
|
|
||||||
|
#if WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP
|
||||||
timeEndPeriod(1);
|
timeEndPeriod(1);
|
||||||
|
#endif
|
||||||
|
|
||||||
memdelete(process_map);
|
memdelete(process_map);
|
||||||
NetSocketWinSock::cleanup();
|
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 {
|
bool OS_Windows::_test_create_rendering_device(const String &p_display_driver) const {
|
||||||
// Tests Rendering Device creation.
|
// 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));
|
UnregisterClassW(L"Engine probe window", GetModuleHandle(nullptr));
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
|
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
|
||||||
hInstance = _hInstance;
|
hInstance = _hInstance;
|
||||||
|
|||||||
@@ -257,8 +257,10 @@ public:
|
|||||||
|
|
||||||
void set_main_window(HWND p_main_window) { main_window = p_main_window; }
|
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_and_gl(const String &p_display_driver) const override;
|
||||||
virtual bool _test_create_rendering_device(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; }
|
HINSTANCE get_hinstance() { return hInstance; }
|
||||||
OS_Windows(HINSTANCE _hInstance);
|
OS_Windows(HINSTANCE _hInstance);
|
||||||
|
|||||||
Reference in New Issue
Block a user