summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2019-03-13 13:32:34 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2019-03-14 12:15:11 +0000
commit15f88a7c01007ae1962b83aefc5a536e16fcb446 (patch)
tree6dfdeefe0c6741ed4b6da47b3e11d7fca1b0cf9c /src/plugins/platforms
parent036fe49580d7470eeaa4c168845bdf2483946f22 (diff)
Windows QPA: Output all adapters in diagnostics used by qtdiag
Split up the code detecting the GPUs into small helpers. Add a QDirect3D9Handle class providing Direct3D9 functionality, add GpuDescription::detectAll() and add a QVariantList "gpuList" property to the native interface. Task-number: QTBUG-50371 Task-number: QTBUG-65882 Change-Id: I8673542d327837babc2ad8f507da76e8ff5524ea Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
Diffstat (limited to 'src/plugins/platforms')
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowsnativeinterface.h2
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.cpp132
-rw-r--r--src/plugins/platforms/windows/qwindowsopengltester.h2
4 files changed, 104 insertions, 41 deletions
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
index 32eec322e8..ed945ec4b1 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp
@@ -289,4 +289,13 @@ QVariant QWindowsNativeInterface::gpu() const
return GpuDescription::detect().toVariant();
}
+QVariant QWindowsNativeInterface::gpuList() const
+{
+ QVariantList result;
+ const auto gpus = GpuDescription::detectAll();
+ for (const auto &gpu : gpus)
+ result.append(gpu.toVariant());
+ return result;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h
index d085a4afb3..e6f8aae8fb 100644
--- a/src/plugins/platforms/windows/qwindowsnativeinterface.h
+++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h
@@ -66,6 +66,7 @@ class QWindowsNativeInterface : public QPlatformNativeInterface
Q_OBJECT
Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose)
Q_PROPERTY(QVariant gpu READ gpu STORED false)
+ Q_PROPERTY(QVariant gpuList READ gpuList STORED false)
public:
void *nativeResourceForIntegration(const QByteArray &resource) override;
@@ -91,6 +92,7 @@ public:
void setAsyncExpose(bool value);
QVariant gpu() const;
+ QVariant gpuList() const;
QVariantMap windowProperties(QPlatformWindow *window) const override;
QVariant windowProperty(QPlatformWindow *window, const QString &name) const override;
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp
index 2046135725..840a3a11c4 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.cpp
+++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp
@@ -62,19 +62,70 @@ QT_BEGIN_NAMESPACE
static const DWORD VENDOR_ID_AMD = 0x1002;
-GpuDescription GpuDescription::detect()
+static GpuDescription adapterIdentifierToGpuDescription(const D3DADAPTER_IDENTIFIER9 &adapterIdentifier)
+{
+ GpuDescription result;
+ result.vendorId = adapterIdentifier.VendorId;
+ result.deviceId = adapterIdentifier.DeviceId;
+ result.revision = adapterIdentifier.Revision;
+ result.subSysId = adapterIdentifier.SubSysId;
+ QVector<int> version(4, 0);
+ version[0] = HIWORD(adapterIdentifier.DriverVersion.HighPart); // Product
+ version[1] = LOWORD(adapterIdentifier.DriverVersion.HighPart); // Version
+ version[2] = HIWORD(adapterIdentifier.DriverVersion.LowPart); // Sub version
+ version[3] = LOWORD(adapterIdentifier.DriverVersion.LowPart); // build
+ result.driverVersion = QVersionNumber(version);
+ result.driverName = adapterIdentifier.Driver;
+ result.description = adapterIdentifier.Description;
+ return result;
+}
+
+class QDirect3D9Handle
+{
+public:
+ Q_DISABLE_COPY(QDirect3D9Handle)
+
+ QDirect3D9Handle();
+ ~QDirect3D9Handle();
+
+ bool isValid() const { return m_direct3D9 != nullptr; }
+
+ UINT adapterCount() const { return m_direct3D9 ? m_direct3D9->GetAdapterCount() : 0u; }
+ bool retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const;
+
+private:
+ QSystemLibrary m_d3d9lib;
+ IDirect3D9 *m_direct3D9 = nullptr;
+};
+
+QDirect3D9Handle::QDirect3D9Handle() :
+ m_d3d9lib(QStringLiteral("d3d9"))
{
- typedef IDirect3D9 * (WINAPI *PtrDirect3DCreate9)(UINT);
+ using PtrDirect3DCreate9 = IDirect3D9 *(WINAPI *)(UINT);
+ if (m_d3d9lib.load()) {
+ if (auto direct3DCreate9 = (PtrDirect3DCreate9)m_d3d9lib.resolve("Direct3DCreate9"))
+ m_direct3D9 = direct3DCreate9(D3D_SDK_VERSION);
+ }
+}
+
+QDirect3D9Handle::~QDirect3D9Handle()
+{
+ if (m_direct3D9)
+ m_direct3D9->Release();
+}
+
+bool QDirect3D9Handle::retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const
+{
+ return m_direct3D9
+ && SUCCEEDED(m_direct3D9->GetAdapterIdentifier(n, 0, adapterIdentifier));
+}
+
+GpuDescription GpuDescription::detect()
+{
GpuDescription result;
- QSystemLibrary d3d9lib(QStringLiteral("d3d9"));
- if (!d3d9lib.load())
- return result;
- PtrDirect3DCreate9 direct3DCreate9 = (PtrDirect3DCreate9)d3d9lib.resolve("Direct3DCreate9");
- if (!direct3DCreate9)
- return result;
- IDirect3D9 *direct3D9 = direct3DCreate9(D3D_SDK_VERSION);
- if (!direct3D9)
+ QDirect3D9Handle direct3D9;
+ if (!direct3D9.isValid())
return result;
D3DADAPTER_IDENTIFIER9 adapterIdentifier;
@@ -85,20 +136,8 @@ GpuDescription GpuDescription::detect()
// and D3D uses by default. Therefore querying any additional adapters is
// futile and not useful for our purposes in general, except for
// identifying a few special cases later on.
- HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier);
- if (SUCCEEDED(hr)) {
- result.vendorId = adapterIdentifier.VendorId;
- result.deviceId = adapterIdentifier.DeviceId;
- result.revision = adapterIdentifier.Revision;
- result.subSysId = adapterIdentifier.SubSysId;
- QVector<int> version(4, 0);
- version[0] = HIWORD(adapterIdentifier.DriverVersion.HighPart); // Product
- version[1] = LOWORD(adapterIdentifier.DriverVersion.HighPart); // Version
- version[2] = HIWORD(adapterIdentifier.DriverVersion.LowPart); // Sub version
- version[3] = LOWORD(adapterIdentifier.DriverVersion.LowPart); // build
- result.driverVersion = QVersionNumber(version);
- result.driverName = adapterIdentifier.Driver;
- result.description = adapterIdentifier.Description;
+ if (direct3D9.retrieveAdapterIdentifier(0, &adapterIdentifier)) {
+ result = adapterIdentifierToGpuDescription(adapterIdentifier);
isAMD = result.vendorId == VENDOR_ID_AMD;
}
@@ -106,30 +145,41 @@ GpuDescription GpuDescription::detect()
// when starting apps on a screen connected to the Intel card) by looking
// for a default AMD adapter and an additional non-AMD one.
if (isAMD) {
- const UINT adapterCount = direct3D9->GetAdapterCount();
+ const UINT adapterCount = direct3D9.adapterCount();
for (UINT adp = 1; adp < adapterCount; ++adp) {
- hr = direct3D9->GetAdapterIdentifier(adp, 0, &adapterIdentifier);
- if (SUCCEEDED(hr)) {
- if (adapterIdentifier.VendorId != VENDOR_ID_AMD) {
- // Bingo. Now figure out the display for the AMD card.
- DISPLAY_DEVICE dd;
- memset(&dd, 0, sizeof(dd));
- dd.cb = sizeof(dd);
- for (int dev = 0; EnumDisplayDevices(nullptr, dev, &dd, 0); ++dev) {
- if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
- // DeviceName is something like \\.\DISPLAY1 which can be used to
- // match with the MONITORINFOEX::szDevice queried by QWindowsScreen.
- result.gpuSuitableScreen = QString::fromWCharArray(dd.DeviceName);
- break;
- }
+ if (direct3D9.retrieveAdapterIdentifier(adp, &adapterIdentifier)
+ && adapterIdentifier.VendorId != VENDOR_ID_AMD) {
+ // Bingo. Now figure out the display for the AMD card.
+ DISPLAY_DEVICE dd;
+ memset(&dd, 0, sizeof(dd));
+ dd.cb = sizeof(dd);
+ for (int dev = 0; EnumDisplayDevices(nullptr, dev, &dd, 0); ++dev) {
+ if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
+ // DeviceName is something like \\.\DISPLAY1 which can be used to
+ // match with the MONITORINFOEX::szDevice queried by QWindowsScreen.
+ result.gpuSuitableScreen = QString::fromWCharArray(dd.DeviceName);
+ break;
}
- break;
}
+ break;
}
}
}
- direct3D9->Release();
+ return result;
+}
+
+QVector<GpuDescription> GpuDescription::detectAll()
+{
+ QVector<GpuDescription> result;
+ QDirect3D9Handle direct3D9;
+ if (const UINT adapterCount = direct3D9.adapterCount()) {
+ for (UINT adp = 0; adp < adapterCount; ++adp) {
+ D3DADAPTER_IDENTIFIER9 adapterIdentifier;
+ if (direct3D9.retrieveAdapterIdentifier(adp, &adapterIdentifier))
+ result.append(adapterIdentifierToGpuDescription(adapterIdentifier));
+ }
+ }
return result;
}
diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h
index 08628c2586..9576dfbae0 100644
--- a/src/plugins/platforms/windows/qwindowsopengltester.h
+++ b/src/plugins/platforms/windows/qwindowsopengltester.h
@@ -42,6 +42,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qflags.h>
+#include <QtCore/qvector.h>
#include <QtCore/qversionnumber.h>
QT_BEGIN_NAMESPACE
@@ -52,6 +53,7 @@ class QVariant;
struct GpuDescription
{
static GpuDescription detect();
+ static QVector<GpuDescription> detectAll();
QString toString() const;
QVariant toVariant() const;