summaryrefslogtreecommitdiffstats
path: root/src/gui/rhi
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2021-01-12 13:02:13 +0100
committerLaszlo Agocs <laszlo.agocs@qt.io>2021-01-13 10:08:23 +0100
commit042cd97884bb86dfd0bedaa63480d99846ab06bb (patch)
tree14095c34b735179ad60135b1a53c6fb77a6d189e /src/gui/rhi
parent04f11f9935453a3db6bc5e5064a187fa25e85d90 (diff)
rhi: Expose device name, type, and IDs
...to the extent it is sensible. We have to make compromises still, meaning some fields will only be applicable with certain APIs. Most of this is already shown upon QRhi::create() as info debug prints, when enabled. Now expose it all through the QRhi API as well. This is useful for printing in qtdiag, and, while it should be avoided as much as possible, to make decisions about disabling 3D rendering features depending on the driver and GPU in use. Change-Id: Iebe1e192965c928b82a094d1c7c50ddf4b38b9a2 Reviewed-by: Andy Nichols <andy.nichols@qt.io>
Diffstat (limited to 'src/gui/rhi')
-rw-r--r--src/gui/rhi/qrhi.cpp94
-rw-r--r--src/gui/rhi/qrhi_p.h25
-rw-r--r--src/gui/rhi/qrhi_p_p.h1
-rw-r--r--src/gui/rhi/qrhid3d11.cpp13
-rw-r--r--src/gui/rhi/qrhid3d11_p_p.h2
-rw-r--r--src/gui/rhi/qrhigles2.cpp16
-rw-r--r--src/gui/rhi/qrhigles2_p_p.h2
-rw-r--r--src/gui/rhi/qrhimetal.mm30
-rw-r--r--src/gui/rhi/qrhimetal_p_p.h2
-rw-r--r--src/gui/rhi/qrhinull.cpp7
-rw-r--r--src/gui/rhi/qrhinull_p_p.h1
-rw-r--r--src/gui/rhi/qrhivulkan.cpp28
-rw-r--r--src/gui/rhi/qrhivulkan_p_p.h2
13 files changed, 221 insertions, 2 deletions
diff --git a/src/gui/rhi/qrhi.cpp b/src/gui/rhi/qrhi.cpp
index 786479fccd..718835ad8f 100644
--- a/src/gui/rhi/qrhi.cpp
+++ b/src/gui/rhi/qrhi.cpp
@@ -4736,6 +4736,100 @@ QRhi::Implementation QRhi::backend() const
}
/*!
+ \return the backend type as string for this QRhi.
+ */
+const char *QRhi::backendName() const
+{
+ switch (d->implType) {
+ case QRhi::Null:
+ return "Null";
+ case QRhi::Vulkan:
+ return "Vulkan";
+ case QRhi::OpenGLES2:
+ return "OpenGL";
+ case QRhi::D3D11:
+ return "D3D11";
+ case QRhi::Metal:
+ return "Metal";
+ default:
+ return "Unknown";
+ }
+}
+
+/*!
+ \enum QRhiDriverInfo::DeviceType
+ Specifies the graphics device's type, when the information is available. In
+ practice this is only applicable with Vulkan and Metal. With others the
+ value will always be UnknownDevice.
+
+ \value UnknownDevice
+ \value IntegratedDevice
+ \value DiscreteDevice
+ \value ExternalDevice
+ \value VirtualDevice
+ \value CpuDevice
+*/
+
+/*!
+ \struct QRhiDriverInfo
+ \internal
+ \inmodule QtGui
+ \since 6.1
+
+ \brief Describes the physical device, adapter, or graphics API
+ implementation that is used by an initialized QRhi.
+
+ Graphics APIs offer different levels and kinds of information. The only
+ value that is available across all APIs is the deviceName, which is a
+ freetext description of the physical device, adapter, or is a combination
+ of the strings reported for \c{GL_VENDOR} + \c{GL_RENDERER} +
+ \c{GL_VERSION}. The deviceId is always 0 for OpenGL. vendorId is always 0
+ for OpenGL and Metal. deviceType is always UnknownDevice for OpenGL and
+ Direct 3D.
+ */
+
+#ifndef QT_NO_DEBUG_STREAM
+static inline const char *deviceTypeStr(QRhiDriverInfo::DeviceType type)
+{
+ switch (type) {
+ case QRhiDriverInfo::UnknownDevice:
+ return "Unknown";
+ case QRhiDriverInfo::IntegratedDevice:
+ return "Integrated";
+ case QRhiDriverInfo::DiscreteDevice:
+ return "Discrete";
+ case QRhiDriverInfo::ExternalDevice:
+ return "External";
+ case QRhiDriverInfo::VirtualDevice:
+ return "Virtual";
+ case QRhiDriverInfo::CpuDevice:
+ return "Cpu";
+ default:
+ return "";
+ }
+}
+QDebug operator<<(QDebug dbg, const QRhiDriverInfo &info)
+{
+ QDebugStateSaver saver(dbg);
+ dbg.nospace() << "QRhiDriverInfo(deviceName=" << info.deviceName
+ << " deviceId=0x" << Qt::hex << info.deviceId
+ << " vendorId=0x" << info.vendorId
+ << " deviceType=" << deviceTypeStr(info.deviceType)
+ << ')';
+ return dbg;
+}
+#endif
+
+/*!
+ \return metadata for the graphics device used by this successfully
+ initialized QRhi instance.
+ */
+QRhiDriverInfo QRhi::driverInfo() const
+{
+ return d->driverInfo();
+}
+
+/*!
\return the thread on which the QRhi was \l{QRhi::create()}{initialized}.
*/
QThread *QRhi::thread() const
diff --git a/src/gui/rhi/qrhi_p.h b/src/gui/rhi/qrhi_p.h
index 14ea81abec..fc65587408 100644
--- a/src/gui/rhi/qrhi_p.h
+++ b/src/gui/rhi/qrhi_p.h
@@ -1443,6 +1443,29 @@ private:
friend class QRhi;
};
+struct Q_GUI_EXPORT QRhiDriverInfo
+{
+ enum DeviceType {
+ UnknownDevice,
+ IntegratedDevice,
+ DiscreteDevice,
+ ExternalDevice,
+ VirtualDevice,
+ CpuDevice
+ };
+
+ QByteArray deviceName;
+ quint64 deviceId = 0;
+ quint64 vendorId = 0;
+ DeviceType deviceType = UnknownDevice;
+};
+
+Q_DECLARE_TYPEINFO(QRhiDriverInfo, Q_RELOCATABLE_TYPE);
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_GUI_EXPORT QDebug operator<<(QDebug, const QRhiDriverInfo &);
+#endif
+
struct Q_GUI_EXPORT QRhiInitParams
{
};
@@ -1530,6 +1553,8 @@ public:
QRhiNativeHandles *importDevice = nullptr);
Implementation backend() const;
+ const char *backendName() const;
+ QRhiDriverInfo driverInfo() const;
QThread *thread() const;
using CleanupCallback = std::function<void(QRhi *)>;
diff --git a/src/gui/rhi/qrhi_p_p.h b/src/gui/rhi/qrhi_p_p.h
index 538df66868..af974b69d0 100644
--- a/src/gui/rhi/qrhi_p_p.h
+++ b/src/gui/rhi/qrhi_p_p.h
@@ -162,6 +162,7 @@ public:
virtual bool isFeatureSupported(QRhi::Feature feature) const = 0;
virtual int resourceLimit(QRhi::ResourceLimit limit) const = 0;
virtual const QRhiNativeHandles *nativeHandles() = 0;
+ virtual QRhiDriverInfo driverInfo() const = 0;
virtual void sendVMemStatsToProfiler() = 0;
virtual bool makeThreadLocalNativeContextCurrent() = 0;
virtual void releaseCachedResources() = 0;
diff --git a/src/gui/rhi/qrhid3d11.cpp b/src/gui/rhi/qrhid3d11.cpp
index 0db32e794f..247d51ecc8 100644
--- a/src/gui/rhi/qrhid3d11.cpp
+++ b/src/gui/rhi/qrhid3d11.cpp
@@ -220,7 +220,6 @@ bool QRhiD3D11::create(QRhi::Flags flags)
hasDxgi2 ? "true" : "false", supportsFlipDiscardSwapchain ? "true" : "false");
if (!importedDeviceAndContext) {
- IDXGIAdapter1 *adapterToUse = nullptr;
IDXGIAdapter1 *adapter;
int requestedAdapterIndex = -1;
if (qEnvironmentVariableIsSet("QT_D3D_ADAPTER_INDEX"))
@@ -253,6 +252,7 @@ bool QRhiD3D11::create(QRhi::Flags flags)
}
}
+ IDXGIAdapter1 *adapterToUse = nullptr;
for (int adapterIndex = 0; dxgiFactory->EnumAdapters1(UINT(adapterIndex), &adapter) != DXGI_ERROR_NOT_FOUND; ++adapterIndex) {
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
@@ -266,6 +266,9 @@ bool QRhiD3D11::create(QRhi::Flags flags)
if (!adapterToUse && (requestedAdapterIndex < 0 || requestedAdapterIndex == adapterIndex)) {
adapterToUse = adapter;
adapterLuid = desc.AdapterLuid;
+ driverInfoStruct.deviceName = name.toUtf8();
+ driverInfoStruct.deviceId = desc.DeviceId;
+ driverInfoStruct.vendorId = desc.VendorId;
qCDebug(QRHI_LOG_INFO, " using this adapter");
} else {
adapter->Release();
@@ -323,6 +326,9 @@ bool QRhiD3D11::create(QRhi::Flags flags)
DXGI_ADAPTER_DESC desc;
adapter->GetDesc(&desc);
adapterLuid = desc.AdapterLuid;
+ driverInfoStruct.deviceName = QString::fromUtf16(reinterpret_cast<char16_t *>(desc.Description)).toUtf8();
+ driverInfoStruct.deviceId = desc.DeviceId;
+ driverInfoStruct.vendorId = desc.VendorId;
adapter->Release();
}
dxgiDev->Release();
@@ -575,6 +581,11 @@ const QRhiNativeHandles *QRhiD3D11::nativeHandles()
return &nativeHandlesStruct;
}
+QRhiDriverInfo QRhiD3D11::driverInfo() const
+{
+ return driverInfoStruct;
+}
+
void QRhiD3D11::sendVMemStatsToProfiler()
{
// nothing to do here
diff --git a/src/gui/rhi/qrhid3d11_p_p.h b/src/gui/rhi/qrhid3d11_p_p.h
index 3b56393900..80e5ee10ae 100644
--- a/src/gui/rhi/qrhid3d11_p_p.h
+++ b/src/gui/rhi/qrhid3d11_p_p.h
@@ -671,6 +671,7 @@ public:
bool isFeatureSupported(QRhi::Feature feature) const override;
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
+ QRhiDriverInfo driverInfo() const override;
void sendVMemStatsToProfiler() override;
bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
@@ -704,6 +705,7 @@ public:
bool supportsFlipDiscardSwapchain = false;
bool deviceLost = false;
QRhiD3D11NativeHandles nativeHandlesStruct;
+ QRhiDriverInfo driverInfoStruct;
struct {
int vsHighestActiveVertexBufferBinding = -1;
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 00477b0716..014d603724 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -461,6 +461,17 @@ bool QRhiGles2::create(QRhi::Flags flags)
if (vendor && renderer && version)
qCDebug(QRHI_LOG_INFO, "OpenGL VENDOR: %s RENDERER: %s VERSION: %s", vendor, renderer, version);
+ if (vendor) {
+ driverInfoStruct.deviceName += QByteArray(vendor);
+ driverInfoStruct.deviceName += ' ';
+ }
+ if (renderer) {
+ driverInfoStruct.deviceName += QByteArray(renderer);
+ driverInfoStruct.deviceName += ' ';
+ }
+ if (version)
+ driverInfoStruct.deviceName += QByteArray(version);
+
const QSurfaceFormat actualFormat = ctx->format();
caps.ctxMajor = actualFormat.majorVersion();
@@ -990,6 +1001,11 @@ const QRhiNativeHandles *QRhiGles2::nativeHandles()
return &nativeHandlesStruct;
}
+QRhiDriverInfo QRhiGles2::driverInfo() const
+{
+ return driverInfoStruct;
+}
+
void QRhiGles2::sendVMemStatsToProfiler()
{
// nothing to do here
diff --git a/src/gui/rhi/qrhigles2_p_p.h b/src/gui/rhi/qrhigles2_p_p.h
index a336497b63..4f4e0f8491 100644
--- a/src/gui/rhi/qrhigles2_p_p.h
+++ b/src/gui/rhi/qrhigles2_p_p.h
@@ -807,6 +807,7 @@ public:
bool isFeatureSupported(QRhi::Feature feature) const override;
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
+ QRhiDriverInfo driverInfo() const override;
void sendVMemStatsToProfiler() override;
bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
@@ -957,6 +958,7 @@ public:
QList<GLint> supportedCompressedFormats;
mutable QList<int> supportedSampleCountList;
QRhiGles2NativeHandles nativeHandlesStruct;
+ QRhiDriverInfo driverInfoStruct;
mutable bool contextLost = false;
struct DeferredReleaseEntry {
diff --git a/src/gui/rhi/qrhimetal.mm b/src/gui/rhi/qrhimetal.mm
index 9e0655ef06..5a1183b8ef 100644
--- a/src/gui/rhi/qrhimetal.mm
+++ b/src/gui/rhi/qrhimetal.mm
@@ -372,7 +372,30 @@ bool QRhiMetal::create(QRhi::Flags flags)
return false;
}
- qCDebug(QRHI_LOG_INFO, "Metal device: %s", qPrintable(QString::fromNSString([d->dev name])));
+ const QString deviceName = QString::fromNSString([d->dev name]);
+ qCDebug(QRHI_LOG_INFO, "Metal device: %s", qPrintable(deviceName));
+ driverInfoStruct.deviceName = deviceName.toUtf8();
+ driverInfoStruct.deviceId = [d->dev registryID];
+#ifdef Q_OS_IOS
+ driverInfoStruct.deviceType = QRhiDriverInfo::IntegratedDevice;
+#else
+ if (@available(macOS 10.15, *)) {
+ const MTLDeviceLocation deviceLocation = [d->dev location];
+ switch (deviceLocation) {
+ case MTLDeviceLocationBuiltIn:
+ driverInfoStruct.deviceType = QRhiDriverInfo::IntegratedDevice;
+ break;
+ case MTLDeviceLocationSlot:
+ driverInfoStruct.deviceType = QRhiDriverInfo::DiscreteDevice;
+ break;
+ case MTLDeviceLocationExternal:
+ driverInfoStruct.deviceType = QRhiDriverInfo::ExternalDevice;
+ break;
+ default:
+ break;
+ }
+ }
+#endif
if (importedCmdQueue)
[d->cmdQueue retain];
@@ -615,6 +638,11 @@ const QRhiNativeHandles *QRhiMetal::nativeHandles()
return &nativeHandlesStruct;
}
+QRhiDriverInfo QRhiMetal::driverInfo() const
+{
+ return driverInfoStruct;
+}
+
void QRhiMetal::sendVMemStatsToProfiler()
{
// nothing to do here
diff --git a/src/gui/rhi/qrhimetal_p_p.h b/src/gui/rhi/qrhimetal_p_p.h
index d2082d04b6..3d1c0f8aa0 100644
--- a/src/gui/rhi/qrhimetal_p_p.h
+++ b/src/gui/rhi/qrhimetal_p_p.h
@@ -435,6 +435,7 @@ public:
bool isFeatureSupported(QRhi::Feature feature) const override;
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
+ QRhiDriverInfo driverInfo() const override;
void sendVMemStatsToProfiler() override;
bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
@@ -463,6 +464,7 @@ public:
QMetalSwapChain *currentSwapChain = nullptr;
QSet<QMetalSwapChain *> swapchains;
QRhiMetalNativeHandles nativeHandlesStruct;
+ QRhiDriverInfo driverInfoStruct;
struct {
int maxTextureSize = 4096;
diff --git a/src/gui/rhi/qrhinull.cpp b/src/gui/rhi/qrhinull.cpp
index 9666f4c688..dbcf8673fd 100644
--- a/src/gui/rhi/qrhinull.cpp
+++ b/src/gui/rhi/qrhinull.cpp
@@ -170,6 +170,13 @@ const QRhiNativeHandles *QRhiNull::nativeHandles()
return &nativeHandlesStruct;
}
+QRhiDriverInfo QRhiNull::driverInfo() const
+{
+ QRhiDriverInfo info;
+ info.deviceName = QByteArrayLiteral("Null");
+ return info;
+}
+
void QRhiNull::sendVMemStatsToProfiler()
{
// nothing to do here
diff --git a/src/gui/rhi/qrhinull_p_p.h b/src/gui/rhi/qrhinull_p_p.h
index eda30614a0..cc8becc5a8 100644
--- a/src/gui/rhi/qrhinull_p_p.h
+++ b/src/gui/rhi/qrhinull_p_p.h
@@ -292,6 +292,7 @@ public:
bool isFeatureSupported(QRhi::Feature feature) const override;
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
+ QRhiDriverInfo driverInfo() const override;
void sendVMemStatsToProfiler() override;
bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
diff --git a/src/gui/rhi/qrhivulkan.cpp b/src/gui/rhi/qrhivulkan.cpp
index aa287ce1b9..cb76851d1e 100644
--- a/src/gui/rhi/qrhivulkan.cpp
+++ b/src/gui/rhi/qrhivulkan.cpp
@@ -361,6 +361,24 @@ static bool qvk_debug_filter(VkDebugReportFlagsEXT flags, VkDebugReportObjectTyp
return false;
}
+static inline QRhiDriverInfo::DeviceType toRhiDeviceType(VkPhysicalDeviceType type)
+{
+ switch (type) {
+ case VK_PHYSICAL_DEVICE_TYPE_OTHER:
+ return QRhiDriverInfo::UnknownDevice;
+ case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
+ return QRhiDriverInfo::IntegratedDevice;
+ case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
+ return QRhiDriverInfo::DiscreteDevice;
+ case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
+ return QRhiDriverInfo::VirtualDevice;
+ case VK_PHYSICAL_DEVICE_TYPE_CPU:
+ return QRhiDriverInfo::CpuDevice;
+ default:
+ return QRhiDriverInfo::UnknownDevice;
+ }
+}
+
bool QRhiVulkan::create(QRhi::Flags flags)
{
Q_UNUSED(flags);
@@ -454,6 +472,11 @@ bool QRhiVulkan::create(QRhi::Flags flags)
physDevProperties.deviceType);
}
+ driverInfoStruct.deviceName = QByteArray(physDevProperties.deviceName);
+ driverInfoStruct.deviceId = physDevProperties.deviceID;
+ driverInfoStruct.vendorId = physDevProperties.vendorID;
+ driverInfoStruct.deviceType = toRhiDeviceType(physDevProperties.deviceType);
+
f->vkGetPhysicalDeviceFeatures(physDev, &physDevFeatures);
// Choose queue and create device, unless the device was specified in importParams.
@@ -4224,6 +4247,11 @@ const QRhiNativeHandles *QRhiVulkan::nativeHandles()
return &nativeHandlesStruct;
}
+QRhiDriverInfo QRhiVulkan::driverInfo() const
+{
+ return driverInfoStruct;
+}
+
void QRhiVulkan::sendVMemStatsToProfiler()
{
QRhiProfilerPrivate *rhiP = profilerPrivateOrNull();
diff --git a/src/gui/rhi/qrhivulkan_p_p.h b/src/gui/rhi/qrhivulkan_p_p.h
index 31edcc6924..a4b306d5c0 100644
--- a/src/gui/rhi/qrhivulkan_p_p.h
+++ b/src/gui/rhi/qrhivulkan_p_p.h
@@ -750,6 +750,7 @@ public:
bool isFeatureSupported(QRhi::Feature feature) const override;
int resourceLimit(QRhi::ResourceLimit limit) const override;
const QRhiNativeHandles *nativeHandles() override;
+ QRhiDriverInfo driverInfo() const override;
void sendVMemStatsToProfiler() override;
bool makeThreadLocalNativeContextCurrent() override;
void releaseCachedResources() override;
@@ -889,6 +890,7 @@ public:
QVkSwapChain *currentSwapChain = nullptr;
QSet<QVkSwapChain *> swapchains;
QRhiVulkanNativeHandles nativeHandlesStruct;
+ QRhiDriverInfo driverInfoStruct;
struct OffscreenFrame {
OffscreenFrame(QRhiImplementation *rhi)