Details
-
Bug
-
Resolution: Unresolved
-
P3: Somewhat important
-
None
-
5.6.2, 5.9.3
-
None
Description
MSAA doesn't seem to work right when using QOpenGLWidget on certain hardware configurations involving AMD GPUs.
On the affected machines, the widget renders as if MSAA were turned off.
There is one notable exception: immediately after the widget is resized, for the first paintGL() invocation after the resize, MSAA is working. If the contents are re-rendered after that by calling update() its back to no visible MSAA.
Currently, the only systems I have been able to reproduce this on are using mobile switchable graphics with an AMD/Intel combination. On these systems the issue only occurs if the AMD GPU is being used. I don't have access to a standalone desktop AMD GPU here at work so I can't say if only switchable implementations are affected.
Just to give an example, one affected system has the following GPU combination:
AMD Radeon R7 M350 - OpenGL Version 6.14.10.13506
Intel HD Graphics 520 - Driver Version 22.20.16.4771
Our own application that is affected is using Qt 5.6.2 but I could easily reproduce this using the hellogl2 example included with Qt and tested with Qt 5.9.3 where this issue is also present. Compiler version or debug/release configuration didn't seem to have any effect in my limited testing.
I've attached two annotated screenshots showing the issue with the hellogl2 example application.
This could potentially be the same issue as https://bugreports.qt.io/browse/QTBUG-61812
I have also found the following workaround:
QOpenGLWidget uses FBOs internally, rendering to one FBO with multisampling turned on and later blitting the FBOs contents to another one to resolve the samples.
If I use the same approch but in a slightly simplified manner, it seems to work correctly on the affected systems.
I configure QOpenGLWidget to not use multisampling and instead create my own FBO with multisampling turned on. In paintGL() render into the multisampled FBO and once done, use QOpenGLFramebufferObject::blitFramebuffer() to blit to QOpenGLWidget's internal FBO by using nullptr as the target FBO for the blit.