Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qopenxrgraphics_d3d12.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
3
5
7
8#include <QtQuick/QQuickWindow>
9#include <QtQuick/QQuickGraphicsDevice>
10
11#include <rhi/qrhi.h>
12
14
15QOpenXRGraphicsD3D12::QOpenXRGraphicsD3D12()
16{
17 m_graphicsBinding.type = XR_TYPE_GRAPHICS_BINDING_D3D12_KHR;
18 m_graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_D3D12_KHR;
19}
20
21bool QOpenXRGraphicsD3D12::initialize(const QVector<XrExtensionProperties> &extensions)
22{
23 return hasExtension(extensions, XR_KHR_D3D12_ENABLE_EXTENSION_NAME);
24}
25
26QVector<const char *> QOpenXRGraphicsD3D12::getRequiredExtensions() const
27{
28 return { XR_KHR_D3D12_ENABLE_EXTENSION_NAME };
29}
30
31
32const XrBaseInStructure *QOpenXRGraphicsD3D12::handle() const
33{
34 return reinterpret_cast<const XrBaseInStructure*>(&m_graphicsBinding);
35}
36
37
38bool QOpenXRGraphicsD3D12::setupGraphics(const XrInstance &instance, XrSystemId &systemId, const QQuickGraphicsConfiguration &)
39{
40 PFN_xrGetD3D12GraphicsRequirementsKHR pfnGetD3D12GraphicsRequirementsKHR = nullptr;
41 OpenXRHelpers::checkXrResult(xrGetInstanceProcAddr(instance, "xrGetD3D12GraphicsRequirementsKHR",
42 reinterpret_cast<PFN_xrVoidFunction*>(&pfnGetD3D12GraphicsRequirementsKHR)),
43 instance);
44
45 if (!pfnGetD3D12GraphicsRequirementsKHR) {
46 qWarning("Could not resolve xrGetD3D12GraphicsRequirementsKHR; perhaps the OpenXR implementation does not support D3D12?");
47 return false;
48 }
49
50 OpenXRHelpers::checkXrResult(pfnGetD3D12GraphicsRequirementsKHR(instance, systemId, &m_graphicsRequirements),
51 instance);
52 return true;
53}
54
55bool QOpenXRGraphicsD3D12::finializeGraphics(QRhi *rhi)
56{
57 const QRhiD3D12NativeHandles *d3d12Rhi = static_cast<const QRhiD3D12NativeHandles *>(rhi->nativeHandles());
58 m_graphicsBinding.device = reinterpret_cast<ID3D12Device*>(d3d12Rhi->dev);
59 m_graphicsBinding.queue = reinterpret_cast<ID3D12CommandQueue*>(d3d12Rhi->commandQueue);
60 m_rhi = rhi;
61
62 return true;
63}
64
65
66int64_t QOpenXRGraphicsD3D12::colorSwapchainFormat(const QVector<int64_t> &swapchainFormats) const
67{
68 // List of supported color swapchain formats.
69 constexpr DXGI_FORMAT supportedColorSwapchainFormats[] = {
70 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
71 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
72 DXGI_FORMAT_B8G8R8A8_UNORM,
73 DXGI_FORMAT_R8G8B8A8_UNORM
74 };
75
76 auto swapchainFormatIt = std::find_first_of(std::begin(supportedColorSwapchainFormats),
77 std::end(supportedColorSwapchainFormats),
78 swapchainFormats.begin(),
79 swapchainFormats.end());
80
81 return *swapchainFormatIt;
82}
83
84int64_t QOpenXRGraphicsD3D12::depthSwapchainFormat(const QVector<int64_t> &swapchainFormats) const
85{
86 // in order of preference
87 constexpr int64_t supportedDepthSwapchainFormats[] = {
88 DXGI_FORMAT_D32_FLOAT_S8X24_UINT,
89 DXGI_FORMAT_D32_FLOAT,
90 DXGI_FORMAT_D16_UNORM
91 };
92
93 return *std::find_first_of(std::begin(supportedDepthSwapchainFormats),
94 std::end(supportedDepthSwapchainFormats),
95 swapchainFormats.begin(),
96 swapchainFormats.end());
97}
98
99QVector<XrSwapchainImageBaseHeader*> QOpenXRGraphicsD3D12::allocateSwapchainImages(int count, XrSwapchain swapchain)
100{
101 QVector<XrSwapchainImageBaseHeader*> swapchainImages;
102 QVector<XrSwapchainImageD3D12KHR> swapchainImageBuffer(count);
103 for (XrSwapchainImageD3D12KHR& image : swapchainImageBuffer) {
104 image.type = XR_TYPE_SWAPCHAIN_IMAGE_D3D12_KHR;
105 swapchainImages.push_back(reinterpret_cast<XrSwapchainImageBaseHeader*>(&image));
106 }
107 m_swapchainImageBuffer.insert(swapchain, swapchainImageBuffer);
108 return swapchainImages;
109}
110
111
112QQuickRenderTarget QOpenXRGraphicsD3D12::renderTarget(const XrSwapchainSubImage &subImage,
113 const XrSwapchainImageBaseHeader *swapchainImage,
114 quint64 swapchainFormat,
115 int samples,
116 int arraySize,
117 const XrSwapchainImageBaseHeader *depthSwapchainImage,
118 quint64 depthSwapchainFormat) const
119{
120 ID3D12Resource* const colorTexture = reinterpret_cast<const XrSwapchainImageD3D12KHR*>(swapchainImage)->texture;
121
122 DXGI_FORMAT viewFormat = DXGI_FORMAT(swapchainFormat);
123 switch (swapchainFormat) {
124 case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
125 viewFormat = DXGI_FORMAT_R8G8B8A8_UNORM;
126 break;
127 case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
128 viewFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
129 break;
130 default:
131 break;
132 }
133
134 QQuickRenderTarget::Flags flags;
135 if (samples > 1)
136 flags |= QQuickRenderTarget::Flag::MultisampleResolve;
137
138 return QQuickRenderTarget::fromD3D12Texture(colorTexture,
139 0,
140 swapchainFormat,
141 viewFormat,
142 QSize(subImage.imageRect.extent.width, subImage.imageRect.extent.height),
143 samples,
144 arraySize,
145 flags);
146
147 // No depthSwapchainImage support because ResolveDepthStencil will be
148 // unsupported with D3D11/12 no matter what.
149 Q_UNUSED(depthSwapchainImage);
150 Q_UNUSED(depthSwapchainFormat);
151}
152
153
154void QOpenXRGraphicsD3D12::setupWindow(QQuickWindow *quickWindow)
155{
156 quickWindow->setGraphicsDevice(QQuickGraphicsDevice::fromAdapter(m_graphicsRequirements.adapterLuid.LowPart,
157 m_graphicsRequirements.adapterLuid.HighPart,
158 m_graphicsRequirements.minFeatureLevel));
159}
160
161QT_END_NAMESPACE
bool checkXrResult(XrResult result, XrInstance instance)
Combined button and popup list for selecting options.