1// Copyright (C) 2020 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquickgraphicsdevice_p.h"
5
6QT_BEGIN_NAMESPACE
7
8/*!
9 \class QQuickGraphicsDevice
10 \since 6.0
11 \inmodule QtQuick
12
13 \brief The QQuickGraphicsDevice class provides an opaque container for
14 native graphics objects representing graphics devices or contexts.
15
16 \sa QQuickWindow::setGraphicsDevice(), QQuickRenderTarget
17*/
18
19/*!
20 Constructs a default QQuickGraphicsDevice that does not reference any native
21 objects.
22 */
23QQuickGraphicsDevice::QQuickGraphicsDevice()
24 : d(new QQuickGraphicsDevicePrivate)
25{
26}
27
28/*!
29 \internal
30 */
31void QQuickGraphicsDevice::detach()
32{
33 qAtomicDetach(d);
34}
35
36/*!
37 \internal
38 */
39QQuickGraphicsDevice::QQuickGraphicsDevice(const QQuickGraphicsDevice &other)
40 : d(other.d)
41{
42 d->ref.ref();
43}
44
45/*!
46 \internal
47 */
48QQuickGraphicsDevice &QQuickGraphicsDevice::operator=(const QQuickGraphicsDevice &other)
49{
50 qAtomicAssign(d, x: other.d);
51 return *this;
52}
53
54/*!
55 Destructor.
56 */
57QQuickGraphicsDevice::~QQuickGraphicsDevice()
58{
59 if (!d->ref.deref())
60 delete d;
61}
62
63/*!
64 \return true if this is a default constructed graphics device that
65 does not reference any native objects.
66 */
67bool QQuickGraphicsDevice::isNull() const
68{
69 return d->type == QQuickGraphicsDevicePrivate::Type::Null;
70}
71
72/*!
73 \return a new QQuickGraphicsDevice referencing an existing OpenGL \a context.
74
75 This factory function is suitable for OpenGL.
76
77 \note It is up the caller to ensure that \a context is going to be
78 compatible and usable with the QQuickWindow. Platform-specific mismatches in
79 the associated QSurfaceFormat, or threading issues due to attempting to use
80 \a context on multiple threads are up to the caller to avoid.
81 */
82#if QT_CONFIG(opengl) || defined(Q_QDOC)
83QQuickGraphicsDevice QQuickGraphicsDevice::fromOpenGLContext(QOpenGLContext *context)
84{
85 QQuickGraphicsDevice dev;
86 QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(p: &dev);
87 d->type = QQuickGraphicsDevicePrivate::Type::OpenGLContext;
88 d->u.context = context;
89 return dev;
90}
91#endif
92
93/*!
94 \return a new QQuickGraphicsDevice describing a DXGI adapter and D3D feature level.
95
96 This factory function is suitable for Direct3D 11 and 12, particularly in
97 combination with OpenXR. \a adapterLuidLow and \a adapterLuidHigh together
98 specify a LUID, while a featureLevel specifies a \c{D3D_FEATURE_LEVEL_}
99 value. \a featureLevel can be set to 0 if it is not intended to be
100 specified, in which case the scene graph's defaults will be used.
101
102 \note With Direct 3D 12 \a featureLevel specifies the \c minimum feature
103 level passed on to D3D12CreateDevice().
104 */
105#if defined(Q_OS_WIN) || defined(Q_QDOC)
106QQuickGraphicsDevice QQuickGraphicsDevice::fromAdapter(quint32 adapterLuidLow,
107 qint32 adapterLuidHigh,
108 int featureLevel)
109{
110 QQuickGraphicsDevice dev;
111 QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
112 d->type = QQuickGraphicsDevicePrivate::Type::Adapter;
113 d->u.adapter = { adapterLuidLow, adapterLuidHigh, featureLevel };
114 return dev;
115}
116#endif
117
118/*!
119 \return a new QQuickGraphicsDevice referencing a native device and context
120 object.
121
122 This factory function is suitable for Direct3D 11. \a device is expected to
123 be a \c{ID3D11Device*}, \a context is expected to be a
124 \c{ID3D11DeviceContext*}.
125
126 It also supports Direct 3D 12, if that is the 3D API used at run time. With
127 D3D12 \a context is unused and can be set to null. \a device is expected to
128 be a \c{ID3D12Device*}.
129
130 \note the resulting QQuickGraphicsDevice does not own any native resources,
131 it merely contains references. It is the caller's responsibility to ensure
132 that the native resource exists as long as necessary.
133 */
134#if defined(Q_OS_WIN) || defined(Q_QDOC)
135QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndContext(void *device, void *context)
136{
137 QQuickGraphicsDevice dev;
138 QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
139 d->type = QQuickGraphicsDevicePrivate::Type::DeviceAndContext;
140 d->u.deviceAndContext = { device, context };
141 return dev;
142}
143#endif
144
145/*!
146 \return a new QQuickGraphicsDevice referencing an existing \a device and
147 \a commandQueue object.
148
149 This factory function is suitable for Metal.
150
151 \note the resulting QQuickGraphicsDevice does not own any native resources,
152 it merely contains references. It is the caller's responsibility to ensure
153 that the native resource exists as long as necessary.
154
155 */
156#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_QDOC)
157QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndCommandQueue(MTLDevice *device,
158 MTLCommandQueue *commandQueue)
159{
160 QQuickGraphicsDevice dev;
161 QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
162 d->type = QQuickGraphicsDevicePrivate::Type::DeviceAndCommandQueue;
163 d->u.deviceAndCommandQueue = { device, commandQueue };
164 return dev;
165}
166#endif
167
168/*!
169 \return a new QQuickGraphicsDevice referencing an existing \a physicalDevice.
170
171 This factory function is suitable for Vulkan, particularly in combination
172 with OpenXR.
173
174 \note the resulting QQuickGraphicsDevice does not own any native resources,
175 it merely contains references. It is the caller's responsibility to ensure
176 that the native resource exists as long as necessary.
177 */
178#if QT_CONFIG(vulkan) || defined(Q_QDOC)
179QQuickGraphicsDevice QQuickGraphicsDevice::fromPhysicalDevice(VkPhysicalDevice physicalDevice)
180{
181 QQuickGraphicsDevice dev;
182 QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(p: &dev);
183 d->type = QQuickGraphicsDevicePrivate::Type::PhysicalDevice;
184 d->u.physicalDevice = { .physicalDevice: physicalDevice };
185 return dev;
186}
187#endif
188
189/*!
190 \return a new QQuickGraphicsDevice referencing an existing \a device object.
191
192 This factory function is suitable for Vulkan. \a physicalDevice, \a device
193 and \a queueFamilyIndex must always be provided. \a queueIndex is optional
194 since the default value of 0 is often suitable.
195
196 \note the resulting QQuickGraphicsDevice does not own any native resources,
197 it merely contains references. It is the caller's responsibility to ensure
198 that the native resource exists as long as necessary.
199 */
200#if QT_CONFIG(vulkan) || defined(Q_QDOC)
201QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceObjects(VkPhysicalDevice physicalDevice,
202 VkDevice device,
203 int queueFamilyIndex,
204 int queueIndex)
205{
206 QQuickGraphicsDevice dev;
207 QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(p: &dev);
208 d->type = QQuickGraphicsDevicePrivate::Type::DeviceObjects;
209 d->u.deviceObjects = { .physicalDevice: physicalDevice, .device: device, .queueFamilyIndex: queueFamilyIndex, .queueIndex: queueIndex };
210 return dev;
211}
212#endif
213
214/*!
215 \return a new QQuickGraphicsDevice referencing an existing \a rhi object.
216
217 \note Similarly to fromOpenGLContext(), the caller must be careful to only
218 share a QRhi (and so the underlying graphics context or device) between
219 QQuickWindows that are known to be compatible, not breaking the underlying
220 graphics API's rules when it comes to threading, pixel formats, etc.
221
222 \since 6.6
223*/
224QQuickGraphicsDevice QQuickGraphicsDevice::fromRhi(QRhi *rhi)
225{
226 QQuickGraphicsDevice dev;
227 QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(p: &dev);
228 d->type = QQuickGraphicsDevicePrivate::Type::Rhi;
229 d->u.rhi = rhi;
230 return dev;
231}
232
233QQuickGraphicsDevicePrivate::QQuickGraphicsDevicePrivate()
234 : ref(1)
235{
236}
237
238QQuickGraphicsDevicePrivate::QQuickGraphicsDevicePrivate(const QQuickGraphicsDevicePrivate *other)
239 : ref(1),
240 type(other->type),
241 u(other->u)
242{
243}
244
245QT_END_NAMESPACE
246

source code of qtdeclarative/src/quick/items/qquickgraphicsdevice.cpp