Discussion:
[Interest] Force Qt 5.4 to use ANGLE OpenGL ES 2 implementation
Roberto Garrido Martín
2015-02-14 18:05:26 UTC
Permalink
Hi all,

We have a windows Qt desktop app that links to a rendering library based on
OpenGL ES 2.0.
We want to assure that the app will run on as much as devices as possible,
so we think that using ANGLE is a good idea.

My question is: is there anything we can do to force our Qt 5.4 app to use
ANGLE instead of the fallback sequence [OpenGL > 2.0 Driver] -> [ANGLE] ->
[Software rasterizer] described here [
http://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/
]?

We have seleted the Qt-ANGLE Kit from QtCreator to build our app. It
compiles, links, and deploys fine. I want to test the initialization
sequence of the render library when ANGLE is used (we have to check the
presence of some GL ES Extensions, and those have to be checked with EGL),
but my dev machine has an OpenGL 4.4 capable Nvidia Graphics card, and
apparently the fallback sequence is being launched, and Qt selects my
OpenGL driver by default, instead of ANGLE.

I have explicitly linked to QtANGLE’s implementation with -llibGLESv2
-llibEGL, and used the QtANGLE’s OpenGL ES headers.

Here the startup trace with GL debugging enabled (env variable
QT_LOGGING_RULES = qt.qpa.gl=true):

----------------------------------------------BEGIN
TRACE---------------------------------------
qt.qpa.gl: OpenGL 2.0 entry points available
qt.qpa.gl: Qt: Using WGL and OpenGL from "opengl32.dll"
qt.qpa.gl: QOpenGLStaticContext::create OpenGL: "NVIDIA
Corporation","GeForce GTX 570/PCIe/SSE2" default ContextFormat: v4.5
profile: 0 options: QFlags(0x4
),SampleBuffers, Extension-API present
Extensions: 309
qt.qpa.gl: QWindowsIntegration::createPlatformOpenGLContext
QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24,
redBufferSize -1, greenBuffer
Size -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8,
samples -1, swapBehavior 2, swapInterval 1, profile 0)
qt.qpa.gl: "ARB::choosePixelFormat Attributes: 0x2003 , 0x2027 , 0x2010 ,
0x1 , 0x2001 , 0x1 , 0x2014 , 0x18 , 0x2011 , 0x1 , 0x2022 , 0x18 , 0x2013
, 0x
202b , 0x201b , 0x8 , 0x2023 , 0x8 , 0x2041 , 0x0 ,
obtained px # 10 of 2
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW
PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0
cColorBits=32 cRedBit
s=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0
cDepthBits=24 cStencilBits=8 cAuxBuffers=4 iLayerType=0 cAlphaBits=8
cAlphaShift=24 cA
ccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16
cAccumAlphaBits=16"
qt.qpa.gl: ARB::createContext Creating context version 2 . 0 3 attributes
qt.qpa.gl: QWindowsGLContext::QWindowsGLContext 0x1179548 ARB requested:
QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24,
redBufferSize
-1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize -1,
stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
obtained # 10 ARB QSurfaceFormat(version 4.5, options QFlags(0x4),
depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize 8,
alphaBuffe
rSize 8, stencilBufferSize 8, samples 0, swapBehavior 2, swapInterval 1,
profile 2)
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW
PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0
cColorBits=32 cRedBit
s=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0
cDepthBits=24 cStencilBits=8 cAuxBuffers=4 iLayerType=0 cAlphaBits=8
cAlphaShift=24 cA
ccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16
cAccumAlphaBits=16 swap interval: 1
default: ContextFormat: v4.5 profile: 0 options: QFlags(0x4)
HGLRC=0x30000

----------------------------------------------END
TRACE---------------------------------------

So it seems that OpenGL ES 2.0 and EGL are not being used. But, if we put
these lines in the very beginning of the main function of the app:

QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGLES);
QSurfaceFormat::setDefaultFormat(format);

Then we have the following output:

----------------------------------------------BEGIN
TRACE---------------------------------------
qt.qpa.gl: OpenGL 2.0 entry points available
qt.qpa.gl: Qt: Using WGL and OpenGL from "opengl32.dll"
qt.qpa.gl: QOpenGLStaticContext::create OpenGL: "NVIDIA
Corporation","GeForce GTX 570/PCIe/SSE2" default ContextFormat: v4.5
profile: 0 options: QFlags(0x4
),SampleBuffers, Extension-API present
Extensions: 309
qt.qpa.gl: QWindowsIntegration::createPlatformOpenGLContext
QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24,
redBufferSize -1, greenBuffer
Size -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8,
samples -1, swapBehavior 2, swapInterval 1, profile 0)
Failed to create EGL context for format QSurfaceFormat(version 2.0, options
QFlags(), depthBufferSize 24, redBufferSize -1, greenBufferSize -1,
blueBufferS
ize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1, swapBehavior
2, swapInterval 1, profile 0) .
This is most likely caused by not having the necessary graphics drivers
installed.

Install a driver providing OpenGL 2.0 or higher, or, if this is not
possible, make sure the ANGLE Open GL ES 2.0 emulation libraries
(libEGL.dll, libGLESv2
.dll and d3dcompiler_*.dll) are available in the application executable's
directory or in a location listed in PATH.
----------------------------------------------END
TRACE---------------------------------------

In this case, in spite of saying that WGL and OpenGL from “opengl32.dll”
are being used by Qt, it tries to create an EGL context, and it fails.
libEGL, libGLES and d3d_compiler dlls are in the same directory as the
executable.

Any ideas on how can we force GLES 2 ANGLE implementation?
Thanks,
Robert.
--
Website: http://robertogarrido.com
Twitter: http://twitter.com/che1404
LinkedIn: http://es.linkedin.com/in/robertogarrido/en
Andrew Knight
2015-02-15 09:08:43 UTC
Permalink
Hi,
Post by Roberto Garrido Martín
Hi all,
We have a windows Qt desktop app that links to a rendering library based
on OpenGL ES 2.0.
We want to assure that the app will run on as much as devices as
possible, so we think that using ANGLE is a good idea.
My question is: is there anything we can do to force our Qt 5.4 app to
use ANGLE instead of the fallback sequence [OpenGL > 2.0 Driver] ->
[ANGLE] -> [Software rasterizer] described here
[http://blog.qt.io/blog/2014/11/27/qt-weekly-21-dynamic-opengl-implementation-loading-in-qt-5-4/]?
FTA, use the QT_OPENGL environment variable (set QT_OPENGL=angle) or the
application attribute
(QCoreApplication::setAttribute(Qt::AA_UseOpenGLES)). From your results
below, it doesn't appear you've tried either.

Finally, you can also rebuild Qt with the -opengl es2 switch (which is
on by default anyway). This will disable the dynamic GL feature and only
use ANGLE.
Post by Roberto Garrido Martín
We have seleted the Qt-ANGLE Kit from QtCreator to build our app. It
compiles, links, and deploys fine. I want to test the initialization
sequence of the render library when ANGLE is used (we have to check the
presence of some GL ES Extensions, and those have to be checked with
EGL), but my dev machine has an OpenGL 4.4 capable Nvidia Graphics card,
and apparently the fallback sequence is being launched, and Qt selects
my OpenGL driver by default, instead of ANGLE.
I have explicitly linked to QtANGLE’s implementation with -llibGLESv2
-llibEGL, and used the QtANGLE’s OpenGL ES headers.
Here the startup trace with GL debugging enabled (env variable
----------------------------------------------BEGIN
TRACE---------------------------------------
qt.qpa.gl <http://qt.qpa.gl>: OpenGL 2.0 entry points available
qt.qpa.gl <http://qt.qpa.gl>: Qt: Using WGL and OpenGL from "opengl32.dll"
v4.5 profile: 0 options: QFlags(0x4
),SampleBuffers, Extension-API present
Extensions: 309
QWindowsIntegration::createPlatformOpenGLContext QSurfaceFormat(version
2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBuffer
Size -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8,
samples -1, swapBehavior 2, swapInterval 1, profile 0)
0x2003 , 0x2027 , 0x2010 , 0x1 , 0x2001 , 0x1 , 0x2014 , 0x18 , 0x2011
, 0x1 , 0x2022 , 0x18 , 0x2013 , 0x
202b , 0x201b , 0x8 , 0x2023 , 0x8 , 0x2041 , 0x0 ,
obtained px # 10 of 2
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW
PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0
cColorBits=32 cRedBit
s=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0
cDepthBits=24 cStencilBits=8 cAuxBuffers=4 iLayerType=0 cAlphaBits=8
cAlphaShift=24 cA
ccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16
cAccumAlphaBits=16"
qt.qpa.gl <http://qt.qpa.gl>: ARB::createContext Creating context
version 2 . 0 3 attributes
qt.qpa.gl <http://qt.qpa.gl>: QWindowsGLContext::QWindowsGLContext
0x1179548 ARB requested: QSurfaceFormat(version 2.0, options QFlags(),
depthBufferSize 24, redBufferSize
-1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize -1,
stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
obtained # 10 ARB QSurfaceFormat(version 4.5, options QFlags(0x4),
depthBufferSize 24, redBufferSize 8, greenBufferSize 8, blueBufferSize
8, alphaBuffe
rSize 8, stencilBufferSize 8, samples 0, swapBehavior 2, swapInterval 1,
profile 2)
PIXELFORMATDESCRIPTOR dwFlags=0x8225 PFD_DRAW_TO_WINDOW
PFD_SUPPORT_OPENGL PFD_SUPPORT_COMPOSITION PFD_DOUBLEBUFFER iPixelType=0
cColorBits=32 cRedBit
s=8 cRedShift=16 cGreenBits=8 cGreenShift=8 cBlueBits=8 cBlueShift=0
cDepthBits=24 cStencilBits=8 cAuxBuffers=4 iLayerType=0 cAlphaBits=8
cAlphaShift=24 cA
ccumBits=64 cAccumRedBits=16 cAccumGreenBits=16 cAccumBlueBits=16
cAccumAlphaBits=16 swap interval: 1
default: ContextFormat: v4.5 profile: 0 options: QFlags(0x4)
HGLRC=0x30000
----------------------------------------------END
TRACE---------------------------------------
So it seems that OpenGL ES 2.0 and EGL are not being used. But, if we
QSurfaceFormat format;
format.setRenderableType(QSurfaceFormat::OpenGLES);
QSurfaceFormat::setDefaultFormat(format);
----------------------------------------------BEGIN
TRACE---------------------------------------
qt.qpa.gl <http://qt.qpa.gl>: OpenGL 2.0 entry points available
qt.qpa.gl <http://qt.qpa.gl>: Qt: Using WGL and OpenGL from "opengl32.dll"
v4.5 profile: 0 options: QFlags(0x4
),SampleBuffers, Extension-API present
Extensions: 309
QWindowsIntegration::createPlatformOpenGLContext QSurfaceFormat(version
2.0, options QFlags(), depthBufferSize 24, redBufferSize -1, greenBuffer
Size -1, blueBufferSize -1, alphaBufferSize -1, stencilBufferSize 8,
samples -1, swapBehavior 2, swapInterval 1, profile 0)
Failed to create EGL context for format QSurfaceFormat(version 2.0,
options QFlags(), depthBufferSize 24, redBufferSize -1, greenBufferSize
-1, blueBufferS
ize -1, alphaBufferSize -1, stencilBufferSize 8, samples -1,
swapBehavior 2, swapInterval 1, profile 0) .
This is most likely caused by not having the necessary graphics drivers
installed.
Install a driver providing OpenGL 2.0 or higher, or, if this is not
possible, make sure the ANGLE Open GL ES 2.0 emulation libraries
(libEGL.dll, libGLESv2
.dll and d3dcompiler_*.dll) are available in the application
executable's directory or in a location listed in PATH.
----------------------------------------------END
TRACE---------------------------------------
In this case, in spite of saying that WGL and OpenGL from “opengl32.dll”
are being used by Qt, it tries to create an EGL context, and it fails.
libEGL, libGLES and d3d_compiler dlls are in the same directory as the
executable.
Any ideas on how can we force GLES 2 ANGLE implementation?
Thanks,
Robert.
--
Website: http://robertogarrido.com
Twitter: http://twitter.com/che1404
LinkedIn: http://es.linkedin.com/in/robertogarrido/en
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Cheers,
Andrew
Roberto Garrido Martín
2015-02-15 10:55:56 UTC
Permalink
Hi,
Post by Andrew Knight
FTA, use the QT_OPENGL environment variable (set QT_OPENGL=angle) or the
application attribute (QCoreApplication::setAttribute(Qt::AA_UseOpenGLES)).
From your results below, it doesn't appear you've tried either.
Setting QCoreApplication::setAttribute(Qt::AA_UseOpenGLES) actually worked,
thanks!
Here the debug message:

qt.qpa.gl: Qt: Using EGL from libEGLd.dll
qt.qpa.gl: Qt: Using OpenGL ES 2.0 from libGLESv2d.dll
qt.qpa.gl: QWindowsEGLStaticContext::create Created EGL display 0x4dc49c8 v
1 . 4
qt.qpa.gl: QWindowsIntegration::createPlatformOpenGLContext
QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24,
redBufferSize -1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize
-1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1,
profile 0)


Now I'm having another error. We are using Glew-1.12.0 in order to load the
non-Core OpenGL 1.1 functions on windows. In order to initialize
Glew-1.12.0, glewInit() must be called first. it returns GLEW_OK when the
initialization was successfull. It does work with Desktop OpenGL , but with
GLES it returns "Missing GL Version".

Besides, functions like glGetIntegerv (GL_MAX_TEXTURE_SIZE,
&maxTextureSize), are returning garbage values. It's like the OpenGL ES
context was not created properly, so the the OpenGL commands don't work.

I have called QOpenGLContext::currentContext()->makeCurrent(_appWindow);
before our rendering library initialization, but the result is the same.

Any ideas?

Cheers,
Robert.
Andrew Knight
2015-02-15 11:59:58 UTC
Permalink
Hi,
Post by Andrew Knight
Hi,
FTA, use the QT_OPENGL environment variable (set QT_OPENGL=angle) or
the application attribute
(QCoreApplication::__setAttribute(Qt::AA___UseOpenGLES)). From your
results below, it doesn't appear you've tried either.
Setting QCoreApplication::__setAttribute(Qt::AA___UseOpenGLES) actually
worked, thanks!
qt.qpa.gl <http://qt.qpa.gl>: Qt: Using EGL from libEGLd.dll
qt.qpa.gl <http://qt.qpa.gl>: Qt: Using OpenGL ES 2.0 from libGLESv2d.dll
qt.qpa.gl <http://qt.qpa.gl>: QWindowsEGLStaticContext::create Created
EGL display 0x4dc49c8 v 1 . 4
QWindowsIntegration::createPlatformOpenGLContext QSurfaceFormat(version
2.0, options QFlags(), depthBufferSize 24, redBufferSize -1,
greenBufferSize -1, blueBufferSize -1, alphaBufferSize -1,
stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1, profile 0)
Looks better.
Post by Andrew Knight
Now I'm having another error. We are using Glew-1.12.0 in order to load
the non-Core OpenGL 1.1 functions on windows. In order to initialize
Glew-1.12.0, glewInit() must be called first. it returns GLEW_OK when
the initialization was successfull. It does work with Desktop OpenGL ,
but with GLES it returns "Missing GL Version".
I haven't used GLEW, but http://glew.sourceforge.net/basic.html says
that you need to create a valid OpenGL rendering context before calling
glewInit(). FWICT, GLEW only works with desktop GL, so you're not going
to have a valid desktop GL context at this point. I'm not sure what the
value of loading OpenGL 1.1 functions would be anyway, given that you
won't be able to use them with the ES 2 context (?)
Post by Andrew Knight
Besides, functions like glGetIntegerv (GL_MAX_TEXTURE_SIZE,
&maxTextureSize), are returning garbage values. It's like the OpenGL ES
context was not created properly, so the the OpenGL commands don't work.
I have called QOpenGLContext::currentContext()->makeCurrent(_appWindow);
before our rendering library initialization, but the result is the same.
Is that call ending up in ANGLE or opengl32? Check with a debugger. Also
try calling via QOpenGLFunctions, as you'll probably want to do that
anyway if you decide to support both desktop/ES later.
Post by Andrew Knight
Any ideas?
Cheers,
Robert.
Sean Harmer
2015-02-15 16:26:11 UTC
Permalink
Post by Roberto Garrido Martín
Hi,
Post by Andrew Knight
FTA, use the QT_OPENGL environment variable (set QT_OPENGL=angle) or the
application attribute
(QCoreApplication::setAttribute(Qt::AA_UseOpenGLES)).
From your results below, it doesn't appear you've tried either.
Setting QCoreApplication::setAttribute(Qt::AA_UseOpenGLES) actually worked,
thanks!
qt.qpa.gl: Qt: Using EGL from libEGLd.dll
qt.qpa.gl: Qt: Using OpenGL ES 2.0 from libGLESv2d.dll
qt.qpa.gl: QWindowsEGLStaticContext::create Created EGL display 0x4dc49c8 v
1 . 4
qt.qpa.gl: QWindowsIntegration::createPlatformOpenGLContext
QSurfaceFormat(version 2.0, options QFlags(), depthBufferSize 24,
redBufferSize -1, greenBufferSize -1, blueBufferSize -1, alphaBufferSize
-1, stencilBufferSize 8, samples -1, swapBehavior 2, swapInterval 1,
profile 0)
Now I'm having another error. We are using Glew-1.12.0 in order to load the
non-Core OpenGL 1.1 functions on windows. In order to initialize
Glew-1.12.0, glewInit() must be called first. it returns GLEW_OK when the
initialization was successfull. It does work with Desktop OpenGL , but with
GLES it returns "Missing GL Version".
Pick OpenGL ES or desktop OpenGL, not both. If you need to use the 3rd party
renderer that uses ES 2, you will need to restrict yourself to OpenGL ES 2
too.

Cheers,

Sean

--
Dr Sean Harmer | ***@kdab.com | Managing Director UK
Klarälvdalens Datakonsult AB, a KDAB Group company
Tel. Sweden (HQ) +46-563-540090, USA +1-866-777-KDAB(5322)
KDAB - Qt Experts - Platform-independent software solutions
Roberto Garrido Martín
2015-02-15 16:29:52 UTC
Permalink
Hi Sean, and Andrew.
The problem was that I was explicitly linking against OpenGL32. Now without
that explicit link, the OpenGL ES 2.0 commands are working, and returning
valid values.

Thank you very much!
Robert.

Loading...