/* * Copyright (c) 2026, the Ladybird developers. * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #ifdef USE_DIRECTX # include # include # include // NOTE: Not using the newer winrt that supersedes wrl as that uses exceptions for error handling. # include namespace Gfx { using namespace Microsoft::WRL; struct Direct3DContext::Impl { Impl(ComPtr adapter, ComPtr device, ComPtr queue) : adapter(move(adapter)) , device(move(device)) , queue(move(queue)) { } ComPtr adapter; ComPtr device; ComPtr queue; }; Direct3DContext::Direct3DContext(NonnullOwnPtr impl) : m_impl(move(impl)) { } Direct3DContext::~Direct3DContext() = default; IDXGIAdapter1* Direct3DContext::adapter() const { return m_impl->adapter.Get(); } ID3D12Device* Direct3DContext::device() const { return m_impl->device.Get(); } ID3D12CommandQueue* Direct3DContext::queue() const { return m_impl->queue.Get(); } static ErrorOr> get_hardware_adapter(IDXGIFactory4& factory) { for (UINT adapter_index = 0;; ++adapter_index) { ComPtr adapter; auto hr = factory.EnumAdapters1(adapter_index, &adapter); if (hr == DXGI_ERROR_NOT_FOUND) break; if (FAILED(hr)) return Error::from_windows_error(hr); if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), nullptr))) return move(adapter); } return Error::from_string_literal("No Direct3D 12 adapter found"); } ErrorOr> create_direct3d_context() { ComPtr factory; auto hr = CreateDXGIFactory1(IID_PPV_ARGS(&factory)); if (FAILED(hr)) return Error::from_windows_error(hr); auto adapter = TRY(get_hardware_adapter(*factory.Get())); ComPtr device; hr = D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device)); if (FAILED(hr)) return Error::from_windows_error(hr); D3D12_COMMAND_QUEUE_DESC queue_description {}; queue_description.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; queue_description.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; ComPtr queue; hr = device->CreateCommandQueue(&queue_description, IID_PPV_ARGS(&queue)); if (FAILED(hr)) return Error::from_windows_error(hr); return adopt_ref(*new Direct3DContext(make(move(adapter), move(device), move(queue)))); } } #endif