aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2020-06-24 16:34:53 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2020-06-29 10:17:25 +0200
commit9c39dd56283c74d28254c0b01f2edddb66919c08 (patch)
tree6427f5e5abe4747b4ab7f164d8a182a5ef634c38 /src
parenta2c0fc9e87d84aee77b45705a092f86e4cd96ad8 (diff)
Make it possible to specify an adapter or physical device only
As required by OpenXR. While we are at it, make the API a bit more type safe. Change-Id: I3c6152feeb71359056830ab02d35f8cb258722c0 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickgraphicsdevice.cpp100
-rw-r--r--src/quick/items/qquickgraphicsdevice.h26
-rw-r--r--src/quick/items/qquickgraphicsdevice_p.h15
-rw-r--r--src/quick/scenegraph/qsgrhisupport.cpp18
4 files changed, 122 insertions, 37 deletions
diff --git a/src/quick/items/qquickgraphicsdevice.cpp b/src/quick/items/qquickgraphicsdevice.cpp
index c60931c036..186df37579 100644
--- a/src/quick/items/qquickgraphicsdevice.cpp
+++ b/src/quick/items/qquickgraphicsdevice.cpp
@@ -106,10 +106,11 @@ bool QQuickGraphicsDevice::isNull() const
}
/*!
- \return a new QQuickGraphicsDevice referencing an existing QOpenGLContext.
+ \return a new QQuickGraphicsDevice referencing an existing OpenGL \a context.
This factory function is suitable for OpenGL.
*/
+#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC)
QQuickGraphicsDevice QQuickGraphicsDevice::fromOpenGLContext(QOpenGLContext *context)
{
QQuickGraphicsDevice dev;
@@ -118,25 +119,43 @@ QQuickGraphicsDevice QQuickGraphicsDevice::fromOpenGLContext(QOpenGLContext *con
d->u.context = context;
return dev;
}
+#endif
/*!
- \return a new QQuickGraphicsDevice referencing a native device and context
- object.
+ \return a new QQuickGraphicsDevice describing a DXGI adapter and D3D feature level.
- This factory function is suitable for:
-
- \list
+ This factory function is suitable for Direct3D 11, particularly in
+ combination with OpenXR. \a adapterLuidLow and \a adapterLuidHigh together
+ specify a LUID, while a featureLevel specifies a \c{D3D_FEATURE_LEVEL_}
+ value. \a featureLevel can be set to 0 if it is not intended to be
+ specified, in which case the scene graph's defaults will be used.
+ */
+#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
+QQuickGraphicsDevice QQuickGraphicsDevice::fromAdapter(quint32 adapterLuidLow,
+ qint32 adapterLuidHigh,
+ int featureLevel)
+{
+ QQuickGraphicsDevice dev;
+ QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
+ d->type = QQuickGraphicsDevicePrivate::Type::Adapter;
+ d->u.adapter = { adapterLuidLow, adapterLuidHigh, featureLevel };
+ return dev;
+}
+#endif
- \li Direct3D11 - \a device is expected to be a \c{ID3D11Device*}, \a
- context is expected to be a \c{ID3D11DeviceContext*}.
+/*!
+ \return a new QQuickGraphicsDevice referencing a native device and context
+ object.
- \endlist
+ This factory function is suitable for Direct3D 11. \a device is expected to
+ be a \c{ID3D11Device*}, \a context is expected to be a
+ \c{ID3D11DeviceContext*}.
\note the resulting QQuickGraphicsDevice does not own any native resources,
it merely contains references. It is the caller's responsibility to ensure
that the native resource exists as long as necessary.
-
*/
+#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndContext(void *device, void *context)
{
QQuickGraphicsDevice dev;
@@ -145,61 +164,76 @@ QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndContext(void *device, vo
d->u.deviceAndContext = { device, context };
return dev;
}
+#endif
/*!
- \return a new QQuickGraphicsDevice referencing a native device and command
- queue object.
-
- This factory function is suitable for:
+ \return a new QQuickGraphicsDevice referencing an existing \a device and
+ \a commandQueue object.
- \list
-
- \li Metal - \a device is expected to be a \c{MTLDevice*}, \a cmdQueue is
- expected to be a \c{MTLCommandQueue*}.
-
- \endlist
+ This factory function is suitable for Metal.
\note the resulting QQuickGraphicsDevice does not own any native resources,
it merely contains references. It is the caller's responsibility to ensure
that the native resource exists as long as necessary.
*/
-QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndCommandQueue(void *device, void *cmdQueue)
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC)
+QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceAndCommandQueue(MTLDevice *device,
+ MTLCommandQueue *commandQueue)
{
QQuickGraphicsDevice dev;
QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
d->type = QQuickGraphicsDevicePrivate::Type::DeviceAndCommandQueue;
- d->u.deviceAndCommandQueue = { device, cmdQueue };
+ d->u.deviceAndCommandQueue = { device, commandQueue };
return dev;
}
+#endif
/*!
- \return a new QQuickGraphicsDevice referencing a native device and related
- objects.
+ \return a new QQuickGraphicsDevice referencing an existing \a physicalDevice.
- This factory function is suitable for:
+ This factory function is suitable for Vulkan, particularly in combination
+ with OpenXR.
- \list
+ \note the resulting QQuickGraphicsDevice does not own any native resources,
+ it merely contains references. It is the caller's responsibility to ensure
+ that the native resource exists as long as necessary.
+ */
+#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
+QQuickGraphicsDevice QQuickGraphicsDevice::fromPhysicalDevice(VkPhysicalDevice physicalDevice)
+{
+ QQuickGraphicsDevice dev;
+ QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
+ d->type = QQuickGraphicsDevicePrivate::Type::PhysicalDevice;
+ d->u.physicalDevice = { physicalDevice };
+ return dev;
+}
+#endif
- \li Vulkan - \a physicalDevice is expected to be \c VkPhysicalDevice, \a
- device is expected to be a \a VkDevice, while \a queueFamilyIndex is the
- index of the graphics queue family on the device.
+/*!
+ \return a new QQuickGraphicsDevice referencing an existing \a device object.
- \endlist
+ This factory function is suitable for Vulkan. \a physicalDevice, \a device
+ and \a queueFamilyIndex must always be provided. \a queueIndex is optional
+ since the default value of 0 is often suitable.
\note the resulting QQuickGraphicsDevice does not own any native resources,
it merely contains references. It is the caller's responsibility to ensure
that the native resource exists as long as necessary.
-
*/
-QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceObjects(void *physicalDevice, void *device, int queueFamilyIndex)
+#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
+QQuickGraphicsDevice QQuickGraphicsDevice::fromDeviceObjects(VkPhysicalDevice physicalDevice,
+ VkDevice device,
+ int queueFamilyIndex,
+ int queueIndex)
{
QQuickGraphicsDevice dev;
QQuickGraphicsDevicePrivate *d = QQuickGraphicsDevicePrivate::get(&dev);
d->type = QQuickGraphicsDevicePrivate::Type::DeviceObjects;
- d->u.deviceObjects = { physicalDevice, device, queueFamilyIndex };
+ d->u.deviceObjects = { physicalDevice, device, queueFamilyIndex, queueIndex };
return dev;
}
+#endif
QQuickGraphicsDevicePrivate::QQuickGraphicsDevicePrivate()
: ref(1)
diff --git a/src/quick/items/qquickgraphicsdevice.h b/src/quick/items/qquickgraphicsdevice.h
index 811d510a5f..d6874cc24d 100644
--- a/src/quick/items/qquickgraphicsdevice.h
+++ b/src/quick/items/qquickgraphicsdevice.h
@@ -42,6 +42,15 @@
#include <QtQuick/qtquickglobal.h>
+#if QT_CONFIG(vulkan)
+#include <QtGui/QVulkanInstance>
+#endif
+
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS)
+Q_FORWARD_DECLARE_OBJC_CLASS(MTLDevice);
+Q_FORWARD_DECLARE_OBJC_CLASS(MTLCommandQueue);
+#endif
+
QT_BEGIN_NAMESPACE
class QQuickGraphicsDevicePrivate;
@@ -57,10 +66,23 @@ public:
bool isNull() const;
+#if QT_CONFIG(opengl) || defined(Q_CLANG_QDOC)
static QQuickGraphicsDevice fromOpenGLContext(QOpenGLContext *context);
+#endif
+
+#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
+ static QQuickGraphicsDevice fromAdapter(quint32 adapterLuidLow, qint32 adapterLuidHigh, int featureLevel = 0);
static QQuickGraphicsDevice fromDeviceAndContext(void *device, void *context);
- static QQuickGraphicsDevice fromDeviceAndCommandQueue(void *device, void *cmdQueue);
- static QQuickGraphicsDevice fromDeviceObjects(void *physicalDevice, void *device, int queueFamilyIndex);
+#endif
+
+#if defined(Q_OS_MACOS) || defined(Q_OS_IOS) || defined(Q_CLANG_QDOC)
+ static QQuickGraphicsDevice fromDeviceAndCommandQueue(MTLDevice *device, MTLCommandQueue *commandQueue);
+#endif
+
+#if QT_CONFIG(vulkan) || defined(Q_CLANG_QDOC)
+ static QQuickGraphicsDevice fromPhysicalDevice(VkPhysicalDevice physicalDevice);
+ static QQuickGraphicsDevice fromDeviceObjects(VkPhysicalDevice physicalDevice, VkDevice device, int queueFamilyIndex, int queueIndex = 0);
+#endif
private:
void detach();
diff --git a/src/quick/items/qquickgraphicsdevice_p.h b/src/quick/items/qquickgraphicsdevice_p.h
index 0a206725a6..e4be39b3e5 100644
--- a/src/quick/items/qquickgraphicsdevice_p.h
+++ b/src/quick/items/qquickgraphicsdevice_p.h
@@ -68,14 +68,22 @@ public:
enum class Type {
Null,
OpenGLContext,
+ Adapter,
DeviceAndContext,
DeviceAndCommandQueue,
+ PhysicalDevice,
DeviceObjects
};
QAtomicInt ref;
Type type = Type::Null;
+ struct Adapter {
+ quint32 luidLow;
+ qint32 luidHigh;
+ int featureLevel;
+ };
+
struct DeviceAndContext {
void *device;
void *context;
@@ -86,16 +94,23 @@ public:
void *cmdQueue;
};
+ struct PhysicalDevice {
+ void *physicalDevice;
+ };
+
struct DeviceObjects {
void *physicalDevice;
void *device;
int queueFamilyIndex;
+ int queueIndex;
};
union {
QOpenGLContext *context;
+ Adapter adapter;
DeviceAndContext deviceAndContext;
DeviceAndCommandQueue deviceAndCommandQueue;
+ PhysicalDevice physicalDevice;
DeviceObjects deviceObjects;
} u;
};
diff --git a/src/quick/scenegraph/qsgrhisupport.cpp b/src/quick/scenegraph/qsgrhisupport.cpp
index e8edbeac57..891beb0d90 100644
--- a/src/quick/scenegraph/qsgrhisupport.cpp
+++ b/src/quick/scenegraph/qsgrhisupport.cpp
@@ -605,9 +605,15 @@ QRhi *QSGRhiSupport::createRhi(QQuickWindow *window, QOffscreenSurface *offscree
importDev.physDev = reinterpret_cast<VkPhysicalDevice>(customDevD->u.deviceObjects.physicalDevice);
importDev.dev = reinterpret_cast<VkDevice>(customDevD->u.deviceObjects.device);
importDev.gfxQueueFamilyIdx = customDevD->u.deviceObjects.queueFamilyIndex;
+ importDev.gfxQueueIdx = customDevD->u.deviceObjects.queueIndex;
qCDebug(QSG_LOG_INFO, "Using existing native Vulkan physical device %p device %p graphics queue family index %d",
importDev.physDev, importDev.dev, importDev.gfxQueueFamilyIdx);
rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
+ } else if (customDevD->type == QQuickGraphicsDevicePrivate::Type::PhysicalDevice) {
+ QRhiVulkanNativeHandles importDev;
+ importDev.physDev = reinterpret_cast<VkPhysicalDevice>(customDevD->u.physicalDevice.physicalDevice);
+ qCDebug(QSG_LOG_INFO, "Using existing native Vulkan physical device %p", importDev.physDev);
+ rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
} else {
rhi = QRhi::create(backend, &rhiParams, flags);
}
@@ -628,6 +634,14 @@ QRhi *QSGRhiSupport::createRhi(QQuickWindow *window, QOffscreenSurface *offscree
qCDebug(QSG_LOG_INFO, "Using existing native D3D11 device %p and context %p",
importDev.dev, importDev.context);
rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
+ } else if (customDevD->type == QQuickGraphicsDevicePrivate::Type::Adapter) {
+ QRhiD3D11NativeHandles importDev;
+ importDev.adapterLuidLow = customDevD->u.adapter.luidLow;
+ importDev.adapterLuidHigh = customDevD->u.adapter.luidHigh;
+ importDev.featureLevel = customDevD->u.adapter.featureLevel;
+ qCDebug(QSG_LOG_INFO, "Using D3D11 adapter LUID %u, %d and feature level %d",
+ importDev.adapterLuidLow, importDev.adapterLuidHigh, importDev.featureLevel);
+ rhi = QRhi::create(backend, &rhiParams, flags, &importDev);
} else {
rhi = QRhi::create(backend, &rhiParams, flags);
}
@@ -638,8 +652,8 @@ QRhi *QSGRhiSupport::createRhi(QQuickWindow *window, QOffscreenSurface *offscree
QRhiMetalInitParams rhiParams;
if (customDevD->type == QQuickGraphicsDevicePrivate::Type::DeviceAndCommandQueue) {
QRhiMetalNativeHandles importDev;
- importDev.dev = customDevD->u.deviceAndCommandQueue.device;
- importDev.cmdQueue = customDevD->u.deviceAndCommandQueue.cmdQueue;
+ importDev.dev = (MTLDevice *) customDevD->u.deviceAndCommandQueue.device;
+ importDev.cmdQueue = (MTLCommandQueue *) customDevD->u.deviceAndCommandQueue.cmdQueue;
qCDebug(QSG_LOG_INFO, "Using existing native Metal device %p and command queue %p",
importDev.dev, importDev.cmdQueue);
rhi = QRhi::create(backend, &rhiParams, flags, &importDev);