Skip to content

Commit

Permalink
Use direct composition for d3d12 backend
Browse files Browse the repository at this point in the history
  • Loading branch information
0x0ACB committed Nov 18, 2024
1 parent 5efd124 commit ace4a14
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 8 deletions.
6 changes: 6 additions & 0 deletions drivers/d3d12/rendering_context_driver_d3d12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ RenderingContextDriverD3D12::~RenderingContextDriverD3D12() {
if (lib_dxgi) {
FreeLibrary(lib_dxgi);
}
if (lib_dcomp) {
FreeLibrary(lib_dcomp);
}
}

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

lib_dcomp = LoadLibraryW(L"Dcomp.dll");
ERR_FAIL_NULL_V(lib_dcomp, ERR_CANT_CREATE);

// Note: symbol is not available in MinGW import library.
PFN_D3D12_GET_INTERFACE d3d_D3D12GetInterface = (PFN_D3D12_GET_INTERFACE)(void *)GetProcAddress(lib_d3d12, "D3D12GetInterface");
if (!d3d_D3D12GetInterface) {
Expand Down
18 changes: 18 additions & 0 deletions drivers/d3d12/rendering_context_driver_d3d12.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@
#undef AS
#endif

#if WINVER < _WIN32_WINNT_WIN8
#pragma push_macro("NTDDI_VERSION")
#pragma push_macro("WINVER")
#undef NTDDI_VERSION
#undef WINVER
#define NTDDI_VERSION NTDDI_WIN8
#define WINVER _WIN32_WINNT_WIN8
#include <dcomp.h>
#pragma pop_macro("WINVER")
#pragma pop_macro("NTDDI_VERSION")
#else
#include <dcomp.h>
#endif

#include "d3dx12.h"
#include <dxgi1_6.h>

Expand Down Expand Up @@ -114,10 +128,14 @@ class RenderingContextDriverD3D12 : public RenderingContextDriver {
uint32_t height = 0;
DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED;
bool needs_resize = false;
ComPtr<IDCompositionDevice> composition_device;
ComPtr<IDCompositionTarget> composition_target;
ComPtr<IDCompositionVisual> composition_visual;
};

HMODULE lib_d3d12 = nullptr;
HMODULE lib_dxgi = nullptr;
HMODULE lib_dcomp = nullptr;

IDXGIAdapter1 *create_adapter(uint32_t p_adapter_index) const;
ID3D12DeviceFactory *device_factory_get() const;
Expand Down
43 changes: 35 additions & 8 deletions drivers/d3d12/rendering_device_driver_d3d12.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2469,7 +2469,7 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
if (swap_chain->d3d_swap_chain != nullptr) {
_swap_chain_release_buffers(swap_chain);
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, 0, 0, DXGI_FORMAT_UNKNOWN, creation_flags);
res = swap_chain->d3d_swap_chain->ResizeBuffers(p_desired_framebuffer_count, surface->width, surface->height, DXGI_FORMAT_UNKNOWN, creation_flags);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_UNAVAILABLE);
} else {
swap_chain_desc.BufferCount = p_desired_framebuffer_count;
Expand All @@ -2478,22 +2478,19 @@ Error RenderingDeviceDriverD3D12::swap_chain_resize(CommandQueueID p_cmd_queue,
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
swap_chain_desc.SampleDesc.Count = 1;
swap_chain_desc.Flags = creation_flags;
swap_chain_desc.Scaling = DXGI_SCALING_NONE;
swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
if (OS::get_singleton()->is_layered_allowed()) {
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
has_comp_alpha[(uint64_t)p_cmd_queue.id] = true;
} else {
swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
has_comp_alpha[(uint64_t)p_cmd_queue.id] = false;
}
swap_chain_desc.Width = surface->width;
swap_chain_desc.Height = surface->height;

ComPtr<IDXGISwapChain1> swap_chain_1;
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());
}
res = context_driver->dxgi_factory_get()->CreateSwapChainForComposition(command_queue->d3d_queue.Get(), &swap_chain_desc, nullptr, swap_chain_1.GetAddressOf());
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);

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

if (surface->composition_device.Get() == nullptr) {
using PFN_DCompositionCreateDevice = HRESULT(WINAPI *)(IDXGIDevice *, REFIID, void **);
PFN_DCompositionCreateDevice pfn_DCompositionCreateDevice = (PFN_DCompositionCreateDevice)GetProcAddress(context_driver->lib_dcomp, "DCompositionCreateDevice");

Check failure on line 2505 in drivers/d3d12/rendering_device_driver_d3d12.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Template w/ GCC (target=template_release, tests=yes, use_mingw=yes)

cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'PFN_DCompositionCreateDevice' {aka 'long int (*)(IDXGIDevice*, const GUID&, void**)'} [-Werror=cast-function-type]
ERR_FAIL_COND_V(!pfn_DCompositionCreateDevice, ERR_CANT_CREATE);

res = pfn_DCompositionCreateDevice(nullptr, IID_PPV_ARGS(surface->composition_device.GetAddressOf()));
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);

res = surface->composition_device->CreateTargetForHwnd(surface->hwnd, TRUE, surface->composition_target.GetAddressOf());
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);

res = surface->composition_device->CreateVisual(surface->composition_visual.GetAddressOf());
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);

res = surface->composition_visual->SetContent(swap_chain->d3d_swap_chain.Get());
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);

res = surface->composition_target->SetRoot(surface->composition_visual.Get());
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);

res = surface->composition_device->Commit();
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
} else {
res = surface->composition_visual->SetContent(swap_chain->d3d_swap_chain.Get());
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);

res = surface->composition_device->Commit();
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
}

res = swap_chain->d3d_swap_chain->GetDesc1(&swap_chain_desc);
ERR_FAIL_COND_V(!SUCCEEDED(res), ERR_CANT_CREATE);
ERR_FAIL_COND_V(swap_chain_desc.BufferCount == 0, ERR_CANT_CREATE);
Expand Down
4 changes: 4 additions & 0 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2167,6 +2167,10 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_initiali

r_style |= WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
r_style_ex |= WS_EX_ACCEPTFILES;

if (OS::get_singleton()->get_current_rendering_driver_name() == "d3d12") {
r_style_ex |= WS_EX_NOREDIRECTIONBITMAP;
}
}

void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repaint) {
Expand Down
4 changes: 4 additions & 0 deletions platform/windows/display_server_windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,10 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2,
} SHC_PROCESS_DPI_AWARENESS;

#ifndef WS_EX_NOREDIRECTIONBITMAP
#define WS_EX_NOREDIRECTIONBITMAP 0x00200000L
#endif

class DropTargetWindows;

class DisplayServerWindows : public DisplayServer {
Expand Down

0 comments on commit ace4a14

Please sign in to comment.