File indexing completed on 2024-05-19 05:31:54

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 "effect/globals.h"
0013 #include "openglcontext.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 class Version;
0025 
0026 enum class GLFeature {
0027     /**
0028      * Set when a texture bound to a pixmap uses the same storage as the pixmap,
0029      * and thus doesn't need to be rebound when the contents of the pixmap
0030      * has changed.
0031      */
0032     LooseBinding,
0033 
0034     /**
0035      * Set if the extension GL_MESA_pack_invert is present
0036      */
0037     PackInvert,
0038 
0039     /**
0040      * Set if the driver supports GL_ARB_timer_query extension or OpenGL 3.3.
0041      */
0042     TimerQuery,
0043 };
0044 
0045 enum Driver {
0046     Driver_R100, // Technically "Radeon"
0047     Driver_R200,
0048     Driver_R300C,
0049     Driver_R300G,
0050     Driver_R600C,
0051     Driver_R600G,
0052     Driver_Nouveau,
0053     Driver_Intel,
0054     Driver_NVidia,
0055     Driver_Catalyst,
0056     Driver_Swrast,
0057     Driver_Softpipe,
0058     Driver_Llvmpipe,
0059     Driver_VirtualBox,
0060     Driver_VMware,
0061     Driver_Qualcomm,
0062     Driver_RadeonSI,
0063     Driver_Virgl,
0064     Driver_Panfrost,
0065     Driver_Lima,
0066     Driver_VC4,
0067     Driver_V3D,
0068     Driver_Unknown,
0069 };
0070 
0071 // clang-format off
0072 enum ChipClass {
0073     // Radeon
0074     R100          = 0,      // GL1.3         DX7                   2000
0075     R200,                   // GL1.4         DX8.1     SM 1.4      2001
0076     R300,                   // GL2.0         DX9       SM 2.0      2002
0077     R400,                   // GL2.0         DX9b      SM 2.0b     2004
0078     R500,                   // GL2.0         DX9c      SM 3.0      2005
0079     R600,                   // GL3.3         DX10      SM 4.0      2006
0080     R700,                   // GL3.3         DX10.1    SM 4.1      2008
0081     Evergreen,              // GL4.0  CL1.0  DX11      SM 5.0      2009
0082     NorthernIslands,        // GL4.0  CL1.1  DX11      SM 5.0      2010
0083     SouthernIslands,        // GL4.5  CL1.2  DX11.1    SM 5.1      2012
0084     SeaIslands,             // GL4.5  CL2.0  DX12      SM 6.0      2013
0085     VolcanicIslands,        // GL4.5  CL2.0  DX12      SM 6.0      2015
0086     ArcticIslands,          // GL4.5  CL2.0  DX12      SM 6.0      2016
0087     Vega,                   // GL4.6  CL2.0  DX12      SM 6.0      2017
0088     Navi,                   // GL4.6  CL2.0  DX12.1    SM 6.4      2019
0089     UnknownRadeon = 999,
0090 
0091     // NVIDIA
0092     NV10          = 1000,   // GL1.2         DX7                   1999
0093     NV20,                   // GL1.3         DX8       SM 1.1      2001
0094     NV30,                   // GL1.5         DX9a      SM 2.0      2003
0095     NV40,                   // GL2.1         DX9c      SM 3.0      2004
0096     G80,                    // GL3.3         DX10      SM 4.0      2006
0097     GF100,                  // GL4.1  CL1.1  DX11      SM 5.0      2010
0098     UnknownNVidia = 1999,
0099 
0100     // Intel
0101     I8XX          = 2000,   //       GL1.3         DX7                   2001
0102     I915,                   //       GL1.4/1.5     DX9/DX9c  SM 2.0      2004
0103     I965,                   //       GL2.0/2.1     DX9/DX10  SM 3.0/4.0  2006
0104     SandyBridge,            // Gen6  GL3.1  CL1.1  DX10.1    SM 4.0      2010
0105     IvyBridge,              // Gen7  GL4.0  CL1.1  DX11      SM 5.0      2012
0106     Haswell,                // Gen7  GL4.0  CL1.2  DX11.1    SM 5.0      2013
0107     BayTrail,               // Gen7  GL4.0  CL1.2  DX11.1    SM 5.0      2013
0108     Cherryview,             // Gen8  GL4.0  CL1.2  DX11.2    SM 5.0      2013
0109     Broadwell,              // Gen8  GL4.4  CL2.0  DX11.2    SM 5.0      2014
0110     ApolloLake,             // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2016
0111     Skylake,                // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2015
0112     GeminiLake,             // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2017
0113     KabyLake,               // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2017
0114     CoffeeLake,             // Gen9  GL4.6  CL3.0  DX12      SM 6.0      2018
0115     WhiskeyLake,            // Gen9  GL4.6  GL3.0  DX12      SM 6.0      2018
0116     CometLake,              // Gen9  GL4.6  GL3.0  DX12      SM 6.0      2019
0117     CannonLake,             // Gen10 GL4.6  GL3.0  DX12      SM 6.0      2018
0118     IceLake,                // Gen11 GL4.6  CL3.0  DX12.1    SM 6.0      2019
0119     TigerLake,              // Gen12 GL4.6  CL3.0  DX12.1    SM 6.0      2020
0120     UnknownIntel  = 2999,
0121 
0122     // Qualcomm Adreno
0123     // from https://en.wikipedia.org/wiki/Adreno
0124     Adreno1XX     = 3000,   // GLES1.1
0125     Adreno2XX,              // GLES2.0       DX9c
0126     Adreno3XX,              // GLES3.0 CL1.1 DX11.1
0127     Adreno4XX,              // GLES3.1 CL1.2 DX11.2
0128     Adreno5XX,              // GLES3.1 CL2.0 DX11.2
0129     UnknownAdreno = 3999,
0130 
0131     // Panfrost Mali
0132     // from https://docs.mesa3d.org/drivers/panfrost.html
0133     MaliT7XX      = 4000,   // GLES2.0/GLES3.0
0134     MaliT8XX,               // GLES3.0
0135     MaliGXX,                // GLES3.0
0136     UnknownPanfrost = 4999,
0137 
0138     // Lima Mali
0139     // from https://docs.mesa3d.org/drivers/lima.html
0140     Mali400       = 5000,
0141     Mali450,
0142     Mali470,
0143     UnknownLima = 5999,
0144 
0145     // Broadcom VideoCore IV (e.g. Raspberry Pi 0 to 3), GLES 2.0/2.1 with caveats
0146     VC4_2_1       = 6000, // Found in Raspberry Pi 3B+
0147     UnknownVideoCore4 = 6999,
0148 
0149     // Broadcom VideoCore 3D (e.g. Raspberry Pi 4, Raspberry Pi 400)
0150     V3D_4_2       = 7000, // Found in Raspberry Pi 400
0151     UnknownVideoCore3D = 7999,
0152 
0153     UnknownChipClass = 99999,
0154 };
0155 // clang-format on
0156 
0157 class KWIN_EXPORT GLPlatform
0158 {
0159 public:
0160     ~GLPlatform();
0161 
0162     /**
0163      * Runs the detection code using the current OpenGL context.
0164      */
0165     void detect(OpenGLPlatformInterface platformInterface);
0166 
0167     /**
0168      * Prints the results of the detection code.
0169      */
0170     void printResults() const;
0171 
0172     /**
0173      * Returns a pointer to the GLPlatform instance.
0174      */
0175     static GLPlatform *instance();
0176 
0177     /**
0178      * Returns true if the driver support the given feature, and false otherwise.
0179      */
0180     bool supports(GLFeature feature) const;
0181 
0182     /**
0183      * Returns the OpenGL version.
0184      */
0185     Version glVersion() const;
0186 
0187     /**
0188      * Returns the GLSL version if the driver supports GLSL, and 0 otherwise.
0189      */
0190     Version glslVersion() const;
0191 
0192     /**
0193      * Returns the Mesa version if the driver is a Mesa driver, and 0 otherwise.
0194      */
0195     Version mesaVersion() const;
0196 
0197     /**
0198      * Returns the driver version.
0199      *
0200      * For Mesa drivers, this is the same as the Mesa version number.
0201      */
0202     Version driverVersion() const;
0203 
0204     /**
0205      * Returns the driver.
0206      */
0207     Driver driver() const;
0208 
0209     /**
0210      * Returns the chip class.
0211      */
0212     ChipClass chipClass() const;
0213 
0214     /**
0215      * Returns true if the driver is a Mesa driver, and false otherwise.
0216      */
0217     bool isMesaDriver() const;
0218 
0219     /**
0220      * Returns true if the GPU is a Radeon GPU, and false otherwise.
0221      */
0222     bool isRadeon() const;
0223 
0224     /**
0225      * Returns true if the GPU is an NVIDIA GPU, and false otherwise.
0226      */
0227     bool isNvidia() const;
0228 
0229     /**
0230      * Returns true if the GPU is an Intel GPU, and false otherwise.
0231      */
0232     bool isIntel() const;
0233 
0234     /**
0235      * @returns @c true if the "GPU" is a VirtualBox GPU, and @c false otherwise.
0236      * @since 4.10
0237      */
0238     bool isVirtualBox() const;
0239 
0240     /**
0241      * @returns @c true if the "GPU" is a VMWare GPU, and @c false otherwise.
0242      * @since 4.10
0243      */
0244     bool isVMware() const;
0245 
0246     /**
0247      * @returns @c true if OpenGL is emulated in software.
0248      * @since 4.7
0249      */
0250     bool isSoftwareEmulation() const;
0251 
0252     /**
0253      * @returns @c true if the driver is known to be from a virtual machine.
0254      * @since 4.10
0255      */
0256     bool isVirtualMachine() const;
0257 
0258     /**
0259      * @returns @c true if the GPU is a Qualcomm Adreno GPU, and false otherwise
0260      * @since 5.8
0261      */
0262     bool isAdreno() const;
0263 
0264     /**
0265      * @returns @c true if the "GPU" is a virtio-gpu (Qemu/KVM)
0266      * @since 5.18
0267      **/
0268     bool isVirgl() const;
0269 
0270     /**
0271      * @returns @c true if the "GPU" is a Panfrost Mali GPU
0272      * @since 5.21.5
0273      **/
0274     bool isPanfrost() const;
0275 
0276     /**
0277      * @returns @c true if the GPU is a Mali GPU supported by the Lima driver (Mali 400, 450)
0278      * @since 5.27.1
0279      **/
0280     bool isLima() const;
0281 
0282     /**
0283      * @returns @c true if the GPU is a Broadcom VideoCore IV (e.g. Raspberry Pi 0 to 3)
0284      * @since 5.27.1
0285      **/
0286     bool isVideoCore4() const;
0287 
0288     /**
0289      * @returns @c true if the GPU is a Broadcom VideoCore 3D (e.g. Raspberry Pi 4, 400)
0290      * @since 5.27.1
0291      **/
0292     bool isVideoCore3D() const;
0293 
0294     /**
0295      * @returns the GL_VERSION string as provided by the driver.
0296      * @since 4.9
0297      */
0298     QByteArrayView glVersionString() const;
0299     /**
0300      * @returns the GL_RENDERER string as provided by the driver.
0301      * @since 4.9
0302      */
0303     QByteArrayView glRendererString() const;
0304     /**
0305      * @returns the GL_VENDOR string as provided by the driver.
0306      * @since 4.9
0307      */
0308     QByteArrayView glVendorString() const;
0309     /**
0310      * @returns the GL_SHADING_LANGUAGE_VERSION string as provided by the driver.
0311      * If the driver does not support the OpenGL Shading Language a null bytearray is returned.
0312      * @since 4.9
0313      */
0314     QByteArrayView glShadingLanguageVersionString() const;
0315     /**
0316      * @returns Whether the driver supports loose texture binding.
0317      * @since 4.9
0318      */
0319     bool isLooseBinding() const;
0320     /**
0321      * @returns Whether OpenGL ES is used
0322      */
0323     bool isGLES() const;
0324 
0325     /**
0326      * @returns The CompositingType recommended by the driver.
0327      * @since 4.10
0328      */
0329     CompositingType recommendedCompositor() const;
0330 
0331     /**
0332      * Returns true if glMapBufferRange() is likely to perform worse than glBufferSubData()
0333      * when updating an unused range of a buffer object, and false otherwise.
0334      *
0335      * @since 4.11
0336      */
0337     bool preferBufferSubData() const;
0338 
0339     /**
0340      * @returns The OpenGLPlatformInterface currently used
0341      * @since 5.0
0342      */
0343     OpenGLPlatformInterface platformInterface() const;
0344 
0345     /**
0346      * @returns a human readable form for the @p driver as a QString.
0347      * @since 4.9
0348      * @see driver
0349      */
0350     static QString driverToString(Driver driver);
0351     /**
0352      * @returns a human readable form for the @p driver as a QByteArray.
0353      * @since 5.5
0354      * @see driver
0355      */
0356     static QByteArray driverToString8(Driver driver);
0357 
0358     /**
0359      * @returns a human readable form for the @p chipClass as a QString.
0360      * @since 4.9
0361      * @see chipClass
0362      */
0363     static QString chipClassToString(ChipClass chipClass);
0364     /**
0365      * @returns a human readable form for the @p chipClass as a QByteArray.
0366      * @since 5.5
0367      * @see chipClass
0368      */
0369     static QByteArray chipClassToString8(ChipClass chipClass);
0370 
0371 private:
0372     GLPlatform();
0373     friend void KWin::cleanupGL();
0374     static void cleanup();
0375 
0376 private:
0377     QByteArray m_glsl_version;
0378     QByteArrayView m_chipset;
0379     Driver m_driver;
0380     ChipClass m_chipClass;
0381     CompositingType m_recommendedCompositor;
0382     Version m_glslVersion;
0383     Version m_mesaVersion;
0384     Version m_driverVersion;
0385     bool m_looseBinding : 1;
0386     bool m_packInvert : 1;
0387     bool m_virtualMachine : 1;
0388     bool m_preferBufferSubData : 1;
0389     OpenGLPlatformInterface m_platformInterface;
0390     std::unique_ptr<OpenGlContext> m_context;
0391     static std::unique_ptr<GLPlatform> s_platform;
0392 };
0393 
0394 inline GLPlatform *GLPlatform::instance()
0395 {
0396     if (!s_platform) {
0397         s_platform.reset(new GLPlatform());
0398     }
0399     return s_platform.get();
0400 }
0401 
0402 } // namespace KWin