windows: Introduce a built-in GPU blacklist
Use a built-in JSON file in case the QT_OPENGL_BUGLIST environment variable is not set. When QT_OPENGL_BUGLIST is set, the built-in list is ignored. To make the implementation simpler and more readable, some of the code in QWindowsOpenGLTester is reshuffled a bit. It also caches the results now, so it is safe and fast to call supportedRenderers() and friends multiple times. The blacklist currently contains the Intel card from QTBUG-43263 (Intel GMA / HD3000 ?) and may also apply to QTBUG-42240. [ChangeLog][QtGui] Qt now contains a built-in GPU driver blacklist for Windows that disables the usage of desktop OpenGL with some older cards that are known to be unstable with opengl32.dll. Task-number: QTBUG-42240 Task-number: QTBUG-43263 Change-Id: I1ecd65b51fca77925317d52048e7ab01d9b8797c Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>bb10
parent
22afbc1536
commit
85620bd788
|
|
@ -77,6 +77,9 @@ public:
|
|||
struct Gpu {
|
||||
Gpu() : vendorId(0), deviceId(0) {}
|
||||
bool isValid() const { return deviceId; }
|
||||
bool equals(const Gpu &other) const {
|
||||
return vendorId == other.vendorId && deviceId == other.deviceId && driverVersion == other.driverVersion;
|
||||
}
|
||||
|
||||
uint vendorId;
|
||||
uint deviceId;
|
||||
|
|
@ -93,6 +96,21 @@ public:
|
|||
static QSet<QString> gpuFeatures(const Gpu &gpu, const QString &fileName);
|
||||
};
|
||||
|
||||
inline bool operator==(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b)
|
||||
{
|
||||
return a.equals(b);
|
||||
}
|
||||
|
||||
inline bool operator!=(const QOpenGLConfig::Gpu &a, const QOpenGLConfig::Gpu &b)
|
||||
{
|
||||
return !a.equals(b);
|
||||
}
|
||||
|
||||
inline uint qHash(const QOpenGLConfig::Gpu &gpu)
|
||||
{
|
||||
return qHash(gpu.vendorId) + qHash(gpu.deviceId) + qHash(gpu.driverVersion);
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QOPENGL_H
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<RCC>
|
||||
<qresource prefix="/qt-project.org/windows/openglblacklists">
|
||||
<file alias="default.json">openglblacklists/default.json</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Qt built-in GPU driver blacklist",
|
||||
"version": "5.5",
|
||||
"entries": [
|
||||
{
|
||||
"id": 1,
|
||||
"description": "Desktop OpenGL is unreliable on Intel HD3000/GMA (QTBUG-43263, QTBUG-42240)",
|
||||
"vendor_id": "0x8086",
|
||||
"device_id": [ "0x0A16" ],
|
||||
"os": {
|
||||
"type": "win"
|
||||
},
|
||||
"features": [
|
||||
"disable_desktopgl"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -79,9 +79,7 @@
|
|||
# include "qwindowsglcontext.h"
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_WINCE
|
||||
# include "qwindowsopengltester.h"
|
||||
#endif
|
||||
#include "qwindowsopengltester.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
|
@ -209,6 +207,10 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL
|
|||
: m_options(0)
|
||||
, m_fontDatabase(0)
|
||||
{
|
||||
#ifndef Q_OS_WINCE
|
||||
Q_INIT_RESOURCE(openglblacklists);
|
||||
#endif
|
||||
|
||||
static bool dpiAwarenessSet = false;
|
||||
int tabletAbsoluteRange = -1;
|
||||
// Default to per-monitor awareness to avoid being scaled when monitors with different DPI
|
||||
|
|
|
|||
|
|
@ -42,14 +42,16 @@
|
|||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QLibraryInfo>
|
||||
#include <QtCore/QHash>
|
||||
|
||||
#ifndef QT_NO_OPENGL
|
||||
#include <private/qopengl_p.h>
|
||||
#endif
|
||||
|
||||
#ifndef Q_OS_WINCE
|
||||
# include <QtCore/qt_windows.h>
|
||||
# include <private/qsystemlibrary_p.h>
|
||||
# include <d3d9.h>
|
||||
# include <GL/gl.h>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
|
@ -206,56 +208,62 @@ static inline QString resolveBugListFile(const QString &fileName)
|
|||
return QStandardPaths::locate(QStandardPaths::ConfigLocation, fileName);
|
||||
}
|
||||
|
||||
static void readDriverBugList(const GpuDescription &gpu,
|
||||
QWindowsOpenGLTester::Renderers *result)
|
||||
typedef QHash<QOpenGLConfig::Gpu, QWindowsOpenGLTester::Renderers> SupportedRenderersCache;
|
||||
Q_GLOBAL_STATIC(SupportedRenderersCache, supportedRenderersCache)
|
||||
|
||||
#endif // !Q_OS_WINCE
|
||||
|
||||
QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly)
|
||||
{
|
||||
const char bugListFileVar[] = "QT_OPENGL_BUGLIST";
|
||||
if (!qEnvironmentVariableIsSet(bugListFileVar))
|
||||
return;
|
||||
const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar)));
|
||||
if (fileName.isEmpty())
|
||||
return;
|
||||
Q_UNUSED(gpu)
|
||||
#ifndef Q_OS_WINCE
|
||||
QOpenGLConfig::Gpu qgpu;
|
||||
qgpu.deviceId = gpu.deviceId;
|
||||
qgpu.vendorId = gpu.vendorId;
|
||||
qgpu.driverVersion = gpu.driverVersion;
|
||||
const QSet<QString> features = QOpenGLConfig::gpuFeatures(qgpu, fileName);
|
||||
if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific
|
||||
qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu;
|
||||
*result &= ~QWindowsOpenGLTester::DesktopGl;
|
||||
}
|
||||
if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword
|
||||
qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu;
|
||||
*result &= ~QWindowsOpenGLTester::GlesMask;
|
||||
} else {
|
||||
if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword
|
||||
qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu;
|
||||
*result &= ~QWindowsOpenGLTester::AngleRendererD3d11;
|
||||
}
|
||||
if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific
|
||||
qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu;
|
||||
*result &= ~QWindowsOpenGLTester::AngleRendererD3d9;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // !Q_OS_WINCE
|
||||
SupportedRenderersCache *srCache = supportedRenderersCache();
|
||||
SupportedRenderersCache::const_iterator it = srCache->find(qgpu);
|
||||
if (it != srCache->cend())
|
||||
return *it;
|
||||
|
||||
static inline QWindowsOpenGLTester::Renderers
|
||||
detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly)
|
||||
{
|
||||
Q_UNUSED(gpu)
|
||||
#ifndef Q_OS_WINCE
|
||||
// Add checks for card types with known issues here.
|
||||
QWindowsOpenGLTester::Renderers result(QWindowsOpenGLTester::AngleRendererD3d11
|
||||
| QWindowsOpenGLTester::AngleRendererD3d9
|
||||
| QWindowsOpenGLTester::AngleRendererD3d11Warp
|
||||
| QWindowsOpenGLTester::SoftwareRasterizer);
|
||||
|
||||
if (!glesOnly && QWindowsOpenGLTester::testDesktopGL())
|
||||
if (!glesOnly && testDesktopGL())
|
||||
result |= QWindowsOpenGLTester::DesktopGl;
|
||||
|
||||
readDriverBugList(gpu, &result);
|
||||
QSet<QString> features;
|
||||
const char bugListFileVar[] = "QT_OPENGL_BUGLIST";
|
||||
if (qEnvironmentVariableIsSet(bugListFileVar)) {
|
||||
const QString fileName = resolveBugListFile(QFile::decodeName(qgetenv(bugListFileVar)));
|
||||
if (!fileName.isEmpty())
|
||||
features = QOpenGLConfig::gpuFeatures(qgpu, fileName);
|
||||
} else {
|
||||
features = QOpenGLConfig::gpuFeatures(qgpu, QStringLiteral(":/qt-project.org/windows/openglblacklists/default.json"));
|
||||
}
|
||||
qCDebug(lcQpaGl) << "GPU features:" << features;
|
||||
|
||||
if (features.contains(QStringLiteral("disable_desktopgl"))) { // Qt-specific
|
||||
qCWarning(lcQpaGl) << "Disabling Desktop GL: " << gpu;
|
||||
result &= ~QWindowsOpenGLTester::DesktopGl;
|
||||
}
|
||||
if (features.contains(QStringLiteral("disable_angle"))) { // Qt-specific keyword
|
||||
qCWarning(lcQpaGl) << "Disabling ANGLE: " << gpu;
|
||||
result &= ~QWindowsOpenGLTester::GlesMask;
|
||||
} else {
|
||||
if (features.contains(QStringLiteral("disable_d3d11"))) { // standard keyword
|
||||
qCWarning(lcQpaGl) << "Disabling D3D11: " << gpu;
|
||||
result &= ~QWindowsOpenGLTester::AngleRendererD3d11;
|
||||
}
|
||||
if (features.contains(QStringLiteral("disable_d3d9"))) { // Qt-specific
|
||||
qCWarning(lcQpaGl) << "Disabling D3D9: " << gpu;
|
||||
result &= ~QWindowsOpenGLTester::AngleRendererD3d9;
|
||||
}
|
||||
}
|
||||
|
||||
srCache->insert(qgpu, result);
|
||||
return result;
|
||||
#else // !Q_OS_WINCE
|
||||
return QWindowsOpenGLTester::Gles;
|
||||
|
|
|
|||
|
|
@ -80,9 +80,12 @@ public:
|
|||
|
||||
static Renderer requestedGlesRenderer();
|
||||
static Renderer requestedRenderer();
|
||||
|
||||
static Renderers supportedGlesRenderers();
|
||||
static Renderers supportedRenderers();
|
||||
|
||||
private:
|
||||
static QWindowsOpenGLTester::Renderers detectSupportedRenderers(const GpuDescription &gpu, bool glesOnly);
|
||||
static bool testDesktopGL();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ contains(QT_CONFIG,dynamicgl) {
|
|||
RESOURCES += $$PWD/cursors.qrc
|
||||
}
|
||||
|
||||
!wince*: RESOURCES += $$PWD/openglblacklists.qrc
|
||||
|
||||
contains(QT_CONFIG, freetype) {
|
||||
DEFINES *= QT_NO_FONTCONFIG
|
||||
QT_FREETYPE_DIR = $$QT_SOURCE_TREE/src/3rdparty/freetype
|
||||
|
|
|
|||
Loading…
Reference in New Issue