File indexing completed on 2025-03-23 11:13:57
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