From 0fa092cbae1593ca73577ecf9ec71283ae3f2498 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 8 Jan 2015 15:43:29 +0100 Subject: Windows: Add GPU detection. Compile qwindowsopengltester on all platforms and add struct GpuDescription with detection method based on IDirect3D9 (dynamically loaded). Expose as a QVariantMap-property to QWindowsNativeInterface to be able to access it from qtdiag. Task-number: QTBUG-43263 Change-Id: I3c6cd0bbbe36465e0e05f7064ecfc943d6ea4101 Reviewed-by: Laszlo Agocs --- .../platforms/windows/qwindowsnativeinterface.cpp | 8 +- .../platforms/windows/qwindowsnativeinterface.h | 5 +- .../platforms/windows/qwindowsopengltester.cpp | 142 ++++++++++++++++++++- .../platforms/windows/qwindowsopengltester.h | 58 ++++++++- src/plugins/platforms/windows/windows.pri | 11 +- 5 files changed, 213 insertions(+), 11 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp index 002f4ae92c..12ecc53f92 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.cpp +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -35,6 +35,7 @@ #include "qwindowswindow.h" #include "qwindowscontext.h" #include "qwindowsopenglcontext.h" +#include "qwindowsopengltester.h" #include "qwindowsintegration.h" #include "qwindowsmime.h" @@ -216,4 +217,9 @@ int QWindowsNativeInterface::registerMimeType(const QString &mimeType) return QWindowsMime::registerMimeType(mimeType); } +QVariant QWindowsNativeInterface::gpu() const +{ + return GpuDescription::detect().toVariant(); +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsnativeinterface.h b/src/plugins/platforms/windows/qwindowsnativeinterface.h index 3d47dbe721..349ed28b1d 100644 --- a/src/plugins/platforms/windows/qwindowsnativeinterface.h +++ b/src/plugins/platforms/windows/qwindowsnativeinterface.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -58,6 +58,7 @@ class QWindowsNativeInterface : public QPlatformNativeInterface { Q_OBJECT Q_PROPERTY(bool asyncExpose READ asyncExpose WRITE setAsyncExpose) + Q_PROPERTY(QVariant gpu READ gpu STORED false) public: void *nativeResourceForIntegration(const QByteArray &resource) Q_DECL_OVERRIDE; @@ -81,6 +82,8 @@ public: bool asyncExpose() const; void setAsyncExpose(bool value); + QVariant gpu() const; + QVariantMap windowProperties(QPlatformWindow *window) const Q_DECL_OVERRIDE; QVariant windowProperty(QPlatformWindow *window, const QString &name) const Q_DECL_OVERRIDE; QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowsopengltester.cpp b/src/plugins/platforms/windows/qwindowsopengltester.cpp index ba3a95ce7a..5ef3dc0855 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.cpp +++ b/src/plugins/platforms/windows/qwindowsopengltester.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -32,13 +32,148 @@ ****************************************************************************/ #include "qwindowsopengltester.h" -#include "qt_windows.h" #include "qwindowscontext.h" +#include +#include +#include + +#ifndef Q_OS_WINCE +# include +# include +# include +#endif + QT_BEGIN_NAMESPACE +QString GpuDriverVersion::toString() const +{ + return QString::number(product) + + QLatin1Char('.') + QString::number(version) + + QLatin1Char('.') + QString::number(subVersion) + + QLatin1Char('.') + QString::number(build); +} + +int GpuDriverVersion::compare(const GpuDriverVersion &rhs) const +{ + if (product < rhs.product) + return -1; + if (product > rhs.product) + return 1; + if (version < rhs.version) + return -1; + if (version > rhs.version) + return 1; + if (subVersion < rhs.subVersion) + return -1; + if (subVersion > rhs.subVersion) + return 1; + if (build < rhs.build) + return -1; + if (build > rhs.build) + return 1; + return 0; +} + +GpuDescription GpuDescription::detect() +{ +#ifndef Q_OS_WINCE + typedef IDirect3D9 * (WINAPI *PtrDirect3DCreate9)(UINT); + + 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) + return result; + D3DADAPTER_IDENTIFIER9 adapterIdentifier; + const HRESULT hr = direct3D9->GetAdapterIdentifier(0, 0, &adapterIdentifier); + direct3D9->Release(); + if (SUCCEEDED(hr)) { + result.vendorId = int(adapterIdentifier.VendorId); + result.deviceId = int(adapterIdentifier.DeviceId); + result.revision = int(adapterIdentifier.Revision); + result.subSysId = int(adapterIdentifier.SubSysId); + result.driverVersion.product = HIWORD(adapterIdentifier.DriverVersion.HighPart); + result.driverVersion.version = LOWORD(adapterIdentifier.DriverVersion.HighPart); + result.driverVersion.subVersion = HIWORD(adapterIdentifier.DriverVersion.LowPart); + result.driverVersion.build = LOWORD(adapterIdentifier.DriverVersion.LowPart); + result.driverName = adapterIdentifier.Driver; + result.description = adapterIdentifier.Description; + } + return result; +#else // !Q_OS_WINCE + GpuDescription result; + result.vendorId = result.deviceId = result.revision + = result.driverVersion.product = result.driverVersion.version + = result.driverVersion.build = 1; + result.driverName = result.description = QByteArrayLiteral("Generic"); + return result; +#endif +} + +QDebug operator<<(QDebug d, const GpuDriverVersion &v) +{ + QDebugStateSaver s(d); + d.nospace(); + d << v.product << '.' << v.version << '.' << v.subVersion << '.' << v.build; + return d; +} + +QDebug operator<<(QDebug d, const GpuDescription &gd) +{ + QDebugStateSaver s(d); + d.nospace(); + d << hex << showbase << "GpuDescription(vendorId=" << gd.vendorId + << ", deviceId=" << gd.deviceId << ", subSysId=" << gd.subSysId + << dec << noshowbase << ", revision=" << gd.revision + << ", driver: " << gd.driverName + << ", version=" << gd.driverVersion << ", " << gd.description << ')'; + return d; +} + +// Return printable string formatted like the output of the dxdiag tool. +QString GpuDescription::toString() const +{ + QString result; + QTextStream str(&result); + str << " Card name: " << description + << "\n Driver Name: " << driverName + << "\n Driver Version: " << driverVersion.toString() + << "\n Vendor ID: 0x" << qSetPadChar(QLatin1Char('0')) + << uppercasedigits << hex << qSetFieldWidth(4) << vendorId + << "\n Device ID: 0x" << qSetFieldWidth(4) << deviceId + << "\n SubSys ID: 0x" << qSetFieldWidth(8) << subSysId + << "\n Revision ID: 0x" << qSetFieldWidth(4) << revision + << dec; + return result; +} + +QVariant GpuDescription::toVariant() const +{ + QVariantMap result; + result.insert(QStringLiteral("vendorId"), QVariant(vendorId)); + result.insert(QStringLiteral("deviceId"), QVariant(deviceId)); + result.insert(QStringLiteral("subSysId"),QVariant(subSysId)); + result.insert(QStringLiteral("revision"), QVariant(revision)); + result.insert(QStringLiteral("driver"), QVariant(QLatin1String(driverName))); + result.insert(QStringLiteral("driverProduct"), QVariant(driverVersion.product)); + result.insert(QStringLiteral("driverVersion"), QVariant(driverVersion.version)); + result.insert(QStringLiteral("driverSubVersion"), QVariant(driverVersion.subVersion)); + result.insert(QStringLiteral("driverBuild"), QVariant(driverVersion.build)); + result.insert(QStringLiteral("driverVersionString"), driverVersion.toString()); + result.insert(QStringLiteral("description"), QVariant(QLatin1String(description))); + result.insert(QStringLiteral("printable"), QVariant(toString())); + return result; +} + bool QWindowsOpenGLTester::testDesktopGL() { +#ifndef Q_OS_WINCE HMODULE lib = 0; HWND wnd = 0; HDC dc = 0; @@ -133,6 +268,9 @@ cleanup: // No FreeLibrary. Some implementations, Mesa in particular, deadlock when trying to unload. return result; +#else // !Q_OS_WINCE + return false; +#endif } QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsopengltester.h b/src/plugins/platforms/windows/qwindowsopengltester.h index 40a8e9d3ac..98b707dcd2 100644 --- a/src/plugins/platforms/windows/qwindowsopengltester.h +++ b/src/plugins/platforms/windows/qwindowsopengltester.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the plugins of the Qt Toolkit. @@ -31,10 +31,64 @@ ** ****************************************************************************/ +#ifndef QWINDOWSOPENGLTESTER_H +#define QWINDOWSOPENGLTESTER_H + #include +#include + QT_BEGIN_NAMESPACE +class QDebug; +class QVariant; + +struct GpuDriverVersion // ### fixme: Use QVersionNumber in Qt 5.5? +{ + GpuDriverVersion(int p = 0, int v = 0, int sv =0, int b = 0) : product(p), version(v), subVersion(sv), build(b) {} + QString toString() const; + int compare(const GpuDriverVersion &rhs) const; + + int product; + int version; + int subVersion; + int build; +}; + +inline bool operator==(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return !v1.compare(v2); } +inline bool operator!=(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2); } +inline bool operator< (const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) < 0; } +inline bool operator<=(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) <= 0; } +inline bool operator> (const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) > 0; } +inline bool operator>=(const GpuDriverVersion &v1, const GpuDriverVersion &v2) + { return v1.compare(v2) >= 0; } + +QDebug operator<<(QDebug d, const GpuDriverVersion &gd); + +struct GpuDescription +{ + GpuDescription() : vendorId(0), deviceId(0), revision(0), subSysId(0) {} + + static GpuDescription detect(); + QString toString() const; + QVariant toVariant() const; + + int vendorId; + int deviceId; + int revision; + int subSysId; + GpuDriverVersion driverVersion; + QByteArray driverName; + QByteArray description; +}; + +QDebug operator<<(QDebug d, const GpuDescription &gd); + class QWindowsOpenGLTester { public: @@ -42,3 +96,5 @@ public: }; QT_END_NAMESPACE + +#endif // QWINDOWSOPENGLTESTER_H diff --git a/src/plugins/platforms/windows/windows.pri b/src/plugins/platforms/windows/windows.pri index 8e5f35d293..246598677f 100644 --- a/src/plugins/platforms/windows/windows.pri +++ b/src/plugins/platforms/windows/windows.pri @@ -40,7 +40,8 @@ SOURCES += \ $$PWD/qwindowsservices.cpp \ $$PWD/qwindowsnativeimage.cpp \ $$PWD/qwindowsnativeinterface.cpp \ - $$PWD/qwindowsscaling.cpp + $$PWD/qwindowsscaling.cpp \ + $$PWD/qwindowsopengltester.cpp HEADERS += \ $$PWD/qwindowswindow.h \ @@ -66,9 +67,8 @@ HEADERS += \ $$PWD/qplatformfunctions_wince.h \ $$PWD/qwindowsnativeimage.h \ $$PWD/qwindowsnativeinterface.h \ - $$PWD/qwindowsscaling.h - -!wince: HEADERS += $$PWD/qwindowsopengltester.h + $$PWD/qwindowsscaling.h \ + $$PWD/qwindowsopengltester.h INCLUDEPATH += $$PWD @@ -84,8 +84,7 @@ contains(QT_CONFIG, opengles2) { # Dynamic GL needs both WGL and EGL contains(QT_CONFIG,dynamicgl) { - SOURCES += $$PWD/qwindowseglcontext.cpp \ - $$PWD/qwindowsopengltester.cpp + SOURCES += $$PWD/qwindowseglcontext.cpp HEADERS += $$PWD/qwindowseglcontext.h } -- cgit v1.2.3