7#include <QtCore/qvariant.h>
8#include <QtCore/qmap.h>
9#include <QtCore/qdebug.h>
10#include <QtCore/qtextstream.h>
11#include <QtCore/qcoreapplication.h>
12#include <QtCore/qfile.h>
13#include <QtCore/qfileinfo.h>
14#include <QtCore/qstandardpaths.h>
15#include <QtCore/qlibraryinfo.h>
16#include <QtCore/qhash.h>
17#include <private/qsystemlibrary_p.h>
18#include <QtGui/qtgui-config.h>
21#include <private/qopengl_p.h>
24#include <QtCore/qt_windows.h>
34 result.vendorId = adapterIdentifier.VendorId;
35 result.deviceId = adapterIdentifier.DeviceId;
36 result.revision = adapterIdentifier.Revision;
37 result.subSysId = adapterIdentifier.SubSysId;
39 version[0] = HIWORD(adapterIdentifier.DriverVersion.HighPart);
40 version[1] = LOWORD(adapterIdentifier.DriverVersion.HighPart);
41 version[2] = HIWORD(adapterIdentifier.DriverVersion.LowPart);
42 version[3] = LOWORD(adapterIdentifier.DriverVersion.LowPart);
44 result.driverName = adapterIdentifier.Driver;
45 result.description = adapterIdentifier.Description;
57 bool isValid()
const {
return m_direct3D9 !=
nullptr; }
59 UINT
adapterCount()
const {
return m_direct3D9 ? m_direct3D9->GetAdapterCount() : 0u; }
63 IDirect3D9 *m_direct3D9 =
nullptr;
68 m_direct3D9 = Direct3DCreate9(D3D_SDK_VERSION);
74 m_direct3D9->Release();
80 && SUCCEEDED(m_direct3D9->GetAdapterIdentifier(
n, 0, adapterIdentifier));
90 D3DADAPTER_IDENTIFIER9 adapterIdentifier;
108 for (UINT adp = 1; adp < adapterCount; ++adp) {
113 memset(&dd, 0,
sizeof(dd));
115 for (
int dev = 0; EnumDisplayDevices(
nullptr, dev, &dd, 0); ++dev) {
116 if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) {
135 if (
const UINT adapterCount = direct3D9.
adapterCount()) {
136 for (UINT adp = 0; adp < adapterCount; ++adp) {
137 D3DADAPTER_IDENTIFIER9 adapterIdentifier;
145#ifndef QT_NO_DEBUG_STREAM
199 const char openGlVar[] =
"QT_OPENGL";
201 qWarning(
"Qt::AA_UseOpenGLES is no longer supported in Qt 6");
208 if (requested ==
"angle")
209 qWarning(
"QT_OPENGL=angle is no longer supported in Qt 6");
210 if (requested ==
"desktop")
212 if (requested ==
"software")
214 qCWarning(lcQpaGl) <<
"Invalid value set for " << openGlVar <<
": " << requested;
239QWindowsOpenGLTester::Renderers QWindowsOpenGLTester::detectSupportedRenderers(
const GpuDescription &gpu,
242#if defined(QT_NO_OPENGL)
250 if (
it != srCache->
cend())
256 if (requested ==
DesktopGl || testDesktopGL())
261 const char bugListFileVar[] =
"QT_OPENGL_BUGLIST";
270 qCDebug(lcQpaGl) <<
"GPU features:" << features;
273 qCDebug(lcQpaGl) <<
"Disabling Desktop GL: " << gpu;
277 qCDebug(lcQpaGl) <<
"Disabling rotation: " << gpu;
281 qCDebug(lcQpaGl) <<
"Disabling program cache: " << gpu;
292 const QWindowsOpenGLTester::Renderers
result = detectSupportedRenderers(gpu, requested);
293 qCDebug(lcQpaGl) << __FUNCTION__ << gpu << requested <<
"renderer: " <<
result;
297bool QWindowsOpenGLTester::testDesktopGL()
299#if !defined(QT_NO_OPENGL)
300 typedef HGLRC (WINAPI *CreateContextType)(HDC);
301 typedef BOOL (WINAPI *DeleteContextType)(HGLRC);
302 typedef BOOL (WINAPI *MakeCurrentType)(HDC, HGLRC);
303 typedef PROC (WINAPI *WglGetProcAddressType)(LPCSTR);
311 CreateContextType CreateContext =
nullptr;
312 DeleteContextType DeleteContext =
nullptr;
313 MakeCurrentType MakeCurrent =
nullptr;
314 WglGetProcAddressType WGL_GetProcAddress =
nullptr;
320 lib = QSystemLibrary::load(L
"opengl32");
322 CreateContext =
reinterpret_cast<CreateContextType
>(
323 reinterpret_cast<QFunctionPointer
>(::GetProcAddress(lib,
"wglCreateContext")));
326 DeleteContext =
reinterpret_cast<DeleteContextType
>(
327 reinterpret_cast<QFunctionPointer
>(::GetProcAddress(lib,
"wglDeleteContext")));
330 MakeCurrent =
reinterpret_cast<MakeCurrentType
>(
331 reinterpret_cast<QFunctionPointer
>(::GetProcAddress(lib,
"wglMakeCurrent")));
334 WGL_GetProcAddress =
reinterpret_cast<WglGetProcAddressType
>(
335 reinterpret_cast<QFunctionPointer
>(::GetProcAddress(lib,
"wglGetProcAddress")));
336 if (!WGL_GetProcAddress)
340 wclass.cbClsExtra = 0;
341 wclass.cbWndExtra = 0;
342 wclass.hInstance =
static_cast<HINSTANCE
>(GetModuleHandle(
nullptr));
343 wclass.hIcon =
nullptr;
344 wclass.hCursor =
nullptr;
345 wclass.hbrBackground = HBRUSH(COLOR_BACKGROUND);
346 wclass.lpszMenuName =
nullptr;
347 wclass.lpfnWndProc = DefWindowProc;
349 wclass.style = CS_OWNDC;
350 if (!RegisterClass(&wclass))
352 wnd = CreateWindow(
className, L
"qtopenglproxytest", WS_OVERLAPPED,
353 0, 0, 640, 480,
nullptr,
nullptr, wclass.hInstance,
nullptr);
360 PIXELFORMATDESCRIPTOR pfd;
361 memset(&pfd, 0,
sizeof(PIXELFORMATDESCRIPTOR));
362 pfd.nSize =
sizeof(PIXELFORMATDESCRIPTOR);
364 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_GENERIC_FORMAT;
365 pfd.iPixelType = PFD_TYPE_RGBA;
367 int pixelFormat = ChoosePixelFormat(dc, &pfd);
370 if (!SetPixelFormat(dc, pixelFormat, &pfd))
382 auto GetString =
reinterpret_cast<GetString_t
>(
383 reinterpret_cast<QFunctionPointer
>(::GetProcAddress(lib,
"glGetString")));
385 if (
const char *versionStr =
reinterpret_cast<const char *
>(GetString(GL_VERSION))) {
387 const int majorDot = version.indexOf(
'.');
388 if (majorDot != -1) {
389 int minorDot = version.indexOf(
'.', majorDot + 1);
391 minorDot = version.size();
392 const int major = version.mid(0, majorDot).toInt();
393 const int minor = version.mid(majorDot + 1, minorDot - majorDot - 1).toInt();
394 qCDebug(lcQpaGl,
"Basic wglCreateContext gives version %d.%d", major, minor);
400 qCDebug(lcQpaGl,
"OpenGL version too low");
406 qCDebug(lcQpaGl,
"OpenGL 1.x entry points not found");
410 if (WGL_GetProcAddress(
"glCreateShader")) {
412 qCDebug(lcQpaGl,
"OpenGL 2.0 entry points available");
414 qCDebug(lcQpaGl,
"OpenGL 2.0 entry points not found");
417 qCDebug(lcQpaGl,
"Failed to load opengl32.dll");
422 MakeCurrent(
nullptr,
nullptr);
429 UnregisterClass(
className, GetModuleHandle(
nullptr));
static bool testAttribute(Qt::ApplicationAttribute attribute)
Returns true if attribute attribute is set; otherwise returns false.
UINT adapterCount() const
bool retrieveAdapterIdentifier(UINT n, D3DADAPTER_IDENTIFIER9 *adapterIdentifier) const
\inmodule QtCore \reentrant
QString absoluteFilePath() const
Returns an absolute path including the file name.
bool isFile() const
Returns true if this object points to a file or to a symbolic link to a file.
static QString decodeName(const QByteArray &localFileName)
This does the reverse of QFile::encodeName() using localFileName.
const_iterator constFind(const Key &key) const noexcept
const_iterator cend() const noexcept
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
static QString path(LibraryPath p)
static QSet< QString > gpuFeatures(const Gpu &gpu, const QString &osName, const QVersionNumber &kernelVersion, const QString &osVersion, const QJsonDocument &doc)
bool contains(const T &value) const
static QString locate(StandardLocation type, const QString &fileName, LocateOptions options=LocateFile)
\macro QT_RESTRICTED_CAST_FROM_ASCII
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
Q_CORE_EXPORT QString toString() const
Returns a string with all of the segments delimited by a period ({.}).
int segmentAt(qsizetype index) const noexcept
Returns the segment value at index.
@ DisableProgramCacheFlag
static Renderer requestedRenderer()
static QWindowsOpenGLTester::Renderers supportedRenderers(Renderer requested)
QSet< QString >::iterator it
Combined button and popup list for selecting options.
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
QTextStream & showbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ShowBase) on stream and r...
QTextStream & uppercasedigits(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::UppercaseDigits) on strea...
QTextStream & noshowbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() & ~QTextStream::ShowBase) on stream and ...
QTextStream & dec(QTextStream &stream)
Calls QTextStream::setIntegerBase(10) on stream and returns stream.
#define Q_GLOBAL_STATIC(TYPE, NAME,...)
#define qCWarning(category,...)
#define qCDebug(category,...)
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
#define QStringLiteral(str)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
Q_CORE_EXPORT bool qEnvironmentVariableIsSet(const char *varName) noexcept
QTextStreamManipulator qSetPadChar(QChar ch)
QTextStreamManipulator qSetFieldWidth(int width)
static GpuDescription adapterIdentifierToGpuDescription(const D3DADAPTER_IDENTIFIER9 &adapterIdentifier)
QHash< QOpenGLConfig::Gpu, QWindowsOpenGLTester::Renderers > SupportedRenderersCache
static QT_BEGIN_NAMESPACE const DWORD VENDOR_ID_AMD
static QString resolveBugListFile(const QString &fileName)
QDebug operator<<(QDebug d, const GpuDescription &gd)
const char className[16]
[1]
QFileInfo fi("c:/temp/foo")
[newstuff]
static GpuDescription detect()
static QList< GpuDescription > detectAll()
QVariant toVariant() const
QVersionNumber driverVersion
QString gpuSuitableScreen
static Gpu fromDevice(uint vendorId, uint deviceId, QVersionNumber driverVersion, const QByteArray &driverDescription)