From a5c8356d404540fffc55516d7aaa0a792e976fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Fri, 12 Aug 2016 09:57:41 +0200 Subject: [PATCH] [libkwineffects] Add detection code for Qualcomm Adreno to GLPlatform Summary: The Qualcom Adreno classes are recognized and a version detection workaround is added for libhybris which only announces GLES version 2 although GLES version 3 is supported. KWin at least used to work with GLES version 3 which gives us e.g. framebuffer blit. Reviewers: #kwin, bshah Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D2415 --- .../qualcomm-adreno-330-libhybris-gles-3.0 | 5 +- .../libkwineffects/kwinglplatformtest.cpp | 8 +++ libkwineffects/kwinglplatform.cpp | 69 +++++++++++++++++++ libkwineffects/kwinglplatform.h | 16 +++++ 4 files changed, 96 insertions(+), 2 deletions(-) diff --git a/autotests/libkwineffects/data/glplatform/qualcomm-adreno-330-libhybris-gles-3.0 b/autotests/libkwineffects/data/glplatform/qualcomm-adreno-330-libhybris-gles-3.0 index e20090a9ba..53790d50a5 100644 --- a/autotests/libkwineffects/data/glplatform/qualcomm-adreno-330-libhybris-gles-3.0 +++ b/autotests/libkwineffects/data/glplatform/qualcomm-adreno-330-libhybris-gles-3.0 @@ -7,9 +7,10 @@ ShadingLanguageVersion=OpenGL ES GLSL ES 3.00 [Settings] GLSL=true TextureNPOT=true -GLVersion=2,0 +GLVersion=3,0 GLSLVersion=3,0 GLES=true +Adreno=true Driver=15 -ChipClass=99999 +ChipClass=3002 Compositor=9 diff --git a/autotests/libkwineffects/kwinglplatformtest.cpp b/autotests/libkwineffects/kwinglplatformtest.cpp index 1eed96de6c..07a2ca13f5 100644 --- a/autotests/libkwineffects/kwinglplatformtest.cpp +++ b/autotests/libkwineffects/kwinglplatformtest.cpp @@ -76,6 +76,7 @@ void GLPlatformTest::testDriverToString_data() QTest::newRow("Llvmpipe") << Driver_Llvmpipe << QStringLiteral("LLVMpipe"); QTest::newRow("VirtualBox") << Driver_VirtualBox << QStringLiteral("VirtualBox (Chromium)"); QTest::newRow("VMware") << Driver_VMware << QStringLiteral("VMware (SVGA3D)"); + QTest::newRow("Qualcomm") << Driver_Qualcomm << QStringLiteral("Qualcomm"); QTest::newRow("Unknown") << Driver_Unknown << QStringLiteral("Unknown"); } @@ -114,6 +115,12 @@ void GLPlatformTest::testChipClassToString_data() QTest::newRow("IvyBridge") << IvyBridge << QStringLiteral("IvyBridge"); QTest::newRow("Haswell") << Haswell << QStringLiteral("Haswell"); QTest::newRow("UnknownIntel") << UnknownIntel << QStringLiteral("Unknown"); + QTest::newRow("Adreno1XX") << Adreno1XX << QStringLiteral("Adreno 1xx series"); + QTest::newRow("Adreno2XX") << Adreno2XX << QStringLiteral("Adreno 2xx series"); + QTest::newRow("Adreno3XX") << Adreno3XX << QStringLiteral("Adreno 3xx series"); + QTest::newRow("Adreno4XX") << Adreno4XX << QStringLiteral("Adreno 4xx series"); + QTest::newRow("Adreno5XX") << Adreno5XX << QStringLiteral("Adreno 5xx series"); + QTest::newRow("UnknwonAdreno") << UnknownAdreno << QStringLiteral("Unknown"); QTest::newRow("UnknownChipClass") << UnknownChipClass << QStringLiteral("Unknown"); } @@ -257,6 +264,7 @@ void GLPlatformTest::testDetect() QCOMPARE(gl->isIntel(), settingsGroup.readEntry("Intel", false)); QCOMPARE(gl->isVirtualBox(), settingsGroup.readEntry("VirtualBox", false)); QCOMPARE(gl->isVMware(), settingsGroup.readEntry("VMware", false)); + QCOMPARE(gl->isAdreno(), settingsGroup.readEntry("Adreno", false)); QCOMPARE(gl->isSoftwareEmulation(), settingsGroup.readEntry("SoftwareEmulation", false)); QCOMPARE(gl->isVirtualMachine(), settingsGroup.readEntry("VirtualMachine", false)); diff --git a/libkwineffects/kwinglplatform.cpp b/libkwineffects/kwinglplatform.cpp index 5cad631289..584abf8c9a 100644 --- a/libkwineffects/kwinglplatform.cpp +++ b/libkwineffects/kwinglplatform.cpp @@ -393,6 +393,37 @@ static ChipClass detectIntelClass(const QByteArray &chipset) return UnknownIntel; } +static ChipClass detectQualcommClass(const QByteArray &chipClass) +{ + if (!chipClass.contains("Adreno")) { + return UnknownChipClass; + } + const auto parts = chipClass.split(' '); + if (parts.count() < 3) { + return UnknownAdreno; + } + bool ok = false; + const int value = parts.at(2).toInt(&ok); + if (ok) { + if (value >= 100 && value < 200) { + return Adreno1XX; + } + if (value >= 200 && value < 300) { + return Adreno2XX; + } + if (value >= 300 && value < 400) { + return Adreno3XX; + } + if (value >= 400 && value < 500) { + return Adreno4XX; + } + if (value >= 500 && value < 600) { + return Adreno5XX; + } + } + return UnknownAdreno; +} + QString GLPlatform::versionToString(qint64 version) { return QString::fromLatin1(versionToString8(version)); @@ -447,6 +478,8 @@ QByteArray GLPlatform::driverToString8(Driver driver) return QByteArrayLiteral("VirtualBox (Chromium)"); case Driver_VMware: return QByteArrayLiteral("VMware (SVGA3D)"); + case Driver_Qualcomm: + return QByteArrayLiteral("Qualcomm"); default: return QByteArrayLiteral("Unknown"); @@ -505,6 +538,17 @@ QByteArray GLPlatform::chipClassToString8(ChipClass chipClass) case Haswell: return QByteArrayLiteral("Haswell"); + case Adreno1XX: + return QByteArrayLiteral("Adreno 1xx series"); + case Adreno2XX: + return QByteArrayLiteral("Adreno 2xx series"); + case Adreno3XX: + return QByteArrayLiteral("Adreno 3xx series"); + case Adreno4XX: + return QByteArrayLiteral("Adreno 4xx series"); + case Adreno5XX: + return QByteArrayLiteral("Adreno 5xx series"); + default: return QByteArrayLiteral("Unknown"); } @@ -753,6 +797,17 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) m_driverVersion = 0; } + else if (m_vendor == "Qualcomm") { + m_driver = Driver_Qualcomm; + m_chipClass = detectQualcommClass(m_renderer); + // version specific overwrite for libhybris disabling OpenGL ES 3 + if (isGLES() && m_glVersion == kVersionNumber(2, 0) && m_glslVersion >= kVersionNumber(3, 0)) { + if (m_version.contains("OpenGL ES 3.0")) { + m_glVersion = kVersionNumber(3, 0); + } + } + } + else if (m_renderer == "Software Rasterizer") { m_driver = Driver_Swrast; } @@ -862,6 +917,15 @@ void GLPlatform::detect(OpenGLPlatformInterface platformInterface) } } + if (m_driver == Driver_Qualcomm) { + if (m_chipClass == Adreno1XX) { + m_recommendedCompositor = NoCompositing; + } else { + // all other drivers support at least GLES 2 + m_recommendedCompositor = OpenGL2Compositing; + } + } + 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 = OpenGL2Compositing; @@ -1037,6 +1101,11 @@ bool GLPlatform::isSoftwareEmulation() const return m_driver == Driver_Softpipe || m_driver == Driver_Swrast || m_driver == Driver_Llvmpipe; } +bool GLPlatform::isAdreno() const +{ + return m_chipClass >= Adreno1XX && m_chipClass <= UnknownAdreno; +} + const QByteArray &GLPlatform::glRendererString() const { return m_renderer; diff --git a/libkwineffects/kwinglplatform.h b/libkwineffects/kwinglplatform.h index 35e28fb01e..62dc396992 100644 --- a/libkwineffects/kwinglplatform.h +++ b/libkwineffects/kwinglplatform.h @@ -101,6 +101,7 @@ enum Driver { Driver_Llvmpipe, Driver_VirtualBox, Driver_VMware, + Driver_Qualcomm, Driver_Unknown }; @@ -135,6 +136,15 @@ enum ChipClass { Haswell, // GL4.0 CL1.2 DX11.1 SM 5.0 2013 UnknownIntel = 2999, + // Qualcomm Adreno + // from https://en.wikipedia.org/wiki/Adreno + Adreno1XX = 3000, // GLES1.1 + Adreno2XX, // GLES2.0 DX9c + Adreno3XX, // GLES3.0 CL1.1 DX11.1 + Adreno4XX, // GLES3.1 CL1.2 DX11.2 + Adreno5XX, // GLES3.1 CL2.0 DX11.2 + UnknownAdreno = 3999, + UnknownChipClass = 99999 }; @@ -267,6 +277,12 @@ public: **/ bool isVirtualMachine() const; + /** + * @returns @c true if the GPU is a Qualcomm Adreno GPU, and false otherwise + * @since 5.8 + **/ + bool isAdreno() const; + /** * @returns the GL_VERSION string as provided by the driver. * @since 4.9