From 6d35a27f905d18d52636100ef11210c84c80950a Mon Sep 17 00:00:00 2001 From: Xaver Hugl Date: Thu, 7 Sep 2023 15:27:03 +0200 Subject: [PATCH] libkwineffects: drop checks for GLSL and NPOT Instead, creating contexts that miss these features should fail directly, making KWin fall back to software rendering. While this commit also drops workarounds for broken drivers that do software emulation for features we need, such workarounds belong into these drivers and the user can still manually turn off compositing if needed. --- .../libkwineffects/kwinglplatformtest.cpp | 6 -- src/backends/x11/standalone/glxcontext.cpp | 6 +- src/libkwineffects/glplatform.cpp | 85 +------------------ src/libkwineffects/glplatform.h | 29 ------- src/libkwineffects/glshader.cpp | 8 -- src/libkwineffects/openglcontext.cpp | 7 ++ src/libkwineffects/openglcontext.h | 4 + .../scenes/opengl/eglcontext.cpp | 17 ++-- src/workspace.cpp | 24 +----- 9 files changed, 32 insertions(+), 154 deletions(-) diff --git a/autotests/libkwineffects/kwinglplatformtest.cpp b/autotests/libkwineffects/kwinglplatformtest.cpp index 50078ad387..79b31705e9 100644 --- a/autotests/libkwineffects/kwinglplatformtest.cpp +++ b/autotests/libkwineffects/kwinglplatformtest.cpp @@ -147,9 +147,6 @@ void GLPlatformTest::testPriorDetect() auto *gl = GLPlatform::instance(); QVERIFY(gl); QCOMPARE(gl->supports(GLFeature::LooseBinding), false); - QCOMPARE(gl->supports(GLFeature::GLSL), false); - QCOMPARE(gl->supports(GLFeature::TextureNPOT), false); - QCOMPARE(gl->supports(GLFeature::LimitedNPOT), false); QCOMPARE(gl->glVersion(), Version()); QCOMPARE(gl->glslVersion(), Version()); @@ -246,9 +243,6 @@ void GLPlatformTest::testDetect() const KConfigGroup settingsGroup = config.group("Settings"); QCOMPARE(gl->supports(GLFeature::LooseBinding), settingsGroup.readEntry("LooseBinding", false)); - QCOMPARE(gl->supports(GLFeature::GLSL), settingsGroup.readEntry("GLSL", false)); - QCOMPARE(gl->supports(GLFeature::TextureNPOT), settingsGroup.readEntry("TextureNPOT", false)); - QCOMPARE(gl->supports(GLFeature::LimitedNPOT), settingsGroup.readEntry("LimitedNPOT", false)); QCOMPARE(gl->glVersion(), readVersion(settingsGroup, "GLVersion")); QCOMPARE(gl->glslVersion(), readVersion(settingsGroup, "GLSLVersion")); diff --git a/src/backends/x11/standalone/glxcontext.cpp b/src/backends/x11/standalone/glxcontext.cpp index c3cce456c8..b73e670e5b 100644 --- a/src/backends/x11/standalone/glxcontext.cpp +++ b/src/backends/x11/standalone/glxcontext.cpp @@ -125,7 +125,11 @@ std::unique_ptr GlxContext::create(GlxBackend *backend, GLXFBConfig glXDestroyContext(backend->display(), handle); return nullptr; } - return std::make_unique(backend->display(), glxWindow, handle); + auto ret = std::make_unique(backend->display(), glxWindow, handle); + if (!ret->checkSupported()) { + return nullptr; + } + return ret; } } diff --git a/src/libkwineffects/glplatform.cpp b/src/libkwineffects/glplatform.cpp index f865e2b566..0bd66b507f 100644 --- a/src/libkwineffects/glplatform.cpp +++ b/src/libkwineffects/glplatform.cpp @@ -716,9 +716,6 @@ GLPlatform::GLPlatform() , m_chipClass(UnknownChipClass) , m_recommendedCompositor(QPainterCompositing) , m_looseBinding(false) - , m_supportsGLSL(false) - , m_textureNPOT(false) - , m_limitedNPOT(false) , m_packInvert(false) , m_virtualMachine(false) , m_preferBufferSubData(false) @@ -743,17 +740,6 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) m_mesaVersion = Version::parseString(versionTokens.at(mesaIndex + 1)); } - if (isGLES()) { - m_supportsGLSL = true; - m_textureNPOT = true; - } else { - m_supportsGLSL = (m_context->hasOpenglExtension("GL_ARB_shader_objects") - && m_context->hasOpenglExtension("GL_ARB_fragment_shader") - && m_context->hasOpenglExtension("GL_ARB_vertex_shader")); - - m_textureNPOT = m_context->hasOpenglExtension("GL_ARB_texture_non_power_of_two"); - } - if (!qEnvironmentVariableIsSet("KWIN_NO_TIMER_QUERY")) { if (isGLES()) { // 3.0 is required so query functions can be used without "EXT" suffix. @@ -764,14 +750,8 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) } } - if (m_supportsGLSL) { - // Parse the GLSL version - m_glsl_version = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); - m_glslVersion = Version::parseString(m_glsl_version); - } else { - m_glsl_version.clear(); - m_glslVersion = Version(0, 0, 0); - } + m_glsl_version = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); + m_glslVersion = Version::parseString(m_glsl_version); m_chipset = QByteArrayLiteral("Unknown"); m_preferBufferSubData = false; @@ -956,22 +936,6 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) // Driver/GPU specific features // ==================================================== if (isRadeon()) { - // R200 technically has a programmable pipeline, but since it's SM 1.4, - // it's too limited to to be of any practical value to us. - if (m_chipClass < R300) { - m_supportsGLSL = false; - } - - m_limitedNPOT = false; - - if (m_chipClass < R600) { - if (driver() == Driver_Catalyst) { - m_textureNPOT = m_limitedNPOT = false; // Software fallback - } else if (driver() == Driver_R300G) { - m_limitedNPOT = m_textureNPOT; - } - } - if (m_chipClass < R300) { // fallback to NoCompositing for R100 and R200 m_recommendedCompositor = NoCompositing; @@ -988,10 +952,6 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) } if (isNvidia()) { - if (m_driver == Driver_NVidia && m_chipClass < NV40) { - m_supportsGLSL = false; // High likelihood of software emulation - } - if (m_driver == Driver_NVidia) { m_looseBinding = true; m_preferBufferSubData = true; @@ -1002,15 +962,9 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) } else { m_recommendedCompositor = OpenGLCompositing; } - - m_limitedNPOT = m_textureNPOT && m_chipClass < NV40; } if (isIntel()) { - if (m_chipClass < I915) { - m_supportsGLSL = false; - } - // see https://bugs.freedesktop.org/show_bug.cgi?id=80349#c1 m_looseBinding = false; @@ -1027,7 +981,6 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) if (isLima()) { m_recommendedCompositor = OpenGLCompositing; - m_supportsGLSL = true; } if (isVideoCore4()) { @@ -1051,12 +1004,9 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) if (m_driver < Driver_Llvmpipe) { // we recommend QPainter m_recommendedCompositor = QPainterCompositing; - // Software emulation does not provide GLSL - m_supportsGLSL = false; } else { // llvmpipe does support GLSL m_recommendedCompositor = OpenGLCompositing; - m_supportsGLSL = true; } } @@ -1072,7 +1022,6 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) if (m_chipClass == UnknownChipClass && m_driver == Driver_Unknown) { // we don't know the hardware. Let's be optimistic and assume OpenGL compatible hardware m_recommendedCompositor = OpenGLCompositing; - m_supportsGLSL = true; } if (isVirtualBox()) { @@ -1089,11 +1038,6 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) m_virtualMachine = true; m_recommendedCompositor = OpenGLCompositing; } - - // and force back to shader supported on gles, we wouldn't have got a context if not supported - if (isGLES()) { - m_supportsGLSL = true; - } } static void print(const QByteArray &label, QByteArrayView setting) @@ -1106,33 +1050,18 @@ void GLPlatform::printResults() const print(QByteArrayLiteral("OpenGL vendor string:"), m_context->vendor()); print(QByteArrayLiteral("OpenGL renderer string:"), m_context->renderer()); print(QByteArrayLiteral("OpenGL version string:"), m_context->openglVersionString()); - - if (m_supportsGLSL) { - print(QByteArrayLiteral("OpenGL shading language version string:"), m_glsl_version); - } - + print(QByteArrayLiteral("OpenGL shading language version string:"), m_glsl_version); print(QByteArrayLiteral("Driver:"), driverToString8(m_driver)); if (!isMesaDriver()) { print(QByteArrayLiteral("Driver version:"), m_driverVersion.toByteArray()); } - print(QByteArrayLiteral("GPU class:"), chipClassToString8(m_chipClass)); - print(QByteArrayLiteral("OpenGL version:"), m_context->openglVersion().toByteArray()); - - if (m_supportsGLSL) { - print(QByteArrayLiteral("GLSL version:"), m_glslVersion.toByteArray()); - } - + print(QByteArrayLiteral("GLSL version:"), m_glslVersion.toByteArray()); if (isMesaDriver()) { print(QByteArrayLiteral("Mesa version:"), mesaVersion().toByteArray()); } - // if (galliumVersion() > 0) - // print("Gallium version:", versionToString(m_galliumVersion)); - print(QByteArrayLiteral("Requires strict binding:"), !m_looseBinding ? QByteArrayLiteral("yes") : QByteArrayLiteral("no")); - print(QByteArrayLiteral("GLSL shaders:"), m_supportsGLSL ? QByteArrayLiteral("yes") : QByteArrayLiteral("no")); - print(QByteArrayLiteral("Texture NPOT support:"), m_textureNPOT ? (m_limitedNPOT ? QByteArrayLiteral("limited") : QByteArrayLiteral("yes")) : QByteArrayLiteral("no")); print(QByteArrayLiteral("Virtual Machine:"), m_virtualMachine ? QByteArrayLiteral("yes") : QByteArrayLiteral("no")); print(QByteArrayLiteral("Timer query support:"), m_supportsTimerQuery ? QByteArrayLiteral("yes") : QByteArrayLiteral("no")); } @@ -1142,12 +1071,6 @@ bool GLPlatform::supports(GLFeature feature) const switch (feature) { case GLFeature::LooseBinding: return m_looseBinding; - case GLFeature::GLSL: - return m_supportsGLSL; - case GLFeature::TextureNPOT: - return m_textureNPOT; - case GLFeature::LimitedNPOT: - return m_limitedNPOT; case GLFeature::PackInvert: return m_packInvert; case GLFeature::TimerQuery: diff --git a/src/libkwineffects/glplatform.h b/src/libkwineffects/glplatform.h index 21bf1c57e1..f07528a081 100644 --- a/src/libkwineffects/glplatform.h +++ b/src/libkwineffects/glplatform.h @@ -32,32 +32,6 @@ enum class GLFeature { */ LooseBinding, - /** - * Set if the driver supports the following extensions: - * - GL_ARB_shader_objects - * - GL_ARB_fragment_shader - * - GL_ARB_vertex_shader - * - GL_ARB_shading_language_100 - */ - GLSL, - - /** - * Set when the driver supports GL_ARB_texture_non_power_of_two. - */ - TextureNPOT, - - /** - * If set, the driver supports GL_ARB_texture_non_power_of_two with the - * GL_ARB_texture_rectangle limitations. - * - * This means no support for mipmap filters, and that only the following - * wrap modes are supported: - * - GL_CLAMP - * - GL_CLAMP_TO_EDGE - * - GL_CLAMP_TO_BORDER - */ - LimitedNPOT, - /** * Set if the extension GL_MESA_pack_invert is present */ @@ -421,9 +395,6 @@ private: Version m_driverVersion; Version m_galliumVersion; bool m_looseBinding : 1; - bool m_supportsGLSL : 1; - bool m_textureNPOT : 1; - bool m_limitedNPOT : 1; bool m_packInvert : 1; bool m_supportsTimerQuery : 1; bool m_virtualMachine : 1; diff --git a/src/libkwineffects/glshader.cpp b/src/libkwineffects/glshader.cpp index b4ab79a4a1..665ffdfacc 100644 --- a/src/libkwineffects/glshader.cpp +++ b/src/libkwineffects/glshader.cpp @@ -147,14 +147,6 @@ bool GLShader::compile(GLuint program, GLenum shaderType, const QByteArray &sour bool GLShader::load(const QByteArray &vertexSource, const QByteArray &fragmentSource) { - // Make sure shaders are actually supported - if (!(GLPlatform::instance()->supports(GLFeature::GLSL) && - // we lack shader branching for Texture2DRectangle everywhere - and it's probably not worth it - GLPlatform::instance()->supports(GLFeature::TextureNPOT))) { - qCCritical(LIBKWINGLUTILS) << "Shaders are not supported"; - return false; - } - m_valid = false; // Compile the vertex shader diff --git a/src/libkwineffects/openglcontext.cpp b/src/libkwineffects/openglcontext.cpp index 2b7fbf4104..50495c6f04 100644 --- a/src/libkwineffects/openglcontext.cpp +++ b/src/libkwineffects/openglcontext.cpp @@ -86,4 +86,11 @@ bool OpenGlContext::isSoftwareRenderer() const { return m_renderer.contains("softpipe") || m_renderer.contains("Software Rasterizer") || m_renderer.contains("llvmpipe"); } + +bool OpenGlContext::checkSupported() const +{ + const bool supportsGLSL = m_isOpenglES || (hasOpenglExtension("GL_ARB_shader_objects") && hasOpenglExtension("GL_ARB_fragment_shader") && hasOpenglExtension("GL_ARB_vertex_shader")); + const bool supportsNonPowerOfTwoTextures = m_isOpenglES || hasOpenglExtension("GL_ARB_texture_non_power_of_two"); + return supportsGLSL && supportsNonPowerOfTwoTextures; +} } diff --git a/src/libkwineffects/openglcontext.h b/src/libkwineffects/openglcontext.h index 9e92a7f03b..0dcfd47dab 100644 --- a/src/libkwineffects/openglcontext.h +++ b/src/libkwineffects/openglcontext.h @@ -34,6 +34,10 @@ public: bool isOpenglES() const; bool hasOpenglExtension(QByteArrayView name) const; bool isSoftwareRenderer() const; + /** + * checks whether or not this context supports all the features that KWin requires + */ + bool checkSupported() const; protected: const QByteArrayView m_versionString; diff --git a/src/platformsupport/scenes/opengl/eglcontext.cpp b/src/platformsupport/scenes/opengl/eglcontext.cpp index dc182715b1..b355b350e2 100644 --- a/src/platformsupport/scenes/opengl/eglcontext.cpp +++ b/src/platformsupport/scenes/opengl/eglcontext.cpp @@ -25,15 +25,18 @@ namespace KWin std::unique_ptr EglContext::create(EglDisplay *display, EGLConfig config, ::EGLContext sharedContext) { auto handle = createContext(display, config, sharedContext); - if (handle) { - if (!eglMakeCurrent(display->handle(), EGL_NO_SURFACE, EGL_NO_SURFACE, handle)) { - eglDestroyContext(display->handle(), handle); - return nullptr; - } - return std::make_unique(display, config, handle); - } else { + if (!handle) { + return nullptr; + } + if (!eglMakeCurrent(display->handle(), EGL_NO_SURFACE, EGL_NO_SURFACE, handle)) { + eglDestroyContext(display->handle(), handle); + return nullptr; + } + auto ret = std::make_unique(display, config, handle); + if (!ret->checkSupported()) { return nullptr; } + return ret; } EglContext::EglContext(EglDisplay *display, EGLConfig config, ::EGLContext context) diff --git a/src/workspace.cpp b/src/workspace.cpp index 30b7b3598f..d63565191a 100644 --- a/src/workspace.cpp +++ b/src/workspace.cpp @@ -1776,9 +1776,7 @@ QString Workspace::supportInformation() const } support.append(QStringLiteral("\n")); - if (platform->supports(GLFeature::GLSL)) { - support.append(QStringLiteral("OpenGL shading language version string: ") + QString::fromUtf8(platform->glShadingLanguageVersionString()) + QStringLiteral("\n")); - } + support.append(QStringLiteral("OpenGL shading language version string: ") + QString::fromUtf8(platform->glShadingLanguageVersionString()) + QStringLiteral("\n")); support.append(QStringLiteral("Driver: ") + GLPlatform::driverToString(platform->driver()) + QStringLiteral("\n")); if (!platform->isMesaDriver()) { @@ -1789,9 +1787,7 @@ QString Workspace::supportInformation() const support.append(QStringLiteral("OpenGL version: ") + platform->glVersion().toString() + QStringLiteral("\n")); - if (platform->supports(GLFeature::GLSL)) { - support.append(QStringLiteral("GLSL version: ") + platform->glslVersion().toString() + QStringLiteral("\n")); - } + support.append(QStringLiteral("GLSL version: ") + platform->glslVersion().toString() + QStringLiteral("\n")); if (platform->isMesaDriver()) { support.append(QStringLiteral("Mesa version: ") + platform->mesaVersion().toString() + QStringLiteral("\n")); @@ -1810,22 +1806,6 @@ QString Workspace::supportInformation() const } else { support.append(QStringLiteral("no\n")); } - support.append(QStringLiteral("GLSL shaders: ")); - if (platform->supports(GLFeature::GLSL)) { - support.append(QStringLiteral(" yes\n")); - } else { - support.append(QStringLiteral(" no\n")); - } - support.append(QStringLiteral("Texture NPOT support: ")); - if (platform->supports(GLFeature::TextureNPOT)) { - if (platform->supports(GLFeature::LimitedNPOT)) { - support.append(QStringLiteral(" limited\n")); - } else { - support.append(QStringLiteral(" yes\n")); - } - } else { - support.append(QStringLiteral(" no\n")); - } support.append(QStringLiteral("Virtual Machine: ")); if (platform->isVirtualMachine()) { support.append(QStringLiteral(" yes\n"));