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 #include "kwinglplatform.h" 0011 // include kwinglutils_funcs.h to avoid the redeclaration issues 0012 // between qopengl.h and epoxy/gl.h 0013 #include "kwinglutils_funcs.h" 0014 #include <epoxy/gl.h> 0015 0016 #include <QDebug> 0017 #include <QOpenGLContext> 0018 #include <QRegularExpression> 0019 #include <QStringList> 0020 0021 #include <sys/utsname.h> 0022 0023 #include <iomanip> 0024 #include <ios> 0025 #include <iostream> 0026 0027 namespace KWin 0028 { 0029 0030 std::unique_ptr<GLPlatform> GLPlatform::s_platform; 0031 0032 static qint64 parseVersionString(const QByteArray &version) 0033 { 0034 // Skip any leading non digit 0035 int start = 0; 0036 while (start < version.length() && !QChar::fromLatin1(version[start]).isDigit()) { 0037 start++; 0038 } 0039 0040 // Strip any non digit, non '.' characters from the end 0041 int end = start; 0042 while (end < version.length() && (version[end] == '.' || QChar::fromLatin1(version[end]).isDigit())) { 0043 end++; 0044 } 0045 0046 const QByteArray result = version.mid(start, end - start); 0047 const QList<QByteArray> tokens = result.split('.'); 0048 const qint64 major = tokens.at(0).toInt(); 0049 const qint64 minor = tokens.count() > 1 ? tokens.at(1).toInt() : 0; 0050 const qint64 patch = tokens.count() > 2 ? tokens.at(2).toInt() : 0; 0051 0052 return kVersionNumber(major, minor, patch); 0053 } 0054 0055 static qint64 getXServerVersion() 0056 { 0057 qint64 major, minor, patch; 0058 major = 0; 0059 minor = 0; 0060 patch = 0; 0061 0062 if (xcb_connection_t *c = connection()) { 0063 auto setup = xcb_get_setup(c); 0064 const QByteArray vendorName(xcb_setup_vendor(setup), xcb_setup_vendor_length(setup)); 0065 if (vendorName.contains("X.Org")) { 0066 const int release = setup->release_number; 0067 major = (release / 10000000); 0068 minor = (release / 100000) % 100; 0069 patch = (release / 1000) % 100; 0070 } 0071 } 0072 0073 return kVersionNumber(major, minor, patch); 0074 } 0075 0076 static qint64 getKernelVersion() 0077 { 0078 struct utsname name; 0079 uname(&name); 0080 0081 if (qstrcmp(name.sysname, "Linux") == 0) { 0082 return parseVersionString(name.release); 0083 } 0084 0085 return 0; 0086 } 0087 0088 // Extracts the portion of a string that matches a regular expression 0089 static QString extract(const QString &text, const QString &pattern) 0090 { 0091 const QRegularExpression regexp(pattern); 0092 const QRegularExpressionMatch match = regexp.match(text); 0093 if (!match.hasMatch()) { 0094 return QString(); 0095 } 0096 return match.captured(); 0097 } 0098 0099 static ChipClass detectRadeonClass(const QByteArray &chipset) 0100 { 0101 if (chipset.isEmpty()) { 0102 return UnknownRadeon; 0103 } 0104 0105 if (chipset.contains("R100") 0106 || chipset.contains("RV100") 0107 || chipset.contains("RS100")) { 0108 return R100; 0109 } 0110 0111 if (chipset.contains("RV200") 0112 || chipset.contains("RS200") 0113 || chipset.contains("R200") 0114 || chipset.contains("RV250") 0115 || chipset.contains("RS300") 0116 || chipset.contains("RV280")) { 0117 return R200; 0118 } 0119 0120 if (chipset.contains("R300") 0121 || chipset.contains("R350") 0122 || chipset.contains("R360") 0123 || chipset.contains("RV350") 0124 || chipset.contains("RV370") 0125 || chipset.contains("RV380")) { 0126 return R300; 0127 } 0128 0129 if (chipset.contains("R420") 0130 || chipset.contains("R423") 0131 || chipset.contains("R430") 0132 || chipset.contains("R480") 0133 || chipset.contains("R481") 0134 || chipset.contains("RV410") 0135 || chipset.contains("RS400") 0136 || chipset.contains("RC410") 0137 || chipset.contains("RS480") 0138 || chipset.contains("RS482") 0139 || chipset.contains("RS600") 0140 || chipset.contains("RS690") 0141 || chipset.contains("RS740")) { 0142 return R400; 0143 } 0144 0145 if (chipset.contains("RV515") 0146 || chipset.contains("R520") 0147 || chipset.contains("RV530") 0148 || chipset.contains("R580") 0149 || chipset.contains("RV560") 0150 || chipset.contains("RV570")) { 0151 return R500; 0152 } 0153 0154 if (chipset.contains("R600") 0155 || chipset.contains("RV610") 0156 || chipset.contains("RV630") 0157 || chipset.contains("RV670") 0158 || chipset.contains("RV620") 0159 || chipset.contains("RV635") 0160 || chipset.contains("RS780") 0161 || chipset.contains("RS880")) { 0162 return R600; 0163 } 0164 0165 if (chipset.contains("R700") 0166 || chipset.contains("RV770") 0167 || chipset.contains("RV730") 0168 || chipset.contains("RV710") 0169 || chipset.contains("RV740")) { 0170 return R700; 0171 } 0172 0173 if (chipset.contains("EVERGREEN") // Not an actual chipset, but returned by R600G in 7.9 0174 || chipset.contains("CEDAR") 0175 || chipset.contains("REDWOOD") 0176 || chipset.contains("JUNIPER") 0177 || chipset.contains("CYPRESS") 0178 || chipset.contains("HEMLOCK") 0179 || chipset.contains("PALM")) { 0180 return Evergreen; 0181 } 0182 0183 if (chipset.contains("SUMO") 0184 || chipset.contains("SUMO2") 0185 || chipset.contains("BARTS") 0186 || chipset.contains("TURKS") 0187 || chipset.contains("CAICOS") 0188 || chipset.contains("CAYMAN")) { 0189 return NorthernIslands; 0190 } 0191 0192 if (chipset.contains("TAHITI") 0193 || chipset.contains("PITCAIRN") 0194 || chipset.contains("VERDE") 0195 || chipset.contains("OLAND") 0196 || chipset.contains("HAINAN")) { 0197 return SouthernIslands; 0198 } 0199 0200 if (chipset.contains("BONAIRE") 0201 || chipset.contains("KAVERI") 0202 || chipset.contains("KABINI") 0203 || chipset.contains("HAWAII") 0204 || chipset.contains("MULLINS")) { 0205 return SeaIslands; 0206 } 0207 0208 if (chipset.contains("TONGA") 0209 || chipset.contains("TOPAZ") 0210 || chipset.contains("FIJI") 0211 || chipset.contains("CARRIZO") 0212 || chipset.contains("STONEY")) { 0213 return VolcanicIslands; 0214 } 0215 0216 if (chipset.contains("POLARIS10") 0217 || chipset.contains("POLARIS11") 0218 || chipset.contains("POLARIS12") 0219 || chipset.contains("VEGAM")) { 0220 return ArcticIslands; 0221 } 0222 0223 if (chipset.contains("VEGA10") 0224 || chipset.contains("VEGA12") 0225 || chipset.contains("VEGA20") 0226 || chipset.contains("RAVEN") 0227 || chipset.contains("RAVEN2") 0228 || chipset.contains("RENOIR") 0229 || chipset.contains("ARCTURUS")) { 0230 return Vega; 0231 } 0232 0233 if (chipset.contains("NAVI10") 0234 || chipset.contains("NAVI12") 0235 || chipset.contains("NAVI14")) { 0236 return Navi; 0237 } 0238 0239 const QString chipset16 = QString::fromLatin1(chipset); 0240 QString name = extract(chipset16, QStringLiteral("HD [0-9]{4}")); // HD followed by a space and 4 digits 0241 if (!name.isEmpty()) { 0242 const int id = QStringView(name).right(4).toInt(); 0243 if (id == 6250 || id == 6310) { // Palm 0244 return Evergreen; 0245 } 0246 0247 if (id >= 6000 && id < 7000) { 0248 return NorthernIslands; // HD 6xxx 0249 } 0250 0251 if (id >= 5000 && id < 6000) { 0252 return Evergreen; // HD 5xxx 0253 } 0254 0255 if (id >= 4000 && id < 5000) { 0256 return R700; // HD 4xxx 0257 } 0258 0259 if (id >= 2000 && id < 4000) { // HD 2xxx/3xxx 0260 return R600; 0261 } 0262 0263 return UnknownRadeon; 0264 } 0265 0266 name = extract(chipset16, QStringLiteral("X[0-9]{3,4}")); // X followed by 3-4 digits 0267 if (!name.isEmpty()) { 0268 const int id = QStringView(name).mid(1, -1).toInt(); 0269 0270 // X1xxx 0271 if (id >= 1300) { 0272 return R500; 0273 } 0274 0275 // X7xx, X8xx, X12xx, 2100 0276 if ((id >= 700 && id < 1000) || id >= 1200) { 0277 return R400; 0278 } 0279 0280 // X200, X3xx, X5xx, X6xx, X10xx, X11xx 0281 if ((id >= 300 && id < 700) || (id >= 1000 && id < 1200)) { 0282 return R300; 0283 } 0284 0285 return UnknownRadeon; 0286 } 0287 0288 name = extract(chipset16, QStringLiteral("\\b[0-9]{4}\\b")); // A group of 4 digits 0289 if (!name.isEmpty()) { 0290 const int id = name.toInt(); 0291 0292 // 7xxx 0293 if (id >= 7000 && id < 8000) { 0294 return R100; 0295 } 0296 0297 // 8xxx, 9xxx 0298 if (id >= 8000 && id < 9500) { 0299 return R200; 0300 } 0301 0302 // 9xxx 0303 if (id >= 9500) { 0304 return R300; 0305 } 0306 0307 if (id == 2100) { 0308 return R400; 0309 } 0310 } 0311 0312 return UnknownRadeon; 0313 } 0314 0315 static ChipClass detectNVidiaClass(const QString &chipset) 0316 { 0317 QString name = extract(chipset, QStringLiteral("\\bNV[0-9,A-F]{2}\\b")); // NV followed by two hexadecimal digits 0318 if (!name.isEmpty()) { 0319 const int id = QStringView(chipset).mid(2, -1).toInt(nullptr, 16); // Strip the 'NV' from the id 0320 0321 switch (id & 0xf0) { 0322 case 0x00: 0323 case 0x10: 0324 return NV10; 0325 0326 case 0x20: 0327 return NV20; 0328 0329 case 0x30: 0330 return NV30; 0331 0332 case 0x40: 0333 case 0x60: 0334 return NV40; 0335 0336 case 0x50: 0337 case 0x80: 0338 case 0x90: 0339 case 0xA0: 0340 return G80; 0341 0342 default: 0343 return UnknownNVidia; 0344 } 0345 } 0346 0347 if (chipset.contains(QLatin1String("GeForce2")) || chipset.contains(QLatin1String("GeForce 256"))) { 0348 return NV10; 0349 } 0350 0351 if (chipset.contains(QLatin1String("GeForce3"))) { 0352 return NV20; 0353 } 0354 0355 if (chipset.contains(QLatin1String("GeForce4"))) { 0356 if (chipset.contains(QLatin1String("MX 420")) 0357 || chipset.contains(QLatin1String("MX 440")) // including MX 440SE 0358 || chipset.contains(QLatin1String("MX 460")) 0359 || chipset.contains(QLatin1String("MX 4000")) 0360 || chipset.contains(QLatin1String("PCX 4300"))) { 0361 return NV10; 0362 } 0363 0364 return NV20; 0365 } 0366 0367 // GeForce 5,6,7,8,9 0368 name = extract(chipset, QStringLiteral("GeForce (FX |PCX |Go )?\\d{4}(M|\\b)")).trimmed(); 0369 if (!name.isEmpty()) { 0370 if (!name[name.length() - 1].isDigit()) { 0371 name.chop(1); 0372 } 0373 0374 const int id = QStringView(name).right(4).toInt(); 0375 if (id < 6000) { 0376 return NV30; 0377 } 0378 0379 if (id >= 6000 && id < 8000) { 0380 return NV40; 0381 } 0382 0383 if (id >= 8000) { 0384 return G80; 0385 } 0386 0387 return UnknownNVidia; 0388 } 0389 0390 // GeForce 100/200/300/400/500 0391 name = extract(chipset, QStringLiteral("GeForce (G |GT |GTX |GTS )?\\d{3}(M|\\b)")).trimmed(); 0392 if (!name.isEmpty()) { 0393 if (!name[name.length() - 1].isDigit()) { 0394 name.chop(1); 0395 } 0396 0397 const int id = QStringView(name).right(3).toInt(); 0398 if (id >= 100 && id < 600) { 0399 if (id >= 400) { 0400 return GF100; 0401 } 0402 0403 return G80; 0404 } 0405 return UnknownNVidia; 0406 } 0407 0408 return UnknownNVidia; 0409 } 0410 static inline ChipClass detectNVidiaClass(const QByteArray &chipset) 0411 { 0412 return detectNVidiaClass(QString::fromLatin1(chipset)); 0413 } 0414 0415 static ChipClass detectIntelClass(const QByteArray &chipset) 0416 { 0417 // see mesa repository: src/mesa/drivers/dri/intel/intel_context.c 0418 // GL 1.3, DX8? SM ? 0419 if (chipset.contains("845G") 0420 || chipset.contains("830M") 0421 || chipset.contains("852GM/855GM") 0422 || chipset.contains("865G")) { 0423 return I8XX; 0424 } 0425 0426 // GL 1.4, DX 9.0, SM 2.0 0427 if (chipset.contains("915G") 0428 || chipset.contains("E7221G") 0429 || chipset.contains("915GM") 0430 || chipset.contains("945G") // DX 9.0c 0431 || chipset.contains("945GM") 0432 || chipset.contains("945GME") 0433 || chipset.contains("Q33") // GL1.5 0434 || chipset.contains("Q35") 0435 || chipset.contains("G33") 0436 || chipset.contains("965Q") // GMA 3000, but apparently considered gen 4 by the driver 0437 || chipset.contains("946GZ") // GMA 3000, but apparently considered gen 4 by the driver 0438 || chipset.contains("IGD")) { 0439 return I915; 0440 } 0441 0442 // GL 2.0, DX 9.0c, SM 3.0 0443 if (chipset.contains("965G") 0444 || chipset.contains("G45/G43") // SM 4.0 0445 || chipset.contains("965GM") // GL 2.1 0446 || chipset.contains("965GME/GLE") 0447 || chipset.contains("GM45") 0448 || chipset.contains("Q45/Q43") 0449 || chipset.contains("G41") 0450 || chipset.contains("B43") 0451 || chipset.contains("Ironlake")) { 0452 return I965; 0453 } 0454 0455 // GL 3.1, CL 1.1, DX 10.1 0456 if (chipset.contains("Sandybridge") || chipset.contains("SNB GT")) { 0457 return SandyBridge; 0458 } 0459 0460 // GL4.0, CL1.1, DX11, SM 5.0 0461 if (chipset.contains("Ivybridge") || chipset.contains("IVB GT")) { 0462 return IvyBridge; 0463 } 0464 0465 // GL4.0, CL1.2, DX11.1, SM 5.0 0466 if (chipset.contains("Haswell") || chipset.contains("HSW GT")) { 0467 return Haswell; 0468 } 0469 if (chipset.contains("BYT")) { 0470 return BayTrail; 0471 } 0472 if (chipset.contains("CHV") || chipset.contains("BSW")) { 0473 return Cherryview; 0474 } 0475 if (chipset.contains("BDW GT")) { 0476 return Broadwell; 0477 } 0478 if (chipset.contains("SKL GT")) { 0479 return Skylake; 0480 } 0481 if (chipset.contains("APL")) { 0482 return ApolloLake; 0483 } 0484 if (chipset.contains("KBL GT")) { 0485 return KabyLake; 0486 } 0487 if (chipset.contains("WHL GT")) { 0488 return WhiskeyLake; 0489 } 0490 if (chipset.contains("CML GT")) { 0491 return CometLake; 0492 } 0493 if (chipset.contains("CNL GT")) { 0494 return CannonLake; 0495 } 0496 if (chipset.contains("CFL GT")) { 0497 return CoffeeLake; 0498 } 0499 if (chipset.contains("ICL GT")) { 0500 return IceLake; 0501 } 0502 if (chipset.contains("TGL GT")) { 0503 return TigerLake; 0504 } 0505 0506 return UnknownIntel; 0507 } 0508 0509 static ChipClass detectQualcommClass(const QByteArray &chipClass) 0510 { 0511 if (!chipClass.contains("Adreno")) { 0512 return UnknownChipClass; 0513 } 0514 const auto parts = chipClass.split(' '); 0515 if (parts.count() < 3) { 0516 return UnknownAdreno; 0517 } 0518 bool ok = false; 0519 const int value = parts.at(2).toInt(&ok); 0520 if (ok) { 0521 if (value >= 100 && value < 200) { 0522 return Adreno1XX; 0523 } else if (value >= 200 && value < 300) { 0524 return Adreno2XX; 0525 } else if (value >= 300 && value < 400) { 0526 return Adreno3XX; 0527 } else if (value >= 400 && value < 500) { 0528 return Adreno4XX; 0529 } else if (value >= 500 && value < 600) { 0530 return Adreno5XX; 0531 } 0532 } 0533 return UnknownAdreno; 0534 } 0535 0536 static ChipClass detectPanfrostClass(const QByteArray &chipClass) 0537 { 0538 // Keep the list of supported Mali chipset up to date with https://docs.mesa3d.org/drivers/panfrost.html 0539 if (chipClass.contains("T720") || chipClass.contains("T760")) { 0540 return MaliT7XX; 0541 } 0542 0543 if (chipClass.contains("T820") || chipClass.contains("T830") || chipClass.contains("T860") || chipClass.contains("T880")) { 0544 return MaliT8XX; 0545 } 0546 0547 if (chipClass.contains("G31") || chipClass.contains("G51") || chipClass.contains("G52") || chipClass.contains("G57") || chipClass.contains("G72") || chipClass.contains("G76")) { 0548 return MaliGXX; 0549 } 0550 0551 return UnknownPanfrost; 0552 } 0553 0554 static ChipClass detectLimaClass(const QByteArray &chipClass) 0555 { 0556 if (chipClass.contains("400")) { 0557 return Mali400; 0558 } else if (chipClass.contains("450")) { 0559 return Mali450; 0560 } else if (chipClass.contains("470")) { 0561 return Mali470; 0562 } 0563 0564 return UnknownLima; 0565 } 0566 0567 static ChipClass detectVC4Class(const QByteArray &chipClass) 0568 { 0569 if (chipClass.contains("2.1")) { 0570 return VC4_2_1; 0571 } 0572 0573 return UnknownVideoCore4; 0574 } 0575 0576 static ChipClass detectV3DClass(const QByteArray &chipClass) 0577 { 0578 if (chipClass.contains("4.2")) { 0579 return V3D_4_2; 0580 } 0581 0582 return UnknownVideoCore3D; 0583 } 0584 0585 QString GLPlatform::versionToString(qint64 version) 0586 { 0587 return QString::fromLatin1(versionToString8(version)); 0588 } 0589 QByteArray GLPlatform::versionToString8(qint64 version) 0590 { 0591 int major = (version >> 32); 0592 int minor = (version >> 16) & 0xffff; 0593 int patch = version & 0xffff; 0594 0595 QByteArray string = QByteArray::number(major) + '.' + QByteArray::number(minor); 0596 if (patch != 0) { 0597 string += '.' + QByteArray::number(patch); 0598 } 0599 0600 return string; 0601 } 0602 0603 QString GLPlatform::driverToString(Driver driver) 0604 { 0605 return QString::fromLatin1(driverToString8(driver)); 0606 } 0607 QByteArray GLPlatform::driverToString8(Driver driver) 0608 { 0609 switch (driver) { 0610 case Driver_R100: 0611 return QByteArrayLiteral("Radeon"); 0612 case Driver_R200: 0613 return QByteArrayLiteral("R200"); 0614 case Driver_R300C: 0615 return QByteArrayLiteral("R300C"); 0616 case Driver_R300G: 0617 return QByteArrayLiteral("R300G"); 0618 case Driver_R600C: 0619 return QByteArrayLiteral("R600C"); 0620 case Driver_R600G: 0621 return QByteArrayLiteral("R600G"); 0622 case Driver_RadeonSI: 0623 return QByteArrayLiteral("RadeonSI"); 0624 case Driver_Nouveau: 0625 return QByteArrayLiteral("Nouveau"); 0626 case Driver_Intel: 0627 return QByteArrayLiteral("Intel"); 0628 case Driver_NVidia: 0629 return QByteArrayLiteral("NVIDIA"); 0630 case Driver_Catalyst: 0631 return QByteArrayLiteral("Catalyst"); 0632 case Driver_Swrast: 0633 return QByteArrayLiteral("Software rasterizer"); 0634 case Driver_Softpipe: 0635 return QByteArrayLiteral("softpipe"); 0636 case Driver_Llvmpipe: 0637 return QByteArrayLiteral("LLVMpipe"); 0638 case Driver_VirtualBox: 0639 return QByteArrayLiteral("VirtualBox (Chromium)"); 0640 case Driver_VMware: 0641 return QByteArrayLiteral("VMware (SVGA3D)"); 0642 case Driver_Qualcomm: 0643 return QByteArrayLiteral("Qualcomm"); 0644 case Driver_Virgl: 0645 return QByteArrayLiteral("Virgl (virtio-gpu, Qemu/KVM guest)"); 0646 case Driver_Panfrost: 0647 return QByteArrayLiteral("Panfrost"); 0648 case Driver_Lima: 0649 return QByteArrayLiteral("Mali (Lima)"); 0650 case Driver_VC4: 0651 return QByteArrayLiteral("VideoCore IV"); 0652 case Driver_V3D: 0653 return QByteArrayLiteral("VideoCore 3D"); 0654 0655 default: 0656 return QByteArrayLiteral("Unknown"); 0657 } 0658 } 0659 0660 QString GLPlatform::chipClassToString(ChipClass chipClass) 0661 { 0662 return QString::fromLatin1(chipClassToString8(chipClass)); 0663 } 0664 QByteArray GLPlatform::chipClassToString8(ChipClass chipClass) 0665 { 0666 switch (chipClass) { 0667 case R100: 0668 return QByteArrayLiteral("R100"); 0669 case R200: 0670 return QByteArrayLiteral("R200"); 0671 case R300: 0672 return QByteArrayLiteral("R300"); 0673 case R400: 0674 return QByteArrayLiteral("R400"); 0675 case R500: 0676 return QByteArrayLiteral("R500"); 0677 case R600: 0678 return QByteArrayLiteral("R600"); 0679 case R700: 0680 return QByteArrayLiteral("R700"); 0681 case Evergreen: 0682 return QByteArrayLiteral("EVERGREEN"); 0683 case NorthernIslands: 0684 return QByteArrayLiteral("Northern Islands"); 0685 case SouthernIslands: 0686 return QByteArrayLiteral("Southern Islands"); 0687 case SeaIslands: 0688 return QByteArrayLiteral("Sea Islands"); 0689 case VolcanicIslands: 0690 return QByteArrayLiteral("Volcanic Islands"); 0691 case ArcticIslands: 0692 return QByteArrayLiteral("Arctic Islands"); 0693 case Vega: 0694 return QByteArrayLiteral("Vega"); 0695 case Navi: 0696 return QByteArrayLiteral("Navi"); 0697 0698 case NV10: 0699 return QByteArrayLiteral("NV10"); 0700 case NV20: 0701 return QByteArrayLiteral("NV20"); 0702 case NV30: 0703 return QByteArrayLiteral("NV30"); 0704 case NV40: 0705 return QByteArrayLiteral("NV40/G70"); 0706 case G80: 0707 return QByteArrayLiteral("G80/G90"); 0708 case GF100: 0709 return QByteArrayLiteral("GF100"); 0710 0711 case I8XX: 0712 return QByteArrayLiteral("i830/i835"); 0713 case I915: 0714 return QByteArrayLiteral("i915/i945"); 0715 case I965: 0716 return QByteArrayLiteral("i965"); 0717 case SandyBridge: 0718 return QByteArrayLiteral("SandyBridge"); 0719 case IvyBridge: 0720 return QByteArrayLiteral("IvyBridge"); 0721 case Haswell: 0722 return QByteArrayLiteral("Haswell"); 0723 case BayTrail: 0724 return QByteArrayLiteral("Bay Trail"); 0725 case Cherryview: 0726 return QByteArrayLiteral("Cherryview"); 0727 case Broadwell: 0728 return QByteArrayLiteral("Broadwell"); 0729 case ApolloLake: 0730 return QByteArrayLiteral("Apollo Lake"); 0731 case Skylake: 0732 return QByteArrayLiteral("Skylake"); 0733 case GeminiLake: 0734 return QByteArrayLiteral("Gemini Lake"); 0735 case KabyLake: 0736 return QByteArrayLiteral("Kaby Lake"); 0737 case CoffeeLake: 0738 return QByteArrayLiteral("Coffee Lake"); 0739 case WhiskeyLake: 0740 return QByteArrayLiteral("Whiskey Lake"); 0741 case CometLake: 0742 return QByteArrayLiteral("Comet Lake"); 0743 case CannonLake: 0744 return QByteArrayLiteral("Cannon Lake"); 0745 case IceLake: 0746 return QByteArrayLiteral("Ice Lake"); 0747 case TigerLake: 0748 return QByteArrayLiteral("Tiger Lake"); 0749 0750 case Adreno1XX: 0751 return QByteArrayLiteral("Adreno 1xx series"); 0752 case Adreno2XX: 0753 return QByteArrayLiteral("Adreno 2xx series"); 0754 case Adreno3XX: 0755 return QByteArrayLiteral("Adreno 3xx series"); 0756 case Adreno4XX: 0757 return QByteArrayLiteral("Adreno 4xx series"); 0758 case Adreno5XX: 0759 return QByteArrayLiteral("Adreno 5xx series"); 0760 0761 case Mali400: 0762 return QByteArrayLiteral("Mali 400 series"); 0763 case Mali450: 0764 return QByteArrayLiteral("Mali 450 series"); 0765 case Mali470: 0766 return QByteArrayLiteral("Mali 470 series"); 0767 0768 case MaliT7XX: 0769 return QByteArrayLiteral("Mali T7xx series"); 0770 case MaliT8XX: 0771 return QByteArrayLiteral("Mali T8xx series"); 0772 case MaliGXX: 0773 return QByteArrayLiteral("Mali Gxx series"); 0774 0775 case VC4_2_1: 0776 return QByteArrayLiteral("VideoCore IV"); 0777 case V3D_4_2: 0778 return QByteArrayLiteral("VideoCore 3D"); 0779 0780 default: 0781 return QByteArrayLiteral("Unknown"); 0782 } 0783 } 0784 0785 // ------- 0786 0787 GLPlatform::GLPlatform() 0788 : m_driver(Driver_Unknown) 0789 , m_chipClass(UnknownChipClass) 0790 , m_recommendedCompositor(QPainterCompositing) 0791 , m_glVersion(0) 0792 , m_glslVersion(0) 0793 , m_mesaVersion(0) 0794 , m_driverVersion(0) 0795 , m_galliumVersion(0) 0796 , m_serverVersion(0) 0797 , m_kernelVersion(0) 0798 , m_looseBinding(false) 0799 , m_supportsGLSL(false) 0800 , m_limitedGLSL(false) 0801 , m_textureNPOT(false) 0802 , m_limitedNPOT(false) 0803 , m_packInvert(false) 0804 , m_virtualMachine(false) 0805 , m_preferBufferSubData(false) 0806 , m_platformInterface(NoOpenGLPlatformInterface) 0807 , m_gles(false) 0808 { 0809 } 0810 0811 GLPlatform::~GLPlatform() 0812 { 0813 } 0814 0815 void GLPlatform::detect(OpenGLPlatformInterface platformInterface) 0816 { 0817 m_platformInterface = platformInterface; 0818 0819 m_vendor = (const char *)glGetString(GL_VENDOR); 0820 m_renderer = (const char *)glGetString(GL_RENDERER); 0821 m_version = (const char *)glGetString(GL_VERSION); 0822 0823 // Parse the OpenGL version 0824 const QList<QByteArray> versionTokens = m_version.split(' '); 0825 if (versionTokens.count() > 0) { 0826 const QByteArray version = QByteArray(m_version); 0827 m_glVersion = parseVersionString(version); 0828 if (platformInterface == EglPlatformInterface) { 0829 // only EGL can have OpenGLES, GLX is OpenGL only 0830 if (version.startsWith("OpenGL ES")) { 0831 // from GLES 2: "Returns a version or release number of the form OpenGL<space>ES<space><version number><space><vendor-specific information>." 0832 // from GLES 3: "Returns a version or release number." and "The version number uses one of these forms: major_number.minor_number major_number.minor_number.release_number" 0833 m_gles = true; 0834 } 0835 } 0836 } 0837 0838 if (!isGLES() && m_glVersion >= kVersionNumber(3, 0)) { 0839 int count; 0840 glGetIntegerv(GL_NUM_EXTENSIONS, &count); 0841 0842 for (int i = 0; i < count; i++) { 0843 const char *name = (const char *)glGetStringi(GL_EXTENSIONS, i); 0844 m_extensions.insert(name); 0845 } 0846 } else { 0847 const QByteArray extensions = (const char *)glGetString(GL_EXTENSIONS); 0848 QList<QByteArray> extensionsList = extensions.split(' '); 0849 m_extensions = {extensionsList.constBegin(), extensionsList.constEnd()}; 0850 } 0851 0852 // Parse the Mesa version 0853 const int mesaIndex = versionTokens.indexOf("Mesa"); 0854 if (mesaIndex != -1) { 0855 const QByteArray &version = versionTokens.at(mesaIndex + 1); 0856 m_mesaVersion = parseVersionString(version); 0857 } 0858 0859 if (isGLES()) { 0860 m_supportsGLSL = true; 0861 m_textureNPOT = true; 0862 } else { 0863 m_supportsGLSL = (m_extensions.contains("GL_ARB_shader_objects") 0864 && m_extensions.contains("GL_ARB_fragment_shader") 0865 && m_extensions.contains("GL_ARB_vertex_shader")); 0866 0867 m_textureNPOT = m_extensions.contains("GL_ARB_texture_non_power_of_two"); 0868 } 0869 0870 m_serverVersion = getXServerVersion(); 0871 m_kernelVersion = getKernelVersion(); 0872 0873 m_glslVersion = 0; 0874 m_glsl_version.clear(); 0875 0876 if (m_supportsGLSL) { 0877 // Parse the GLSL version 0878 m_glsl_version = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); 0879 m_glslVersion = parseVersionString(m_glsl_version); 0880 } 0881 0882 m_chipset = QByteArrayLiteral("Unknown"); 0883 m_preferBufferSubData = false; 0884 m_packInvert = m_extensions.contains("GL_MESA_pack_invert"); 0885 0886 // Mesa classic drivers 0887 // ==================================================== 0888 0889 // Radeon 0890 if (m_renderer.startsWith("Mesa DRI R")) { 0891 // Sample renderer string: Mesa DRI R600 (RV740 94B3) 20090101 x86/MMX/SSE2 TCL DRI2 0892 const QList<QByteArray> tokens = m_renderer.split(' '); 0893 const QByteArray &chipClass = tokens.at(2); 0894 m_chipset = tokens.at(3).mid(1, -1); // Strip the leading '(' 0895 0896 if (chipClass == "R100") { 0897 // Vendor: Tungsten Graphics, Inc. 0898 m_driver = Driver_R100; 0899 0900 } else if (chipClass == "R200") { 0901 // Vendor: Tungsten Graphics, Inc. 0902 m_driver = Driver_R200; 0903 0904 } else if (chipClass == "R300") { 0905 // Vendor: DRI R300 Project 0906 m_driver = Driver_R300C; 0907 0908 } else if (chipClass == "R600") { 0909 // Vendor: Advanced Micro Devices, Inc. 0910 m_driver = Driver_R600C; 0911 } 0912 0913 m_chipClass = detectRadeonClass(m_chipset); 0914 } 0915 0916 // Intel 0917 else if (m_renderer.contains("Intel")) { 0918 // Vendor: Tungsten Graphics, Inc. 0919 // Sample renderer string: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100328 2010Q1 0920 0921 QByteArray chipset; 0922 if (m_renderer.startsWith("Intel(R) Integrated Graphics Device")) { 0923 chipset = "IGD"; 0924 } else { 0925 chipset = m_renderer; 0926 } 0927 0928 m_driver = Driver_Intel; 0929 m_chipClass = detectIntelClass(chipset); 0930 } 0931 0932 // Properietary drivers 0933 // ==================================================== 0934 else if (m_vendor == "ATI Technologies Inc.") { 0935 m_chipClass = detectRadeonClass(m_renderer); 0936 m_driver = Driver_Catalyst; 0937 0938 if (versionTokens.count() > 1 && versionTokens.at(2)[0] == '(') { 0939 m_driverVersion = parseVersionString(versionTokens.at(1)); 0940 } else if (versionTokens.count() > 0) { 0941 m_driverVersion = parseVersionString(versionTokens.at(0)); 0942 } else { 0943 m_driverVersion = 0; 0944 } 0945 } 0946 0947 else if (m_vendor == "NVIDIA Corporation") { 0948 m_chipClass = detectNVidiaClass(m_renderer); 0949 m_driver = Driver_NVidia; 0950 0951 int index = versionTokens.indexOf("NVIDIA"); 0952 if (versionTokens.count() > index) { 0953 m_driverVersion = parseVersionString(versionTokens.at(index + 1)); 0954 } else { 0955 m_driverVersion = 0; 0956 } 0957 } 0958 0959 else if (m_vendor == "Qualcomm") { 0960 m_driver = Driver_Qualcomm; 0961 m_chipClass = detectQualcommClass(m_renderer); 0962 } 0963 0964 else if (m_renderer.contains("Panfrost")) { 0965 m_driver = Driver_Panfrost; 0966 m_chipClass = detectPanfrostClass(m_renderer); 0967 } 0968 0969 else if (m_renderer.contains("Mali")) { 0970 m_driver = Driver_Lima; 0971 m_chipClass = detectLimaClass(m_renderer); 0972 } 0973 0974 else if (m_renderer.startsWith("VC4 ")) { 0975 m_driver = Driver_VC4; 0976 m_chipClass = detectVC4Class(m_renderer); 0977 } 0978 0979 else if(m_renderer.startsWith("V3D ")) { 0980 m_driver = Driver_V3D; 0981 m_chipClass = detectV3DClass(m_renderer); 0982 } 0983 0984 else if (m_renderer == "Software Rasterizer") { 0985 m_driver = Driver_Swrast; 0986 } 0987 0988 // Virtual Hardware 0989 // ==================================================== 0990 else if (m_vendor == "Humper" && m_renderer == "Chromium") { 0991 // Virtual Box 0992 m_driver = Driver_VirtualBox; 0993 0994 const int index = versionTokens.indexOf("Chromium"); 0995 if (versionTokens.count() > index) { 0996 m_driverVersion = parseVersionString(versionTokens.at(index + 1)); 0997 } else { 0998 m_driverVersion = 0; 0999 } 1000 } 1001 1002 // Gallium drivers 1003 // ==================================================== 1004 else { 1005 const QList<QByteArray> tokens = m_renderer.split(' '); 1006 if (m_renderer.contains("Gallium")) { 1007 // Sample renderer string: Gallium 0.4 on AMD RV740 1008 m_galliumVersion = parseVersionString(tokens.at(1)); 1009 m_chipset = (tokens.at(3) == "AMD" || tokens.at(3) == "ATI") ? tokens.at(4) : tokens.at(3); 1010 } else { 1011 // The renderer string does not contain "Gallium" anymore. 1012 m_chipset = tokens.at(0); 1013 // We don't know the actual version anymore, but it's at least 0.4. 1014 m_galliumVersion = kVersionNumber(0, 4, 0); 1015 } 1016 1017 // R300G 1018 if (m_vendor == QByteArrayLiteral("X.Org R300 Project")) { 1019 m_chipClass = detectRadeonClass(m_chipset); 1020 m_driver = Driver_R300G; 1021 } 1022 1023 // R600G 1024 else if (m_vendor == "X.Org" && (m_renderer.contains("R6") || m_renderer.contains("R7") || m_renderer.contains("RV6") || m_renderer.contains("RV7") || m_renderer.contains("RS780") || m_renderer.contains("RS880") || m_renderer.contains("CEDAR") || m_renderer.contains("REDWOOD") || m_renderer.contains("JUNIPER") || m_renderer.contains("CYPRESS") || m_renderer.contains("HEMLOCK") || m_renderer.contains("PALM") || m_renderer.contains("EVERGREEN") || m_renderer.contains("SUMO") || m_renderer.contains("SUMO2") || m_renderer.contains("BARTS") || m_renderer.contains("TURKS") || m_renderer.contains("CAICOS") || m_renderer.contains("CAYMAN"))) { 1025 m_chipClass = detectRadeonClass(m_chipset); 1026 m_driver = Driver_R600G; 1027 } 1028 1029 // RadeonSI 1030 else if ((m_vendor == "X.Org" || m_vendor == "AMD") && (m_renderer.contains("TAHITI") || m_renderer.contains("PITCAIRN") || m_renderer.contains("VERDE") || m_renderer.contains("OLAND") || m_renderer.contains("HAINAN") || m_renderer.contains("BONAIRE") || m_renderer.contains("KAVERI") || m_renderer.contains("KABINI") || m_renderer.contains("HAWAII") || m_renderer.contains("MULLINS") || m_renderer.contains("TOPAZ") || m_renderer.contains("TONGA") || m_renderer.contains("FIJI") || m_renderer.contains("CARRIZO") || m_renderer.contains("STONEY") || m_renderer.contains("POLARIS10") || m_renderer.contains("POLARIS11") || m_renderer.contains("POLARIS12") || m_renderer.contains("VEGAM") || m_renderer.contains("VEGA10") || m_renderer.contains("VEGA12") || m_renderer.contains("VEGA20") || m_renderer.contains("RAVEN") || m_renderer.contains("RAVEN2") || m_renderer.contains("RENOIR") || m_renderer.contains("ARCTURUS") || m_renderer.contains("NAVI10") || m_renderer.contains("NAVI12") || m_renderer.contains("NAVI14"))) { 1031 m_chipClass = detectRadeonClass(m_renderer); 1032 m_driver = Driver_RadeonSI; 1033 } 1034 1035 // Nouveau 1036 else if (m_vendor == "nouveau") { 1037 m_chipClass = detectNVidiaClass(m_chipset); 1038 m_driver = Driver_Nouveau; 1039 } 1040 1041 // softpipe 1042 else if (m_chipset == "softpipe") { 1043 m_driver = Driver_Softpipe; 1044 } 1045 1046 // llvmpipe 1047 else if (m_chipset == "llvmpipe") { 1048 m_driver = Driver_Llvmpipe; 1049 } 1050 1051 // SVGA3D 1052 else if (m_vendor == "VMware, Inc." && m_chipset.contains("SVGA3D")) { 1053 m_driver = Driver_VMware; 1054 } 1055 1056 // virgl 1057 else if (m_renderer == "virgl") { 1058 m_driver = Driver_Virgl; 1059 } 1060 } 1061 1062 // Driver/GPU specific features 1063 // ==================================================== 1064 if (isRadeon()) { 1065 // R200 technically has a programmable pipeline, but since it's SM 1.4, 1066 // it's too limited to to be of any practical value to us. 1067 if (m_chipClass < R300) { 1068 m_supportsGLSL = false; 1069 } 1070 1071 m_limitedGLSL = false; 1072 m_limitedNPOT = false; 1073 1074 if (m_chipClass < R600) { 1075 if (driver() == Driver_Catalyst) { 1076 m_textureNPOT = m_limitedNPOT = false; // Software fallback 1077 } else if (driver() == Driver_R300G) { 1078 m_limitedNPOT = m_textureNPOT; 1079 } 1080 1081 m_limitedGLSL = m_supportsGLSL; 1082 } 1083 1084 if (m_chipClass < R300) { 1085 // fallback to NoCompositing for R100 and R200 1086 m_recommendedCompositor = NoCompositing; 1087 } else if (m_chipClass < R600) { 1088 // NoCompositing due to NPOT limitations not supported by KWin's shaders 1089 m_recommendedCompositor = NoCompositing; 1090 } else { 1091 m_recommendedCompositor = OpenGLCompositing; 1092 } 1093 1094 if (driver() == Driver_R600G || (driver() == Driver_R600C && m_renderer.contains("DRI2"))) { 1095 m_looseBinding = true; 1096 } 1097 } 1098 1099 if (isNvidia()) { 1100 if (m_driver == Driver_NVidia && m_chipClass < NV40) { 1101 m_supportsGLSL = false; // High likelihood of software emulation 1102 } 1103 1104 if (m_driver == Driver_NVidia) { 1105 m_looseBinding = true; 1106 m_preferBufferSubData = true; 1107 } 1108 1109 if (m_chipClass < NV40) { 1110 m_recommendedCompositor = NoCompositing; 1111 } else { 1112 m_recommendedCompositor = OpenGLCompositing; 1113 } 1114 1115 m_limitedNPOT = m_textureNPOT && m_chipClass < NV40; 1116 m_limitedGLSL = m_supportsGLSL && m_chipClass < G80; 1117 } 1118 1119 if (isIntel()) { 1120 if (m_chipClass < I915) { 1121 m_supportsGLSL = false; 1122 } 1123 1124 m_limitedGLSL = m_supportsGLSL && m_chipClass < I965; 1125 // see https://bugs.freedesktop.org/show_bug.cgi?id=80349#c1 1126 m_looseBinding = false; 1127 1128 if (m_chipClass < I915) { 1129 m_recommendedCompositor = NoCompositing; 1130 } else { 1131 m_recommendedCompositor = OpenGLCompositing; 1132 } 1133 } 1134 1135 if (isPanfrost()) { 1136 m_recommendedCompositor = OpenGLCompositing; 1137 } 1138 1139 if (isLima()) { 1140 m_recommendedCompositor = OpenGLCompositing; 1141 m_supportsGLSL = true; 1142 } 1143 1144 if (isVideoCore4()) { 1145 // OpenGL works, but is much slower than QPainter 1146 m_recommendedCompositor = QPainterCompositing; 1147 } 1148 1149 if (isVideoCore3D()) { 1150 // OpenGL works, but is much slower than QPainter 1151 m_recommendedCompositor = QPainterCompositing; 1152 } 1153 1154 if (isMesaDriver() && platformInterface == EglPlatformInterface) { 1155 // According to the reference implementation in 1156 // mesa/demos/src/egl/opengles1/texture_from_pixmap 1157 // the mesa egl implementation does not require a strict binding (so far). 1158 m_looseBinding = true; 1159 } 1160 1161 if (isSoftwareEmulation()) { 1162 if (m_driver < Driver_Llvmpipe) { 1163 // we recommend QPainter 1164 m_recommendedCompositor = QPainterCompositing; 1165 // Software emulation does not provide GLSL 1166 m_limitedGLSL = m_supportsGLSL = false; 1167 } else { 1168 // llvmpipe does support GLSL 1169 m_recommendedCompositor = OpenGLCompositing; 1170 m_limitedGLSL = false; 1171 m_supportsGLSL = true; 1172 } 1173 } 1174 1175 if (m_driver == Driver_Qualcomm) { 1176 if (m_chipClass == Adreno1XX) { 1177 m_recommendedCompositor = NoCompositing; 1178 } else { 1179 // all other drivers support at least GLES 2 1180 m_recommendedCompositor = OpenGLCompositing; 1181 } 1182 } 1183 1184 if (m_chipClass == UnknownChipClass && m_driver == Driver_Unknown) { 1185 // we don't know the hardware. Let's be optimistic and assume OpenGL compatible hardware 1186 m_recommendedCompositor = OpenGLCompositing; 1187 m_supportsGLSL = true; 1188 } 1189 1190 if (isVirtualBox()) { 1191 m_virtualMachine = true; 1192 m_recommendedCompositor = OpenGLCompositing; 1193 } 1194 1195 if (isVMware()) { 1196 m_virtualMachine = true; 1197 m_recommendedCompositor = OpenGLCompositing; 1198 } 1199 1200 if (m_driver == Driver_Virgl) { 1201 m_virtualMachine = true; 1202 m_recommendedCompositor = OpenGLCompositing; 1203 } 1204 1205 // and force back to shader supported on gles, we wouldn't have got a context if not supported 1206 if (isGLES()) { 1207 m_supportsGLSL = true; 1208 m_limitedGLSL = false; 1209 } 1210 } 1211 1212 static void print(const QByteArray &label, const QByteArray &setting) 1213 { 1214 qInfo("%-40s%s", label.data(), setting.data()); 1215 } 1216 1217 void GLPlatform::printResults() const 1218 { 1219 print(QByteArrayLiteral("OpenGL vendor string:"), m_vendor); 1220 print(QByteArrayLiteral("OpenGL renderer string:"), m_renderer); 1221 print(QByteArrayLiteral("OpenGL version string:"), m_version); 1222 1223 if (m_supportsGLSL) { 1224 print(QByteArrayLiteral("OpenGL shading language version string:"), m_glsl_version); 1225 } 1226 1227 print(QByteArrayLiteral("Driver:"), driverToString8(m_driver)); 1228 if (!isMesaDriver()) { 1229 print(QByteArrayLiteral("Driver version:"), versionToString8(m_driverVersion)); 1230 } 1231 1232 print(QByteArrayLiteral("GPU class:"), chipClassToString8(m_chipClass)); 1233 1234 print(QByteArrayLiteral("OpenGL version:"), versionToString8(m_glVersion)); 1235 1236 if (m_supportsGLSL) { 1237 print(QByteArrayLiteral("GLSL version:"), versionToString8(m_glslVersion)); 1238 } 1239 1240 if (isMesaDriver()) { 1241 print(QByteArrayLiteral("Mesa version:"), versionToString8(mesaVersion())); 1242 } 1243 // if (galliumVersion() > 0) 1244 // print("Gallium version:", versionToString(m_galliumVersion)); 1245 if (serverVersion() > 0) { 1246 print(QByteArrayLiteral("X server version:"), versionToString8(m_serverVersion)); 1247 } 1248 if (kernelVersion() > 0) { 1249 print(QByteArrayLiteral("Linux kernel version:"), versionToString8(m_kernelVersion)); 1250 } 1251 1252 print(QByteArrayLiteral("Requires strict binding:"), !m_looseBinding ? QByteArrayLiteral("yes") : QByteArrayLiteral("no")); 1253 print(QByteArrayLiteral("GLSL shaders:"), m_supportsGLSL ? (m_limitedGLSL ? QByteArrayLiteral("limited") : QByteArrayLiteral("yes")) : QByteArrayLiteral("no")); 1254 print(QByteArrayLiteral("Texture NPOT support:"), m_textureNPOT ? (m_limitedNPOT ? QByteArrayLiteral("limited") : QByteArrayLiteral("yes")) : QByteArrayLiteral("no")); 1255 print(QByteArrayLiteral("Virtual Machine:"), m_virtualMachine ? QByteArrayLiteral("yes") : QByteArrayLiteral("no")); 1256 } 1257 1258 bool GLPlatform::supports(GLFeature feature) const 1259 { 1260 switch (feature) { 1261 case LooseBinding: 1262 return m_looseBinding; 1263 1264 case GLSL: 1265 return m_supportsGLSL; 1266 1267 case LimitedGLSL: 1268 return m_limitedGLSL; 1269 1270 case TextureNPOT: 1271 return m_textureNPOT; 1272 1273 case LimitedNPOT: 1274 return m_limitedNPOT; 1275 1276 case PackInvert: 1277 return m_packInvert; 1278 1279 default: 1280 return false; 1281 } 1282 } 1283 1284 qint64 GLPlatform::glVersion() const 1285 { 1286 return m_glVersion; 1287 } 1288 1289 qint64 GLPlatform::glslVersion() const 1290 { 1291 return m_glslVersion; 1292 } 1293 1294 qint64 GLPlatform::mesaVersion() const 1295 { 1296 return m_mesaVersion; 1297 } 1298 1299 qint64 GLPlatform::galliumVersion() const 1300 { 1301 return m_galliumVersion; 1302 } 1303 1304 qint64 GLPlatform::serverVersion() const 1305 { 1306 return m_serverVersion; 1307 } 1308 1309 qint64 GLPlatform::kernelVersion() const 1310 { 1311 return m_kernelVersion; 1312 } 1313 1314 qint64 GLPlatform::driverVersion() const 1315 { 1316 if (isMesaDriver()) { 1317 return mesaVersion(); 1318 } 1319 1320 return m_driverVersion; 1321 } 1322 1323 Driver GLPlatform::driver() const 1324 { 1325 return m_driver; 1326 } 1327 1328 ChipClass GLPlatform::chipClass() const 1329 { 1330 return m_chipClass; 1331 } 1332 1333 bool GLPlatform::isMesaDriver() const 1334 { 1335 return mesaVersion() > 0; 1336 } 1337 1338 bool GLPlatform::isGalliumDriver() const 1339 { 1340 return galliumVersion() > 0; 1341 } 1342 1343 bool GLPlatform::isRadeon() const 1344 { 1345 return m_chipClass >= R100 && m_chipClass <= UnknownRadeon; 1346 } 1347 1348 bool GLPlatform::isNvidia() const 1349 { 1350 return m_chipClass >= NV10 && m_chipClass <= UnknownNVidia; 1351 } 1352 1353 bool GLPlatform::isIntel() const 1354 { 1355 return m_chipClass >= I8XX && m_chipClass <= UnknownIntel; 1356 } 1357 1358 bool GLPlatform::isVirtualBox() const 1359 { 1360 return m_driver == Driver_VirtualBox; 1361 } 1362 1363 bool GLPlatform::isVMware() const 1364 { 1365 return m_driver == Driver_VMware; 1366 } 1367 1368 bool GLPlatform::isVirgl() const 1369 { 1370 return m_driver == Driver_Virgl; 1371 } 1372 1373 bool GLPlatform::isSoftwareEmulation() const 1374 { 1375 return m_driver == Driver_Softpipe || m_driver == Driver_Swrast || m_driver == Driver_Llvmpipe; 1376 } 1377 1378 bool GLPlatform::isAdreno() const 1379 { 1380 return m_chipClass >= Adreno1XX && m_chipClass <= UnknownAdreno; 1381 } 1382 1383 bool GLPlatform::isPanfrost() const 1384 { 1385 return m_chipClass >= MaliT7XX && m_chipClass <= UnknownPanfrost; 1386 } 1387 1388 bool GLPlatform::isLima() const 1389 { 1390 return m_chipClass >= Mali400 && m_chipClass <= UnknownLima; 1391 } 1392 1393 bool GLPlatform::isVideoCore4() const 1394 { 1395 return m_chipClass >= VC4_2_1 && m_chipClass <= UnknownVideoCore4; 1396 } 1397 1398 bool GLPlatform::isVideoCore3D() const 1399 { 1400 return m_chipClass >= V3D_4_2 && m_chipClass <= UnknownVideoCore3D; 1401 } 1402 1403 const QByteArray &GLPlatform::glRendererString() const 1404 { 1405 return m_renderer; 1406 } 1407 1408 const QByteArray &GLPlatform::glVendorString() const 1409 { 1410 return m_vendor; 1411 } 1412 1413 const QByteArray &GLPlatform::glVersionString() const 1414 { 1415 return m_version; 1416 } 1417 1418 const QByteArray &GLPlatform::glShadingLanguageVersionString() const 1419 { 1420 return m_glsl_version; 1421 } 1422 1423 bool GLPlatform::isLooseBinding() const 1424 { 1425 return m_looseBinding; 1426 } 1427 1428 bool GLPlatform::isVirtualMachine() const 1429 { 1430 return m_virtualMachine; 1431 } 1432 1433 CompositingType GLPlatform::recommendedCompositor() const 1434 { 1435 return m_recommendedCompositor; 1436 } 1437 1438 bool GLPlatform::preferBufferSubData() const 1439 { 1440 return m_preferBufferSubData; 1441 } 1442 1443 OpenGLPlatformInterface GLPlatform::platformInterface() const 1444 { 1445 return m_platformInterface; 1446 } 1447 1448 bool GLPlatform::isGLES() const 1449 { 1450 return m_gles; 1451 } 1452 1453 void GLPlatform::cleanup() 1454 { 1455 s_platform.reset(); 1456 } 1457 1458 } // namespace KWin