Summary: | Kwin crash with gles | ||
---|---|---|---|
Product: | [Plasma] kwin | Reporter: | Andrei Slavoiu <ansla80> |
Component: | scene-opengl | Assignee: | KWin default assignee <kwin-bugs-null> |
Status: | RESOLVED UPSTREAM | ||
Severity: | crash | CC: | stalkerg |
Priority: | NOR | Keywords: | drkonqi |
Version: | 5.7.5 | ||
Target Milestone: | --- | ||
Platform: | Gentoo Packages | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: | |||
Attachments: | epoxy_test.c |
Description
Andrei Slavoiu
2016-09-25 10:57:34 UTC
This is a driver bug. It reports OpenGL ES 3.1, but doesn't provide all functionality of it: From the debug output No provider of glFenceSync found. Requires one of: Desktop OpenGL 3.2 GL extension "GL_ARB_sync" OpenGL ES 3.0 GL extension "GL_APPLE_sync" That is not true, glFenceSync is provided by the driver and a simple test program based on the gles2 test of epoxy is able to call it without issue on the same system. The problem is with the way kwin uses epoxy. The only logical explanation is that epoxy believes the context is a Desktop OpenGL one and so it compares the version reported by the driver with 3.2 instead of 3.0 as it should. Btw, this issue is most likely not reproduce-able with an Intel card as Intel exposes OpenGL ES 3.2 Created attachment 101459 [details]
epoxy_test.c
> That is not true, glFenceSync is provided by the driver and a simple test program based on the gles2 test of epoxy is able to call it without issue on the same system.
Your test program is not creating a pure OpenGL ES context - sorry to say so. You create an OpenGL context through GLX and then the compatibility extension. But KWin is doing proper GLES using EGL and creating an OpenGL ES context directly. It's not using GLX! It is possible that the driver reports different things depending on how the context is created. Especially as the way you created it loads libgl.so instead of libgles.so.
I'm sorry, but the code you attached doesn't show that there is something wrong in KWin. Heck our code works on hardware which doesn't have OpenGL at all - e.g. the Nexus 5 or Odroid. Of course it uses proper OpenGL ES and epoxy knows it's using OpenGL ES.
I finally figured out what is going on here, it looks like epoxy is unable to distinguish between GLES and regular GL contexts created using EGL on the mesa implementation (which returns EGL_OPENGL_API when queried about the type of the current context even when it actually is a GLES one. However weird that may sound it's perfectly ok to do that per spec) because of a workaround they did for the non standards compliant PowerVR driver. The epoxy bug url: https://github.com/anholt/libepoxy/issues/25 So you may wonder why I reopened this bug again if all you can do about it is pressure epoxy to fix their own bug? Because there actually is an issue in kwin as well. When using Desktop OpenGL kwin should either request an OpenGL 3.2 context or check for the GL_ARB_sync extension in order to use glFenceSync (according to epoxy code). However, kwin will create a OpenGL 3.1 context and never check for the presence of the GL_ARB_sync extension. Now, to anyone else hitting this bug, an easy workaround for it is to remove the code under #if PLATFORM_HAS_EGL from the implementation of epoxy_is_desktop_gl, that's it. *** Bug 370264 has been marked as a duplicate of this bug. *** Thanks for the good investigation.
> When using Desktop OpenGL kwin should either request an OpenGL 3.2 context or check for the GL_ARB_sync extension in order to use glFenceSync
Normally one does not need to explicitly request OpenGL 3.2 - we get 3.2 if it's supported. But looks like we should add runtime checks to the syncing code. I'll read up on it on Monday and try to come up with a change. I understand that you could test patches, right?
Thanks Andrei, with https://github.com/yaronct/libepoxy everything works well! I just had a look at the implementation and alas our code does the correct checks - see libkwineffects/kwinglutils.cpp method GLVertexBuffer::initStatic (around like 2290) In short it's: if (GLPlatform::instance()->isGLES()) { GLVertexBufferPrivate::haveSyncFences = hasGLVersion(3, 0); } else { GLVertexBufferPrivate::haveSyncFences = hasGLVersion(3, 2) || hasGLExtension("GL_ARB_sync"); } if (GLVertexBufferPrivate::haveBufferStorage && GLVertexBufferPrivate::haveSyncFences) { if (qgetenv("KWIN_PERSISTENT_VBO") != QByteArrayLiteral("0")) { GLVertexBufferPrivate::streamingBuffer->d->persistent = true; } } Only if the d->persistent is true the glFenceSync is called. Thus the checks look correct to me. We check for either GLES 3.0, or GL 3.2 or GL_ARB_sync. Our code cannot do more. If the upstream project is broken in that regard, it's unfortunate. I guess we need to get distros to switch to the fork. Ah I'm not happy with that development. That was kind of what I was afraid of to happen when we switch to epoxy. > I guess we need to get distros to switch to the fork. I started - https://bugs.gentoo.org/show_bug.cgi?id=596548 |