Skip to content

Commit 127738c

Browse files
committed
Merge pull request #99387 from 0x0ACB/direct_composition
Use direct composition for d3d12 backend
2 parents 0045b1a + a8cd0e9 commit 127738c

5 files changed

+67
-8
lines changed

drivers/d3d12/rendering_context_driver_d3d12.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ RenderingContextDriverD3D12::~RenderingContextDriverD3D12() {
9696
if (lib_dxgi) {
9797
FreeLibrary(lib_dxgi);
9898
}
99+
if (lib_dcomp) {
100+
FreeLibrary(lib_dcomp);
101+
}
99102
}
100103

101104
Error RenderingContextDriverD3D12::_init_device_factory() {
@@ -108,6 +111,9 @@ Error RenderingContextDriverD3D12::_init_device_factory() {
108111
lib_dxgi = LoadLibraryW(L"DXGI.dll");
109112
ERR_FAIL_NULL_V(lib_dxgi, ERR_CANT_CREATE);
110113

114+
lib_dcomp = LoadLibraryW(L"Dcomp.dll");
115+
ERR_FAIL_NULL_V(lib_dcomp, ERR_CANT_CREATE);
116+
111117
// Note: symbol is not available in MinGW import library.
112118
PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetInterface");
113119
if (!d3d_D3D12GetInterface) {

drivers/d3d12/rendering_context_driver_d3d12.h

+18
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@
5959
#undef AS
6060
#endif
6161

62+
#if (WINVER < _WIN32_WINNT_WIN8) && defined(_MSC_VER)
63+
#pragma push_macro("NTDDI_VERSION")
64+
#pragma push_macro("WINVER")
65+
#undef NTDDI_VERSION
66+
#undef WINVER
67+
#define NTDDI_VERSION NTDDI_WIN8
68+
#define WINVER _WIN32_WINNT_WIN8
69+
#include <dcomp.h>
70+
#pragma pop_macro("WINVER")
71+
#pragma pop_macro("NTDDI_VERSION")
72+
#else
73+
#include <dcomp.h>
74+
#endif
75+
6276
#include "d3dx12.h"
6377
#include <dxgi1_6.h>
6478

@@ -114,10 +128,14 @@ class RenderingContextDriverD3D12 : public RenderingContextDriver {
114128
uint32_t height = 0;
115129
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
116130
bool needs_resize = false;
131+
ComPtr<IDCompositionDevice> composition_device;
132+
ComPtr<IDCompositionTarget> composition_target;
133+
ComPtr<IDCompositionVisual> composition_visual;
117134
};
118135

119136
HMODULE lib_d3d12 = nullptr;
120137
HMODULE lib_dxgi = nullptr;
138+
HMODULE lib_dcomp = nullptr;
121139

122140
IDXGIAdapter1 *create_adapter(uint32_t p_adapter_index) const;
123141
ID3D12DeviceFactory *device_factory_get() const;

drivers/d3d12/rendering_device_driver_d3d12.cpp

+35-8
Original file line numberDiff line numberDiff line change
@@ -2469,7 +2469,7 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
24692469
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
24702470
if (swap_chain->d3d_swap_chain != nullptr) {
24712471
_swap_chain_release_buffers(swap_chain);
2472-
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, 0, 0, DXGI_FORMAT_UNKNOWN, creation_flags);
2472+
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, surface->width, surface->height, DXGI_FORMAT_UNKNOWN, creation_flags);
24732473
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_UNAVAILABLE);
24742474
} else {
24752475
swap_chain_desc.BufferCount = p_desired_framebuffer_count;
@@ -2478,22 +2478,19 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
24782478
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
24792479
swap_chain_desc.SampleDesc.Count = 1;
24802480
swap_chain_desc.Flags = creation_flags;
2481-
swap_chain_desc.Scaling = DXGI_SCALING_NONE;
2481+
swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
24822482
if (OS::get_singleton()->is_layered_allowed()) {
24832483
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
24842484
has_comp_alpha[(uint64_t)p_cmd_queue.id] = true;
24852485
} else {
24862486
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
24872487
has_comp_alpha[(uint64_t)p_cmd_queue.id] = false;
24882488
}
2489+
swap_chain_desc.Width = surface->width;
2490+
swap_chain_desc.Height = surface->height;
24892491

24902492
ComPtr<IDXGISwapChain1> swap_chain_1;
2491-
res = context_driver->dxgi_factory_get()->CreateSwapChainForHwnd(command_queue->d3d_queue.Get(), surface->hwnd, &swap_chain_desc, nullptr, nullptr, swap_chain_1.GetAddressOf());
2492-
if (!SUCCEEDED(res) && swap_chain_desc.AlphaMode != DXGI_ALPHA_MODE_IGNORE) {
2493-
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
2494-
has_comp_alpha[(uint64_t)p_cmd_queue.id] = false;
2495-
res = context_driver->dxgi_factory_get()->CreateSwapChainForHwnd(command_queue->d3d_queue.Get(), surface->hwnd, &swap_chain_desc, nullptr, nullptr, swap_chain_1.GetAddressOf());
2496-
}
2493+
res = context_driver->dxgi_factory_get()->CreateSwapChainForComposition(command_queue->d3d_queue.Get(), &swap_chain_desc, nullptr, swap_chain_1.GetAddressOf());
24972494
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
24982495

24992496
swap_chain_1.As(&swap_chain->d3d_swap_chain);
@@ -2503,6 +2500,36 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
25032500
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
25042501
}
25052502

2503+
if (surface->composition_device.Get() == nullptr) {
2504+
using PFN_DCompositionCreateDevice = HRESULT(WINAPI *)(IDXGIDevice *, REFIID, void **);
2505+
PFN_DCompositionCreateDevice pfn_DCompositionCreateDevice = (PFN_DCompositionCreateDevice)(void *)GetProcAddress(context_driver->lib_dcomp, "DCompositionCreateDevice");
2506+
ERR_FAIL_NULL_V(pfn_DCompositionCreateDevice, ERR_CANT_CREATE);
2507+
2508+
res = pfn_DCompositionCreateDevice(nullptr, IID_PPV_ARGS(surface->composition_device.GetAddressOf()));
2509+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2510+
2511+
res = surface->composition_device->CreateTargetForHwnd(surface->hwnd, TRUE, surface->composition_target.GetAddressOf());
2512+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2513+
2514+
res = surface->composition_device->CreateVisual(surface->composition_visual.GetAddressOf());
2515+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2516+
2517+
res = surface->composition_visual->SetContent(swap_chain->d3d_swap_chain.Get());
2518+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2519+
2520+
res = surface->composition_target->SetRoot(surface->composition_visual.Get());
2521+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2522+
2523+
res = surface->composition_device->Commit();
2524+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2525+
} else {
2526+
res = surface->composition_visual->SetContent(swap_chain->d3d_swap_chain.Get());
2527+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2528+
2529+
res = surface->composition_device->Commit();
2530+
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
2531+
}
2532+
25062533
res = swap_chain->d3d_swap_chain->GetDesc1(&swap_chain_desc);
25072534
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
25082535
ERR_FAIL_COND_V(swap_chain_desc.BufferCount == 0, ERR_CANT_CREATE);

platform/windows/display_server_windows.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -2167,6 +2167,10 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_initiali
21672167

21682168
r_style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
21692169
r_style_ex |= WS_EX_ACCEPTFILES;
2170+
2171+
if (OS::get_singleton()->get_current_rendering_driver_name() == "d3d12") {
2172+
r_style_ex |= WS_EX_NOREDIRECTIONBITMAP;
2173+
}
21702174
}
21712175

21722176
void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repaint) {

platform/windows/display_server_windows.h

+4
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,10 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
356356
SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2,
357357
} SHC_PROCESS_DPI_AWARENESS;
358358

359+
#ifndef WS_EX_NOREDIRECTIONBITMAP
360+
#define WS_EX_NOREDIRECTIONBITMAP 0x00200000L
361+
#endif
362+
359363
class DropTargetWindows;
360364

361365
class DisplayServerWindows : public DisplayServer {

0 commit comments

Comments
 (0)