File indexing completed on 2024-05-19 16:34:32

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2010 Fredrik Höglund <fredrik@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #pragma once
0011 
0012 #include <kwinglobals.h>
0013 #include <kwinglutils_export.h>
0014 
0015 #include <QByteArray>
0016 #include <QSet>
0017 #include <memory>
0018 
0019 namespace KWin
0020 {
0021 // forward declare method
0022 void cleanupGL();
0023 
0024 inline qint64 kVersionNumber(qint64 major, qint64 minor, qint64 patch = 0)
0025 {
0026     return ((major & 0xffff) << 32) | ((minor & 0xffff) << 16) | (patch & 0xffff);
0027 }
0028 
0029 enum GLFeature {
0030     /**
0031      * Set when a texture bound to a pixmap uses the same storage as the pixmap,
0032      * and thus doesn't need to be rebound when the contents of the pixmap
0033      * has changed.
0034      */
0035     LooseBinding,
0036 
0037     /**
0038      * Set if the driver supports the following extensions:
0039      * - GL_ARB_shader_objects
0040      * - GL_ARB_fragment_shader
0041      * - GL_ARB_vertex_shader
0042      * - GL_ARB_shading_language_100
0043      */
0044     GLSL,
0045 
0046     /**
0047      * If set, assume the following:
0048      * - No flow control or branches
0049      * - No loops, unless the loops have a fixed iteration count and can be unrolled
0050      * - No functions, unless they can be inlined
0051      * - No indirect indexing of arrays
0052      * - No support for gl_ClipVertex or gl_FrontFacing
0053      * - No texture fetches in vertex shaders
0054      * - Max 32 texture fetches in fragment shaders
0055      * - Max 4 texture indirections
0056      */
0057     LimitedGLSL,
0058 
0059     /**
0060      * Set when the driver supports GL_ARB_texture_non_power_of_two.
0061      */
0062     TextureNPOT,
0063 
0064     /**
0065      * If set, the driver supports GL_ARB_texture_non_power_of_two with the
0066      * GL_ARB_texture_rectangle limitations.
0067      *
0068      * This means no support for mipmap filters, and that only the following
0069      * wrap modes are supported:
0070      * - GL_CLAMP
0071      * - GL_CLAMP_TO_EDGE
0072      * - GL_CLAMP_TO_BORDER
0073      */
0074     LimitedNPOT,
0075 
0076     /**
0077      * Set if the extension GL_MESA_pack_invert is present
0078      */
0079     PackInvert,
0080 };
0081 
0082 enum Driver {
0083     Driver_R100, // Technically "Radeon"
0084     Driver_R200,
0085     Driver_R300C,
0086     Driver_R300G,
0087     Driver_R600C,
0088     Driver_R600G,
0089     Driver_Nouveau,
0090     Driver_Intel,
0091     Driver_NVidia,
0092     Driver_Catalyst,
0093     Driver_Swrast,
0094     Driver_Softpipe,
0095     Driver_Llvmpipe,
0096     Driver_VirtualBox,
0097     Driver_VMware,
0098     Driver_Qualcomm,
0099     Driver_RadeonSI,
0100     Driver_Virgl,
0101     Driver_Panfrost,
0102     Driver_Lima,
0103     Driver_VC4,
0104     Driver_V3D,
0105     Driver_Unknown,
0106 };
0107 
0108 // clang-format off
0109 enum ChipClass {
0110     // Radeon
0111     R100          = 0,      // GL1.3         DX7                   2000
0112     R200,                   // GL1.4         DX8.1     SM 1.4      2001
0113     R300,                   // GL2.0         DX9       SM 2.0      2002
0114     R400,                   // GL2.0         DX9b      SM 2.0b     2004
0115     R500,                   // GL2.0         DX9c      SM 3.0      2005
0116     R600,                   // GL3.3         DX10      SM 4.0      2006
0117     R700,                   // GL3.3         DX10.1    SM 4.1      2008
0118     Evergreen,              // GL4.0  CL1.0  DX11      SM 5.0      2009
0119     NorthernIslands,        // GL4.0  CL1.1  DX11      SM 5.0      2010
0120     SouthernIslands,        // GL4.5  CL1.2  DX11.1    SM 5.1      2012
0121     SeaIslands,             // GL4.5  CL2.0  DX12      SM 6.0      2013
0122     VolcanicIslands,        // GL4.5  CL2.0  DX12      SM 6.0      2015
0123     ArcticIslands,          // GL4.5  CL2.0  DX12      SM 6.0      2016
0124     Vega,                   // GL4.6  CL2.0  DX12      SM 6.0      2017
0125     Navi,                   // GL4.6  CL2.0  DX12.1    SM 6.4      2019
0126     UnknownRadeon = 999,
0127 
0128     // NVIDIA
0129     NV10          = 1000,   // GL1.2         DX7                   1999
0130     NV20,                   // GL1.3         DX8       SM 1.1      2001
0131     NV30,                   // GL1.5         DX9a      SM 2.0      2003
0132     NV40,                   // GL2.1         DX9c      SM 3.0      2004
0133     G80,                    // GL3.3         DX10      SM 4.0      2006
0134     GF100,                  // GL4.1  CL1.1  DX11      SM 5.0      2010
0135     UnknownNVidia = 1999,
0136 
0137     // Intel
0138     I8XX          = 2000,   //       GL1.3         DX7                   2001
0139     I915,                   //       GL1.4/1.5     DX9/DX9c  SM 2.0      2004
0140     I965,                   //       GL2.0/2.1     DX9/DX10  SM 3.0/4.0  2006
0141     SandyBridge,            // Gen6  GL3.1  CL1.1  DX10.1    SM 4.0      2010
0142     IvyBridge,              // Gen7  GL4.0  CL1.1  DX11      SM 5.0      2012
0143     Haswell,                // Gen7  GL4.0  CL1.2  DX11.1    SM 5.0      2013
0144     BayTrail,               // Gen7  GL4.0  CL1.2  DX11.1    SM 5.0      2013
0145     Cherryview,             // Gen8  GL4.0  CL1.2  DX11.2    SM 5.0      2013
0146     Broadwell,              // Gen8  GL4.4  CL2.0  DX11.2    SM 5.0      2014
0147     ApolloLake,             // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2016
0148     Skylake,                // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2015
0149     GeminiLake,             // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2017
0150     KabyLake,               // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2017
0151     CoffeeLake,             // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2018
0152     WhiskeyLake,            // Gen9  GL4.6  GL3.0  DX12      SM 6.0      2018
0153     CometLake,              // Gen9  GL4.6  GL3.0  DX12      SM 6.0      2019
0154     CannonLake,             // Gen10 GL4.6  GL3.0  DX12      SM 6.0      2018
0155     IceLake,                // Gen11 GL4.6  CL3.0  DX12.1    SM 6.0      2019
0156     TigerLake,              // Gen12 GL4.6  CL3.0  DX12.1    SM 6.0      2020
0157     UnknownIntel  = 2999,
0158 
0159     // Qualcomm Adreno
0160     // from https://en.wikipedia.org/wiki/Adreno
0161     Adreno1XX     = 3000,   // GLES1.1
0162     Adreno2XX,              // GLES2.0       DX9c
0163     Adreno3XX,              // GLES3.0 CL1.1 DX11.1
0164     Adreno4XX,              // GLES3.1 CL1.2 DX11.2
0165     Adreno5XX,              // GLES3.1 CL2.0 DX11.2
0166     UnknownAdreno = 3999,
0167 
0168     // Panfrost Mali
0169     // from https://docs.mesa3d.org/drivers/panfrost.html
0170     MaliT7XX      = 4000,   // GLES2.0/GLES3.0
0171     MaliT8XX,               // GLES3.0
0172     MaliGXX,                // GLES3.0
0173     UnknownPanfrost = 4999,
0174 
0175     // Lima Mali
0176     // from https://docs.mesa3d.org/drivers/lima.html
0177     Mali400       = 5000,
0178     Mali450,
0179     Mali470,
0180     UnknownLima = 5999,
0181 
0182     // Broadcom VideoCore IV (e.g. Raspberry Pi 0 to 3), GLES 2.0/2.1 with caveats
0183     VC4_2_1       = 6000, // Found in Raspberry Pi 3B+
0184     UnknownVideoCore4 = 6999,
0185 
0186     // Broadcom VideoCore 3D (e.g. Raspberry Pi 4, Raspberry Pi 400)
0187     V3D_4_2       = 7000, // Found in Raspberry Pi 400
0188     UnknownVideoCore3D = 7999,
0189 
0190     UnknownChipClass = 99999,
0191 };
0192 // clang-format on
0193 
0194 class KWINGLUTILS_EXPORT GLPlatform
0195 {
0196 public:
0197     ~GLPlatform();
0198 
0199     /**
0200      * Runs the detection code using the current OpenGL context.
0201      */
0202     void detect(OpenGLPlatformInterface platformInterface);
0203 
0204     /**
0205      * Prints the results of the detection code.
0206      */
0207     void printResults() const;
0208 
0209     /**
0210      * Returns a pointer to the GLPlatform instance.
0211      */
0212     static GLPlatform *instance();
0213 
0214     /**
0215      * Returns true if the driver support the given feature, and false otherwise.
0216      */
0217     bool supports(GLFeature feature) const;
0218 
0219     /**
0220      * Returns the OpenGL version.
0221      */
0222     qint64 glVersion() const;
0223 
0224     /**
0225      * Returns the GLSL version if the driver supports GLSL, and 0 otherwise.
0226      */
0227     qint64 glslVersion() const;
0228 
0229     /**
0230      * Returns the Mesa version if the driver is a Mesa driver, and 0 otherwise.
0231      */
0232     qint64 mesaVersion() const;
0233 
0234     /**
0235      * Returns the Gallium version if the driver is a Gallium driver, and 0 otherwise.
0236      */
0237     qint64 galliumVersion() const;
0238 
0239     /**
0240      * Returns the X server version.
0241      *
0242      * Note that the version number changed from 7.2 to 1.3 in the first release
0243      * following the doupling of the X server from the katamari.
0244      *
0245      * For non X.org servers, this method returns 0.
0246      */
0247     qint64 serverVersion() const;
0248 
0249     /**
0250      * Returns the Linux kernel version.
0251      *
0252      * If the kernel is not a Linux kernel, this method returns 0.
0253      */
0254     qint64 kernelVersion() const;
0255 
0256     /**
0257      * Returns the driver version.
0258      *
0259      * For Mesa drivers, this is the same as the Mesa version number.
0260      */
0261     qint64 driverVersion() const;
0262 
0263     /**
0264      * Returns the driver.
0265      */
0266     Driver driver() const;
0267 
0268     /**
0269      * Returns the chip class.
0270      */
0271     ChipClass chipClass() const;
0272 
0273     /**
0274      * Returns true if the driver is a Mesa driver, and false otherwise.
0275      */
0276     bool isMesaDriver() const;
0277 
0278     /**
0279      * Returns true if the driver is a Gallium driver, and false otherwise.
0280      */
0281     bool isGalliumDriver() const;
0282 
0283     /**
0284      * Returns true if the GPU is a Radeon GPU, and false otherwise.
0285      */
0286     bool isRadeon() const;
0287 
0288     /**
0289      * Returns true if the GPU is an NVIDIA GPU, and false otherwise.
0290      */
0291     bool isNvidia() const;
0292 
0293     /**
0294      * Returns true if the GPU is an Intel GPU, and false otherwise.
0295      */
0296     bool isIntel() const;
0297 
0298     /**
0299      * @returns @c true if the "GPU" is a VirtualBox GPU, and @c false otherwise.
0300      * @since 4.10
0301      */
0302     bool isVirtualBox() const;
0303 
0304     /**
0305      * @returns @c true if the "GPU" is a VMWare GPU, and @c false otherwise.
0306      * @since 4.10
0307      */
0308     bool isVMware() const;
0309 
0310     /**
0311      * @returns @c true if OpenGL is emulated in software.
0312      * @since 4.7
0313      */
0314     bool isSoftwareEmulation() const;
0315 
0316     /**
0317      * @returns @c true if the driver is known to be from a virtual machine.
0318      * @since 4.10
0319      */
0320     bool isVirtualMachine() const;
0321 
0322     /**
0323      * @returns @c true if the GPU is a Qualcomm Adreno GPU, and false otherwise
0324      * @since 5.8
0325      */
0326     bool isAdreno() const;
0327 
0328     /**
0329      * @returns @c true if the "GPU" is a virtio-gpu (Qemu/KVM)
0330      * @since 5.18
0331      **/
0332     bool isVirgl() const;
0333 
0334     /**
0335      * @returns @c true if the "GPU" is a Panfrost Mali GPU
0336      * @since 5.21.5
0337      **/
0338     bool isPanfrost() const;
0339 
0340      /**
0341      * @returns @c true if the GPU is a Mali GPU supported by the Lima driver (Mali 400, 450)
0342      * @since 5.27.1
0343      **/
0344     bool isLima() const;
0345 
0346     /**
0347      * @returns @c true if the GPU is a Broadcom VideoCore IV (e.g. Raspberry Pi 0 to 3)
0348      * @since 5.27.1
0349      **/
0350     bool isVideoCore4() const;
0351 
0352     /**
0353      * @returns @c true if the GPU is a Broadcom VideoCore 3D (e.g. Raspberry Pi 4, 400)
0354      * @since 5.27.1
0355      **/
0356     bool isVideoCore3D() const;
0357 
0358     /**
0359      * @returns the GL_VERSION string as provided by the driver.
0360      * @since 4.9
0361      */
0362     const QByteArray &glVersionString() const;
0363     /**
0364      * @returns the GL_RENDERER string as provided by the driver.
0365      * @since 4.9
0366      */
0367     const QByteArray &glRendererString() const;
0368     /**
0369      * @returns the GL_VENDOR string as provided by the driver.
0370      * @since 4.9
0371      */
0372     const QByteArray &glVendorString() const;
0373     /**
0374      * @returns the GL_SHADING_LANGUAGE_VERSION string as provided by the driver.
0375      * If the driver does not support the OpenGL Shading Language a null bytearray is returned.
0376      * @since 4.9
0377      */
0378     const QByteArray &glShadingLanguageVersionString() const;
0379     /**
0380      * @returns Whether the driver supports loose texture binding.
0381      * @since 4.9
0382      */
0383     bool isLooseBinding() const;
0384     /**
0385      * @returns Whether OpenGL ES is used
0386      */
0387     bool isGLES() const;
0388 
0389     /**
0390      * @returns The CompositingType recommended by the driver.
0391      * @since 4.10
0392      */
0393     CompositingType recommendedCompositor() const;
0394 
0395     /**
0396      * Returns true if glMapBufferRange() is likely to perform worse than glBufferSubData()
0397      * when updating an unused range of a buffer object, and false otherwise.
0398      *
0399      * @since 4.11
0400      */
0401     bool preferBufferSubData() const;
0402 
0403     /**
0404      * @returns The OpenGLPlatformInterface currently used
0405      * @since 5.0
0406      */
0407     OpenGLPlatformInterface platformInterface() const;
0408 
0409     /**
0410      * @returns a human readable form of the @p version as a QString.
0411      * @since 4.9
0412      * @see glVersion
0413      * @see glslVersion
0414      * @see driverVersion
0415      * @see mesaVersion
0416      * @see galliumVersion
0417      * @see kernelVersion
0418      * @see serverVersion
0419      */
0420     static QString versionToString(qint64 version);
0421     /**
0422      * @returns a human readable form of the @p version as a QByteArray.
0423      * @since 5.5
0424      * @see glVersion
0425      * @see glslVersion
0426      * @see driverVersion
0427      * @see mesaVersion
0428      * @see galliumVersion
0429      * @see kernelVersion
0430      * @see serverVersion
0431      */
0432     static QByteArray versionToString8(qint64 version);
0433 
0434     /**
0435      * @returns a human readable form for the @p driver as a QString.
0436      * @since 4.9
0437      * @see driver
0438      */
0439     static QString driverToString(Driver driver);
0440     /**
0441      * @returns a human readable form for the @p driver as a QByteArray.
0442      * @since 5.5
0443      * @see driver
0444      */
0445     static QByteArray driverToString8(Driver driver);
0446 
0447     /**
0448      * @returns a human readable form for the @p chipClass as a QString.
0449      * @since 4.9
0450      * @see chipClass
0451      */
0452     static QString chipClassToString(ChipClass chipClass);
0453     /**
0454      * @returns a human readable form for the @p chipClass as a QByteArray.
0455      * @since 5.5
0456      * @see chipClass
0457      */
0458     static QByteArray chipClassToString8(ChipClass chipClass);
0459 
0460 private:
0461     GLPlatform();
0462     friend void KWin::cleanupGL();
0463     static void cleanup();
0464 
0465 private:
0466     QByteArray m_renderer;
0467     QByteArray m_vendor;
0468     QByteArray m_version;
0469     QByteArray m_glsl_version;
0470     QByteArray m_chipset;
0471     QSet<QByteArray> m_extensions;
0472     Driver m_driver;
0473     ChipClass m_chipClass;
0474     CompositingType m_recommendedCompositor;
0475     qint64 m_glVersion;
0476     qint64 m_glslVersion;
0477     qint64 m_mesaVersion;
0478     qint64 m_driverVersion;
0479     qint64 m_galliumVersion;
0480     qint64 m_serverVersion;
0481     qint64 m_kernelVersion;
0482     bool m_looseBinding : 1;
0483     bool m_supportsGLSL : 1;
0484     bool m_limitedGLSL : 1;
0485     bool m_textureNPOT : 1;
0486     bool m_limitedNPOT : 1;
0487     bool m_packInvert : 1;
0488     bool m_virtualMachine : 1;
0489     bool m_preferBufferSubData : 1;
0490     OpenGLPlatformInterface m_platformInterface;
0491     bool m_gles : 1;
0492     static std::unique_ptr<GLPlatform> s_platform;
0493 };
0494 
0495 inline GLPlatform *GLPlatform::instance()
0496 {
0497     if (!s_platform) {
0498         s_platform.reset(new GLPlatform());
0499     }
0500     return s_platform.get();
0501 }
0502 
0503 } // namespace KWin