Direct3D 12: Let platforms report support for direct composition

This commit is contained in:
Pedro J. Estébanez
2025-05-14 17:30:28 +02:00
parent 428a762e98
commit 7759296594
5 changed files with 28 additions and 1 deletions

View File

@ -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"]

View File

@ -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");

View File

@ -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;

View File

@ -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);

View File

@ -241,7 +241,7 @@ def get_flags():
return { return {
"arch": arch, "arch": arch,
"supported": ["d3d12", "mono", "xaudio2"], "supported": ["d3d12", "dcomp", "mono", "xaudio2"],
} }