From 042cd97884bb86dfd0bedaa63480d99846ab06bb Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 12 Jan 2021 13:02:13 +0100 Subject: 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 --- src/gui/rhi/qrhi.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++ src/gui/rhi/qrhi_p.h | 25 ++++++++++++ src/gui/rhi/qrhi_p_p.h | 1 + src/gui/rhi/qrhid3d11.cpp | 13 +++++- src/gui/rhi/qrhid3d11_p_p.h | 2 + src/gui/rhi/qrhigles2.cpp | 16 ++++++++ src/gui/rhi/qrhigles2_p_p.h | 2 + src/gui/rhi/qrhimetal.mm | 30 +++++++++++++- src/gui/rhi/qrhimetal_p_p.h | 2 + src/gui/rhi/qrhinull.cpp | 7 ++++ src/gui/rhi/qrhinull_p_p.h | 1 + src/gui/rhi/qrhivulkan.cpp | 28 +++++++++++++ src/gui/rhi/qrhivulkan_p_p.h | 2 + 13 files changed, 221 insertions(+), 2 deletions(-) (limited to 'src/gui') 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 @@ -4735,6 +4735,100 @@ QRhi::Implementation QRhi::backend() const return d->implType; } +/*! + \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}. */ 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; 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(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 supportedCompressedFormats; mutable QList 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 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 swapchains; QRhiVulkanNativeHandles nativeHandlesStruct; + QRhiDriverInfo driverInfoStruct; struct OffscreenFrame { OffscreenFrame(QRhiImplementation *rhi) -- cgit v1.2.3