2010-11-12 08:30:38 +03:00
/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project .
Copyright ( C ) 2010 Fredrik H ö glund < fredrik @ kde . org >
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "kwinglplatform.h"
2018-03-06 06:55:13 +03:00
// include kwinglutils_funcs.h to avoid the redeclaration issues
// between qopengl.h and epoxy/gl.h
# include "kwinglutils_funcs.h"
2016-08-05 09:46:38 +03:00
# include <epoxy/gl.h>
2010-11-12 08:30:38 +03:00
# include <QRegExp>
# include <QStringList>
# include <QDebug>
2015-10-30 15:47:16 +03:00
# include <QOpenGLContext>
2010-11-12 08:30:38 +03:00
# include <sys/utsname.h>
2010-11-28 20:07:23 +03:00
# include <iostream>
# include <iomanip>
2010-12-05 00:10:49 +03:00
# include <ios>
2010-11-28 20:07:23 +03:00
2010-11-12 08:30:38 +03:00
namespace KWin
{
GLPlatform * GLPlatform : : s_platform = 0 ;
static qint64 parseVersionString ( const QByteArray & version )
{
// Skip any leading non digit
int start = 0 ;
2013-07-23 09:02:52 +04:00
while ( start < version . length ( ) & & ! QChar : : fromLatin1 ( version [ start ] ) . isDigit ( ) )
2010-11-12 08:30:38 +03:00
start + + ;
// Strip any non digit, non '.' characters from the end
int end = start ;
2013-07-23 09:02:52 +04:00
while ( end < version . length ( ) & & ( version [ end ] = = ' . ' | | QChar : : fromLatin1 ( version [ end ] ) . isDigit ( ) ) )
2010-11-12 08:30:38 +03:00
end + + ;
2011-02-23 08:15:21 +03:00
const QByteArray result = version . mid ( start , end - start ) ;
2010-11-12 08:30:38 +03:00
const QList < QByteArray > tokens = result . split ( ' . ' ) ;
const qint64 major = tokens . at ( 0 ) . toInt ( ) ;
const qint64 minor = tokens . count ( ) > 1 ? tokens . at ( 1 ) . toInt ( ) : 0 ;
const qint64 patch = tokens . count ( ) > 2 ? tokens . at ( 2 ) . toInt ( ) : 0 ;
return kVersionNumber ( major , minor , patch ) ;
}
static qint64 getXServerVersion ( )
{
qint64 major , minor , patch ;
2016-08-23 12:43:43 +03:00
major = 0 ;
minor = 0 ;
patch = 0 ;
if ( xcb_connection_t * c = connection ( ) ) {
auto setup = xcb_get_setup ( c ) ;
const QByteArray vendorName ( xcb_setup_vendor ( setup ) , xcb_setup_vendor_length ( setup ) ) ;
if ( vendorName . contains ( " X.Org " ) ) {
const int release = setup - > release_number ;
major = ( release / 10000000 ) ;
minor = ( release / 100000 ) % 100 ;
patch = ( release / 1000 ) % 100 ;
}
2010-11-12 08:30:38 +03:00
}
return kVersionNumber ( major , minor , patch ) ;
}
static qint64 getKernelVersion ( )
{
struct utsname name ;
uname ( & name ) ;
2015-11-05 17:14:06 +03:00
if ( qstrcmp ( name . sysname , " Linux " ) = = 0 )
2010-11-12 08:30:38 +03:00
return parseVersionString ( name . release ) ;
return 0 ;
}
// Extracts the portion of a string that matches a regular expression
static QString extract ( const QString & string , const QString & match , int offset = 0 )
{
QString result ;
QRegExp rx ( match ) ;
int pos = rx . indexIn ( string , offset ) ;
if ( pos ! = - 1 )
2011-01-30 17:34:42 +03:00
result = string . mid ( pos , rx . matchedLength ( ) ) ;
2010-11-12 08:30:38 +03:00
return result ;
}
2015-11-05 17:14:06 +03:00
static ChipClass detectRadeonClass ( const QByteArray & chipset )
2010-11-12 08:30:38 +03:00
{
if ( chipset . isEmpty ( ) )
return UnknownRadeon ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " R100 " ) | |
chipset . contains ( " RV100 " ) | |
chipset . contains ( " RS100 " ) )
2010-11-12 08:30:38 +03:00
return R100 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " RV200 " ) | |
chipset . contains ( " RS200 " ) | |
chipset . contains ( " R200 " ) | |
chipset . contains ( " RV250 " ) | |
chipset . contains ( " RS300 " ) | |
chipset . contains ( " RV280 " ) )
2010-11-12 08:30:38 +03:00
return R200 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " R300 " ) | |
chipset . contains ( " R350 " ) | |
chipset . contains ( " R360 " ) | |
chipset . contains ( " RV350 " ) | |
chipset . contains ( " RV370 " ) | |
chipset . contains ( " RV380 " ) )
2010-11-12 08:30:38 +03:00
return R300 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " R420 " ) | |
chipset . contains ( " R423 " ) | |
chipset . contains ( " R430 " ) | |
chipset . contains ( " R480 " ) | |
chipset . contains ( " R481 " ) | |
chipset . contains ( " RV410 " ) | |
chipset . contains ( " RS400 " ) | |
chipset . contains ( " RC410 " ) | |
chipset . contains ( " RS480 " ) | |
chipset . contains ( " RS482 " ) | |
chipset . contains ( " RS600 " ) | |
chipset . contains ( " RS690 " ) | |
chipset . contains ( " RS740 " ) )
2010-11-12 08:30:38 +03:00
return R400 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " RV515 " ) | |
chipset . contains ( " R520 " ) | |
chipset . contains ( " RV530 " ) | |
chipset . contains ( " R580 " ) | |
chipset . contains ( " RV560 " ) | |
chipset . contains ( " RV570 " ) )
2010-11-12 08:30:38 +03:00
return R500 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " R600 " ) | |
chipset . contains ( " RV610 " ) | |
chipset . contains ( " RV630 " ) | |
chipset . contains ( " RV670 " ) | |
chipset . contains ( " RV620 " ) | |
chipset . contains ( " RV635 " ) | |
chipset . contains ( " RS780 " ) | |
chipset . contains ( " RS880 " ) )
2010-11-12 08:30:38 +03:00
return R600 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " R700 " ) | |
chipset . contains ( " RV770 " ) | |
chipset . contains ( " RV730 " ) | |
chipset . contains ( " RV710 " ) | |
chipset . contains ( " RV740 " ) )
2010-11-12 08:30:38 +03:00
return R700 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " EVERGREEN " ) | | // Not an actual chipset, but returned by R600G in 7.9
chipset . contains ( " CEDAR " ) | |
chipset . contains ( " REDWOOD " ) | |
chipset . contains ( " JUNIPER " ) | |
chipset . contains ( " CYPRESS " ) | |
chipset . contains ( " HEMLOCK " ) | |
chipset . contains ( " PALM " ) )
2010-11-12 08:30:38 +03:00
return Evergreen ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( " SUMO " ) | |
chipset . contains ( " SUMO2 " ) | |
chipset . contains ( " BARTS " ) | |
chipset . contains ( " TURKS " ) | |
chipset . contains ( " CAICOS " ) | |
chipset . contains ( " CAYMAN " ) )
2011-01-11 23:14:06 +03:00
return NorthernIslands ;
2015-11-05 17:14:06 +03:00
const QString chipset16 = QString : : fromLatin1 ( chipset ) ;
QString name = extract ( chipset16 , QStringLiteral ( " HD [0-9]{4} " ) ) ; // HD followed by a space and 4 digits
2010-12-04 00:23:03 +03:00
if ( ! name . isEmpty ( ) ) {
2015-11-05 17:14:06 +03:00
const int id = name . rightRef ( 4 ) . toInt ( ) ;
2011-01-30 17:34:42 +03:00
if ( id = = 6250 | | id = = 6310 ) // Palm
2010-11-12 08:30:38 +03:00
return Evergreen ;
2010-12-04 00:23:03 +03:00
if ( id > = 6000 & & id < 7000 )
return NorthernIslands ; // HD 6xxx
if ( id > = 5000 & & id < 6000 )
return Evergreen ; // HD 5xxx
if ( id > = 4000 & & id < 5000 )
return R700 ; // HD 4xxx
2011-01-30 17:34:42 +03:00
if ( id > = 2000 & & id < 4000 ) // HD 2xxx/3xxx
2010-11-12 08:30:38 +03:00
return R600 ;
2010-12-04 00:23:03 +03:00
return UnknownRadeon ;
2010-11-12 08:30:38 +03:00
}
2015-11-05 17:14:06 +03:00
name = extract ( chipset16 , QStringLiteral ( " X[0-9]{3,4} " ) ) ; // X followed by 3-4 digits
2010-11-12 08:30:38 +03:00
if ( ! name . isEmpty ( ) ) {
2015-11-05 17:14:06 +03:00
const int id = name . midRef ( 1 , - 1 ) . toInt ( ) ;
2010-11-12 08:30:38 +03:00
// X1xxx
if ( id > = 1300 )
return R500 ;
// X7xx, X8xx, X12xx, 2100
if ( ( id > = 700 & & id < 1000 ) | | id > = 1200 )
return R400 ;
// X200, X3xx, X5xx, X6xx, X10xx, X11xx
if ( ( id > = 300 & & id < 700 ) | | ( id > = 1000 & & id < 1200 ) )
return R300 ;
return UnknownRadeon ;
}
2015-11-05 17:14:06 +03:00
name = extract ( chipset16 , QStringLiteral ( " \\ b[0-9]{4} \\ b " ) ) ; // A group of 4 digits
2010-11-12 08:30:38 +03:00
if ( ! name . isEmpty ( ) ) {
const int id = name . toInt ( ) ;
// 7xxx
if ( id > = 7000 & & id < 8000 )
return R100 ;
// 8xxx, 9xxx
if ( id > = 8000 & & id < 9500 )
return R200 ;
// 9xxx
if ( id > = 9500 )
return R300 ;
if ( id = = 2100 )
return R400 ;
}
return UnknownRadeon ;
}
static ChipClass detectNVidiaClass ( const QString & chipset )
{
2013-07-23 09:02:52 +04:00
QString name = extract ( chipset , QStringLiteral ( " \\ bNV[0-9,A-F]{2} \\ b " ) ) ; // NV followed by two hexadecimal digits
2011-01-30 17:34:42 +03:00
if ( ! name . isEmpty ( ) ) {
2015-11-05 17:14:06 +03:00
const int id = chipset . midRef ( 2 , - 1 ) . toInt ( 0 , 16 ) ; // Strip the 'NV' from the id
2010-11-12 08:30:38 +03:00
2011-01-30 17:34:42 +03:00
switch ( id & 0xf0 ) {
2010-11-12 08:30:38 +03:00
case 0x00 :
case 0x10 :
return NV10 ;
case 0x20 :
return NV20 ;
case 0x30 :
return NV30 ;
case 0x40 :
case 0x60 :
return NV40 ;
case 0x50 :
case 0x80 :
case 0x90 :
case 0xA0 :
return G80 ;
default :
return UnknownNVidia ;
2011-01-30 17:34:42 +03:00
}
2010-11-12 08:30:38 +03:00
}
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( QLatin1String ( " GeForce2 " ) ) | | chipset . contains ( QLatin1String ( " GeForce 256 " ) ) )
2010-12-04 02:26:30 +03:00
return NV10 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( QLatin1String ( " GeForce3 " ) ) )
2010-12-04 02:26:30 +03:00
return NV20 ;
2015-11-05 17:14:06 +03:00
if ( chipset . contains ( QLatin1String ( " GeForce4 " ) ) ) {
if ( chipset . contains ( QLatin1String ( " MX 420 " ) ) | |
chipset . contains ( QLatin1String ( " MX 440 " ) ) | | // including MX 440SE
chipset . contains ( QLatin1String ( " MX 460 " ) ) | |
chipset . contains ( QLatin1String ( " MX 4000 " ) ) | |
chipset . contains ( QLatin1String ( " PCX 4300 " ) ) )
2010-12-04 02:26:30 +03:00
return NV10 ;
return NV20 ;
}
// GeForce 5,6,7,8,9
2013-07-23 09:02:52 +04:00
name = extract ( chipset , QStringLiteral ( " GeForce (FX |PCX |Go )? \\ d{4}(M| \\ b) " ) ) . trimmed ( ) ;
2010-12-04 02:26:30 +03:00
if ( ! name . isEmpty ( ) ) {
if ( ! name [ name . length ( ) - 1 ] . isDigit ( ) )
name . chop ( 1 ) ;
2015-11-05 17:14:06 +03:00
const int id = name . rightRef ( 4 ) . toInt ( ) ;
2010-12-04 02:26:30 +03:00
if ( id < 6000 )
return NV30 ;
if ( id > = 6000 & & id < 8000 )
return NV40 ;
if ( id > = 8000 )
return G80 ;
return UnknownNVidia ;
}
// GeForce 100/200/300/400/500
2013-07-23 09:02:52 +04:00
name = extract ( chipset , QStringLiteral ( " GeForce (G |GT |GTX |GTS )? \\ d{3}(M| \\ b) " ) ) . trimmed ( ) ;
2010-12-04 02:26:30 +03:00
if ( ! name . isEmpty ( ) ) {
if ( ! name [ name . length ( ) - 1 ] . isDigit ( ) )
name . chop ( 1 ) ;
2015-11-05 17:14:06 +03:00
const int id = name . rightRef ( 3 ) . toInt ( ) ;
2010-12-04 02:26:30 +03:00
if ( id > = 100 & & id < 600 ) {
if ( id > = 400 )
return GF100 ;
return G80 ;
}
return UnknownNVidia ;
2011-01-30 17:34:42 +03:00
}
2010-12-04 02:26:30 +03:00
2010-11-12 08:30:38 +03:00
return UnknownNVidia ;
}
2015-11-05 17:14:06 +03:00
static inline ChipClass detectNVidiaClass ( const QByteArray & chipset )
{
return detectNVidiaClass ( QString : : fromLatin1 ( chipset ) ) ;
}
2010-11-12 08:30:38 +03:00
static ChipClass detectIntelClass ( const QByteArray & chipset )
{
2012-10-13 10:35:30 +04:00
// see mesa repository: src/mesa/drivers/dri/intel/intel_context.c
2010-11-12 08:30:38 +03:00
// GL 1.3, DX8? SM ?
if ( chipset . contains ( " 845G " ) | |
2011-01-30 17:34:42 +03:00
chipset . contains ( " 830M " ) | |
chipset . contains ( " 852GM/855GM " ) | |
chipset . contains ( " 865G " ) )
2010-11-12 08:30:38 +03:00
return I8XX ;
// GL 1.4, DX 9.0, SM 2.0
if ( chipset . contains ( " 915G " ) | |
2011-01-30 17:34:42 +03:00
chipset . contains ( " E7221G " ) | |
chipset . contains ( " 915GM " ) | |
chipset . contains ( " 945G " ) | | // DX 9.0c
chipset . contains ( " 945GM " ) | |
chipset . contains ( " 945GME " ) | |
chipset . contains ( " Q33 " ) | | // GL1.5
chipset . contains ( " Q35 " ) | |
chipset . contains ( " G33 " ) | |
chipset . contains ( " 965Q " ) | | // GMA 3000, but apparently considered gen 4 by the driver
chipset . contains ( " 946GZ " ) | | // GMA 3000, but apparently considered gen 4 by the driver
chipset . contains ( " IGD " ) )
2010-11-12 08:30:38 +03:00
return I915 ;
// GL 2.0, DX 9.0c, SM 3.0
if ( chipset . contains ( " 965G " ) | |
2011-01-30 17:34:42 +03:00
chipset . contains ( " G45/G43 " ) | | // SM 4.0
chipset . contains ( " 965GM " ) | | // GL 2.1
chipset . contains ( " 965GME/GLE " ) | |
chipset . contains ( " GM45 " ) | |
chipset . contains ( " Q45/Q43 " ) | |
chipset . contains ( " G41 " ) | |
chipset . contains ( " B43 " ) | |
2012-02-04 14:21:32 +04:00
chipset . contains ( " Ironlake " ) )
2010-11-12 08:30:38 +03:00
return I965 ;
2012-02-04 14:21:32 +04:00
// GL 3.1, CL 1.1, DX 10.1
if ( chipset . contains ( " Sandybridge " ) ) {
return SandyBridge ;
}
2012-10-13 10:35:30 +04:00
// GL4.0, CL1.1, DX11, SM 5.0
if ( chipset . contains ( " Ivybridge " ) ) {
return IvyBridge ;
}
// GL4.0, CL1.2, DX11.1, SM 5.0
if ( chipset . contains ( " Haswell " ) ) {
return Haswell ;
}
2010-11-12 08:30:38 +03:00
return UnknownIntel ;
}
2016-08-12 10:57:41 +03:00
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 ;
}
2012-03-04 18:10:45 +04:00
QString GLPlatform : : versionToString ( qint64 version )
2015-11-05 17:14:06 +03:00
{
return QString : : fromLatin1 ( versionToString8 ( version ) ) ;
}
QByteArray GLPlatform : : versionToString8 ( qint64 version )
2010-11-28 20:07:23 +03:00
{
int major = ( version > > 32 ) ;
int minor = ( version > > 16 ) & 0xffff ;
int patch = version & 0xffff ;
2015-11-05 17:14:06 +03:00
QByteArray string = QByteArray : : number ( major ) + ' . ' + QByteArray : : number ( minor ) ;
2010-11-28 20:07:23 +03:00
if ( patch ! = 0 )
2015-11-05 17:14:06 +03:00
string + = ' . ' + QByteArray : : number ( patch ) ;
2010-11-28 20:07:23 +03:00
return string ;
}
2012-03-04 18:10:45 +04:00
QString GLPlatform : : driverToString ( Driver driver )
2015-11-05 17:14:06 +03:00
{
return QString : : fromLatin1 ( driverToString8 ( driver ) ) ;
}
QByteArray GLPlatform : : driverToString8 ( Driver driver )
2010-11-28 20:07:23 +03:00
{
2011-01-30 17:34:42 +03:00
switch ( driver ) {
2010-11-28 20:07:23 +03:00
case Driver_R100 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Radeon " ) ;
2010-11-28 20:07:23 +03:00
case Driver_R200 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R200 " ) ;
2010-11-28 20:07:23 +03:00
case Driver_R300C :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R300C " ) ;
2010-11-28 20:07:23 +03:00
case Driver_R300G :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R300G " ) ;
2010-11-28 20:07:23 +03:00
case Driver_R600C :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R600C " ) ;
2010-11-28 20:07:23 +03:00
case Driver_R600G :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R600G " ) ;
2010-11-28 20:07:23 +03:00
case Driver_Nouveau :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Nouveau " ) ;
2010-11-28 20:07:23 +03:00
case Driver_Intel :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Intel " ) ;
2010-11-28 20:07:23 +03:00
case Driver_NVidia :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " NVIDIA " ) ;
2010-11-28 20:07:23 +03:00
case Driver_Catalyst :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Catalyst " ) ;
2010-11-28 20:07:23 +03:00
case Driver_Swrast :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Software rasterizer " ) ;
2010-11-28 20:07:23 +03:00
case Driver_Softpipe :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " softpipe " ) ;
2010-11-28 20:07:23 +03:00
case Driver_Llvmpipe :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " LLVMpipe " ) ;
2012-10-13 12:33:38 +04:00
case Driver_VirtualBox :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " VirtualBox (Chromium) " ) ;
2012-10-13 18:40:17 +04:00
case Driver_VMware :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " VMware (SVGA3D) " ) ;
2016-08-12 10:57:41 +03:00
case Driver_Qualcomm :
return QByteArrayLiteral ( " Qualcomm " ) ;
2010-11-28 20:07:23 +03:00
default :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Unknown " ) ;
2010-11-28 20:07:23 +03:00
}
}
2012-03-04 18:10:45 +04:00
QString GLPlatform : : chipClassToString ( ChipClass chipClass )
2015-11-05 17:14:06 +03:00
{
return QString : : fromLatin1 ( chipClassToString8 ( chipClass ) ) ;
}
QByteArray GLPlatform : : chipClassToString8 ( ChipClass chipClass )
2010-11-28 20:07:23 +03:00
{
2011-01-30 17:34:42 +03:00
switch ( chipClass ) {
2010-11-28 20:07:23 +03:00
case R100 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R100 " ) ;
2010-11-28 20:07:23 +03:00
case R200 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R200 " ) ;
2010-11-28 20:07:23 +03:00
case R300 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R300 " ) ;
2010-11-28 20:07:23 +03:00
case R400 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R400 " ) ;
2010-11-28 20:07:23 +03:00
case R500 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R500 " ) ;
2010-11-28 20:07:23 +03:00
case R600 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R600 " ) ;
2010-11-28 20:07:23 +03:00
case R700 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " R700 " ) ;
2010-11-28 20:07:23 +03:00
case Evergreen :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " EVERGREEN " ) ;
2010-11-28 20:07:23 +03:00
case NorthernIslands :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " NI " ) ;
2010-11-28 20:07:23 +03:00
case NV10 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " NV10 " ) ;
2010-11-28 20:07:23 +03:00
case NV20 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " NV20 " ) ;
2010-11-28 20:07:23 +03:00
case NV30 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " NV30 " ) ;
2010-11-28 20:07:23 +03:00
case NV40 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " NV40/G70 " ) ;
2010-11-28 20:07:23 +03:00
case G80 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " G80/G90 " ) ;
2010-11-28 20:07:23 +03:00
case GF100 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " GF100 " ) ;
2010-11-28 20:07:23 +03:00
case I8XX :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " i830/i835 " ) ;
2010-11-28 20:07:23 +03:00
case I915 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " i915/i945 " ) ;
2010-11-28 20:07:23 +03:00
case I965 :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " i965 " ) ;
2010-11-28 20:07:23 +03:00
case SandyBridge :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " SandyBridge " ) ;
2012-10-13 10:35:30 +04:00
case IvyBridge :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " IvyBridge " ) ;
2012-10-13 10:35:30 +04:00
case Haswell :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Haswell " ) ;
2010-11-28 20:07:23 +03:00
2016-08-12 10:57:41 +03:00
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 " ) ;
2010-11-28 20:07:23 +03:00
default :
2015-11-05 17:14:06 +03:00
return QByteArrayLiteral ( " Unknown " ) ;
2010-11-28 20:07:23 +03:00
}
}
2010-11-12 08:30:38 +03:00
// -------
GLPlatform : : GLPlatform ( )
: m_driver ( Driver_Unknown ) ,
m_chipClass ( UnknownChipClass ) ,
2012-10-05 20:00:49 +04:00
m_recommendedCompositor ( XRenderCompositing ) ,
2016-08-04 18:10:46 +03:00
m_glVersion ( 0 ) ,
m_glslVersion ( 0 ) ,
2010-11-12 08:30:38 +03:00
m_mesaVersion ( 0 ) ,
2016-08-04 18:10:46 +03:00
m_driverVersion ( 0 ) ,
2010-11-12 08:30:38 +03:00
m_galliumVersion ( 0 ) ,
2016-08-04 18:10:46 +03:00
m_serverVersion ( 0 ) ,
m_kernelVersion ( 0 ) ,
2010-11-12 08:30:38 +03:00
m_looseBinding ( false ) ,
m_supportsGLSL ( false ) ,
2012-06-13 03:03:41 +04:00
m_limitedGLSL ( false ) ,
m_textureNPOT ( false ) ,
2012-10-13 12:33:38 +04:00
m_limitedNPOT ( false ) ,
2014-04-22 11:27:05 +04:00
m_virtualMachine ( false ) ,
2016-08-04 18:10:46 +03:00
m_preferBufferSubData ( false ) ,
2015-11-02 12:43:48 +03:00
m_platformInterface ( NoOpenGLPlatformInterface ) ,
m_gles ( false )
2010-11-12 08:30:38 +03:00
{
}
GLPlatform : : ~ GLPlatform ( )
{
}
2012-09-29 15:19:35 +04:00
void GLPlatform : : detect ( OpenGLPlatformInterface platformInterface )
2010-11-12 08:30:38 +03:00
{
2014-04-22 11:27:05 +04:00
m_platformInterface = platformInterface ;
2010-11-12 08:30:38 +03:00
m_vendor = ( const char * ) glGetString ( GL_VENDOR ) ;
m_renderer = ( const char * ) glGetString ( GL_RENDERER ) ;
m_version = ( const char * ) glGetString ( GL_VERSION ) ;
// Parse the OpenGL version
const QList < QByteArray > versionTokens = m_version . split ( ' ' ) ;
if ( versionTokens . count ( ) > 0 ) {
2011-02-23 08:15:21 +03:00
const QByteArray version = QByteArray ( m_version ) ;
2010-11-12 08:30:38 +03:00
m_glVersion = parseVersionString ( version ) ;
2015-11-02 12:43:48 +03:00
if ( platformInterface = = EglPlatformInterface ) {
// only EGL can have OpenGLES, GLX is OpenGL only
if ( version . startsWith ( " OpenGL ES " ) ) {
// from GLES 2: "Returns a version or release number of the form OpenGL<space>ES<space><version number><space><vendor-specific information>."
// 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"
m_gles = true ;
}
}
2010-11-12 08:30:38 +03:00
}
2015-10-30 12:20:42 +03:00
if ( ! isGLES ( ) & & m_glVersion > = kVersionNumber ( 3 , 0 ) ) {
2013-03-13 19:39:26 +04:00
int count ;
glGetIntegerv ( GL_NUM_EXTENSIONS , & count ) ;
for ( int i = 0 ; i < count ; i + + ) {
const char * name = ( const char * ) glGetStringi ( GL_EXTENSIONS , i ) ;
m_extensions . insert ( name ) ;
}
2015-10-30 12:20:42 +03:00
} else {
2013-03-13 19:39:26 +04:00
const QByteArray extensions = ( const char * ) glGetString ( GL_EXTENSIONS ) ;
m_extensions = QSet < QByteArray > : : fromList ( extensions . split ( ' ' ) ) ;
}
2010-11-12 08:30:38 +03:00
// Parse the Mesa version
const int mesaIndex = versionTokens . indexOf ( " Mesa " ) ;
if ( mesaIndex ! = - 1 ) {
const QByteArray version = versionTokens . at ( mesaIndex + 1 ) ;
m_mesaVersion = parseVersionString ( version ) ;
}
2016-11-22 09:44:37 +03:00
if ( isGLES ( ) ) {
m_supportsGLSL = true ;
m_textureNPOT = true ;
} else {
2014-03-16 13:31:04 +04:00
m_supportsGLSL = m_extensions . contains ( " GL_ARB_shader_objects " ) & &
2013-03-13 20:00:17 +04:00
m_extensions . contains ( " GL_ARB_fragment_shader " ) & &
m_extensions . contains ( " GL_ARB_vertex_shader " ) ;
2010-11-12 08:30:38 +03:00
2012-09-29 15:19:35 +04:00
m_textureNPOT = m_extensions . contains ( " GL_ARB_texture_non_power_of_two " ) ;
}
2010-12-12 14:07:56 +03:00
m_serverVersion = getXServerVersion ( ) ;
m_kernelVersion = getKernelVersion ( ) ;
2010-11-19 00:47:29 +03:00
2010-11-28 20:16:45 +03:00
m_glslVersion = 0 ;
2015-11-05 17:14:06 +03:00
m_glsl_version . clear ( ) ;
2010-11-28 20:16:45 +03:00
if ( m_supportsGLSL ) {
// Parse the GLSL version
m_glsl_version = ( const char * ) glGetString ( GL_SHADING_LANGUAGE_VERSION ) ;
2011-02-23 08:15:21 +03:00
m_glslVersion = parseVersionString ( m_glsl_version ) ;
2010-11-28 20:16:45 +03:00
}
2015-11-05 17:14:06 +03:00
m_chipset = QByteArrayLiteral ( " Unknown " ) ;
2013-06-28 22:04:33 +04:00
m_preferBufferSubData = false ;
2010-11-12 08:30:38 +03:00
// Mesa classic drivers
// ====================================================
// Radeon
if ( m_renderer . startsWith ( " Mesa DRI R " ) ) {
// Sample renderer string: Mesa DRI R600 (RV740 94B3) 20090101 x86/MMX/SSE2 TCL DRI2
const QList < QByteArray > tokens = m_renderer . split ( ' ' ) ;
const QByteArray chipClass = tokens . at ( 2 ) ;
m_chipset = tokens . at ( 3 ) . mid ( 1 , - 1 ) ; // Strip the leading '('
if ( chipClass = = " R100 " )
// Vendor: Tungsten Graphics, Inc.
m_driver = Driver_R100 ;
else if ( chipClass = = " R200 " )
// Vendor: Tungsten Graphics, Inc.
m_driver = Driver_R200 ;
else if ( chipClass = = " R300 " )
// Vendor: DRI R300 Project
m_driver = Driver_R300C ;
else if ( chipClass = = " R600 " )
// Vendor: Advanced Micro Devices, Inc.
m_driver = Driver_R600C ;
2015-11-05 17:14:06 +03:00
m_chipClass = detectRadeonClass ( m_chipset ) ;
2010-11-12 08:30:38 +03:00
}
// Intel
else if ( m_renderer . contains ( " Intel " ) ) {
2011-01-30 17:34:42 +03:00
// Vendor: Tungsten Graphics, Inc.
2010-11-12 08:30:38 +03:00
// Sample renderer string: Mesa DRI Mobile Intel® GM45 Express Chipset GEM 20100328 2010Q1
QByteArray chipset ;
if ( m_renderer . startsWith ( " Intel(R) Integrated Graphics Device " ) )
chipset = " IGD " ;
else
chipset = m_renderer ;
m_driver = Driver_Intel ;
m_chipClass = detectIntelClass ( chipset ) ;
2011-01-30 17:34:42 +03:00
}
2010-11-12 08:30:38 +03:00
2017-12-24 01:30:07 +03:00
// Properietary drivers
// ====================================================
else if ( m_vendor = = " ATI Technologies Inc. " ) {
m_chipClass = detectRadeonClass ( m_renderer ) ;
m_driver = Driver_Catalyst ;
if ( versionTokens . count ( ) > 1 & & versionTokens . at ( 2 ) [ 0 ] = = ' ( ' )
m_driverVersion = parseVersionString ( versionTokens . at ( 1 ) ) ;
else if ( versionTokens . count ( ) > 0 )
m_driverVersion = parseVersionString ( versionTokens . at ( 0 ) ) ;
else
m_driverVersion = 0 ;
}
else if ( m_vendor = = " NVIDIA Corporation " ) {
m_chipClass = detectNVidiaClass ( m_renderer ) ;
m_driver = Driver_NVidia ;
int index = versionTokens . indexOf ( " NVIDIA " ) ;
if ( versionTokens . count ( ) > index )
m_driverVersion = parseVersionString ( versionTokens . at ( index + 1 ) ) ;
else
m_driverVersion = 0 ;
}
else if ( m_vendor = = " Qualcomm " ) {
m_driver = Driver_Qualcomm ;
m_chipClass = detectQualcommClass ( m_renderer ) ;
}
else if ( m_renderer = = " Software Rasterizer " ) {
m_driver = Driver_Swrast ;
}
// Virtual Hardware
// ====================================================
else if ( m_vendor = = " Humper " & & m_renderer = = " Chromium " ) {
// Virtual Box
m_driver = Driver_VirtualBox ;
const int index = versionTokens . indexOf ( " Chromium " ) ;
if ( versionTokens . count ( ) > index )
m_driverVersion = parseVersionString ( versionTokens . at ( index + 1 ) ) ;
else
m_driverVersion = 0 ;
}
2010-11-12 08:30:38 +03:00
// Gallium drivers
// ====================================================
2017-12-24 01:30:07 +03:00
else {
2010-11-12 08:30:38 +03:00
const QList < QByteArray > tokens = m_renderer . split ( ' ' ) ;
2017-12-24 01:30:07 +03:00
if ( m_renderer . contains ( " Gallium " ) ) {
// Sample renderer string: Gallium 0.4 on AMD RV740
m_galliumVersion = parseVersionString ( tokens . at ( 1 ) ) ;
m_chipset = ( tokens . at ( 3 ) = = " AMD " | | tokens . at ( 3 ) = = " ATI " ) ?
tokens . at ( 4 ) : tokens . at ( 3 ) ;
}
else {
// The renderer string does not contain "Gallium" anymore.
m_chipset = tokens . at ( 0 ) ;
// We don't know the actual version anymore, but it's at least 0.4.
m_galliumVersion = kVersionNumber ( 0 , 4 , 0 ) ;
}
2010-11-12 08:30:38 +03:00
// R300G
2015-11-05 17:14:06 +03:00
if ( m_vendor = = QByteArrayLiteral ( " X.Org R300 Project " ) ) {
m_chipClass = detectRadeonClass ( m_chipset ) ;
2010-11-12 08:30:38 +03:00
m_driver = Driver_R300G ;
}
// R600G
else if ( m_vendor = = " X.Org " & &
2011-01-30 17:34:42 +03:00
( 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 " ) | |
2011-07-15 20:56:15 +04:00
m_renderer . contains ( " SUMO " ) | |
m_renderer . contains ( " SUMO2 " ) | |
2011-01-30 17:34:42 +03:00
m_renderer . contains ( " BARTS " ) | |
m_renderer . contains ( " TURKS " ) | |
2011-07-15 20:56:15 +04:00
m_renderer . contains ( " CAICOS " ) | |
m_renderer . contains ( " CAYMAN " ) ) ) {
2015-11-05 17:14:06 +03:00
m_chipClass = detectRadeonClass ( m_chipset ) ;
2010-11-12 08:30:38 +03:00
m_driver = Driver_R600G ;
}
// Nouveau
else if ( m_vendor = = " nouveau " ) {
2015-11-05 17:14:06 +03:00
m_chipClass = detectNVidiaClass ( m_chipset ) ;
2010-11-12 08:30:38 +03:00
m_driver = Driver_Nouveau ;
}
2011-05-06 20:13:54 +04:00
// softpipe
else if ( m_vendor = = " VMware, Inc. " & & m_chipset = = " softpipe " ) {
m_driver = Driver_Softpipe ;
}
// llvmpipe
else if ( m_vendor = = " VMware, Inc. " & & m_chipset = = " llvmpipe " ) {
m_driver = Driver_Llvmpipe ;
2010-11-12 08:30:38 +03:00
}
2012-10-13 18:40:17 +04:00
// SVGA3D
else if ( m_vendor = = " VMware, Inc. " & & m_chipset . contains ( " SVGA3D " ) ) {
m_driver = Driver_VMware ;
}
2011-01-30 17:34:42 +03:00
}
2010-11-12 08:30:38 +03:00
// Driver/GPU specific features
// ====================================================
if ( isRadeon ( ) ) {
// R200 technically has a programmable pipeline, but since it's SM 1.4,
// it's too limited to to be of any practical value to us.
if ( m_chipClass < R300 )
m_supportsGLSL = false ;
2010-11-19 00:47:29 +03:00
m_limitedGLSL = false ;
m_limitedNPOT = false ;
if ( m_chipClass < R600 ) {
if ( driver ( ) = = Driver_Catalyst )
m_textureNPOT = m_limitedNPOT = false ; // Software fallback
else if ( driver ( ) = = Driver_R300G )
m_limitedNPOT = m_textureNPOT ;
m_limitedGLSL = m_supportsGLSL ;
}
2010-11-12 08:30:38 +03:00
2012-10-05 20:00:49 +04:00
if ( m_chipClass < R300 ) {
// fallback to XRender for R100 and R200
m_recommendedCompositor = XRenderCompositing ;
} else if ( m_chipClass < R600 ) {
2014-02-25 14:02:32 +04:00
// XRender due to NPOT limitations not supported by KWin's shaders
m_recommendedCompositor = XRenderCompositing ;
2012-10-05 20:00:49 +04:00
} else {
m_recommendedCompositor = OpenGL2Compositing ;
}
2010-11-12 08:30:38 +03:00
if ( driver ( ) = = Driver_R600G | |
2011-01-30 17:34:42 +03:00
( driver ( ) = = Driver_R600C & & m_renderer . contains ( " DRI2 " ) ) ) {
2010-11-12 08:30:38 +03:00
m_looseBinding = true ;
}
}
if ( isNvidia ( ) ) {
if ( m_driver = = Driver_NVidia & & m_chipClass < NV40 )
m_supportsGLSL = false ; // High likelihood of software emulation
2013-06-28 22:04:33 +04:00
if ( m_driver = = Driver_NVidia ) {
2010-11-12 08:30:38 +03:00
m_looseBinding = true ;
2013-06-28 22:04:33 +04:00
m_preferBufferSubData = true ;
}
2010-11-12 08:30:38 +03:00
2014-02-25 14:02:32 +04:00
if ( m_chipClass < NV40 ) {
2012-10-05 20:00:49 +04:00
m_recommendedCompositor = XRenderCompositing ;
} else {
m_recommendedCompositor = OpenGL2Compositing ;
}
2010-11-19 00:47:29 +03:00
m_limitedNPOT = m_textureNPOT & & m_chipClass < NV40 ;
2010-11-12 08:30:38 +03:00
m_limitedGLSL = m_supportsGLSL & & m_chipClass < G80 ;
2011-01-30 17:34:42 +03:00
}
2010-11-12 08:30:38 +03:00
if ( isIntel ( ) ) {
if ( m_chipClass < I915 )
m_supportsGLSL = false ;
m_limitedGLSL = m_supportsGLSL & & m_chipClass < I965 ;
2014-06-23 09:45:44 +04:00
// see https://bugs.freedesktop.org/show_bug.cgi?id=80349#c1
m_looseBinding = false ;
2012-10-05 20:00:49 +04:00
2014-03-28 20:52:16 +04:00
if ( m_chipClass < I915 ) {
2014-02-25 14:02:32 +04:00
m_recommendedCompositor = XRenderCompositing ;
2012-10-05 20:00:49 +04:00
} else {
m_recommendedCompositor = OpenGL2Compositing ;
}
2010-11-12 08:30:38 +03:00
}
2011-01-12 01:32:51 +03:00
2012-09-29 15:19:35 +04:00
if ( isMesaDriver ( ) & & platformInterface = = EglPlatformInterface ) {
2011-12-01 13:00:38 +04:00
// According to the reference implementation in
// mesa/demos/src/egl/opengles1/texture_from_pixmap
// the mesa egl implementation does not require a strict binding (so far).
m_looseBinding = true ;
}
2011-05-06 20:13:54 +04:00
if ( isSoftwareEmulation ( ) ) {
2012-10-05 20:00:49 +04:00
if ( m_driver < Driver_Llvmpipe ) {
2016-07-15 15:25:16 +03:00
// we recommend XRender
m_recommendedCompositor = XRenderCompositing ;
2012-10-05 20:00:49 +04:00
// Software emulation does not provide GLSL
m_limitedGLSL = m_supportsGLSL = false ;
} else {
// llvmpipe does support GLSL
2016-07-15 15:25:16 +03:00
m_recommendedCompositor = OpenGL2Compositing ;
2012-10-05 20:00:49 +04:00
m_limitedGLSL = false ;
m_supportsGLSL = true ;
}
}
2016-08-12 10:57:41 +03:00
if ( m_driver = = Driver_Qualcomm ) {
if ( m_chipClass = = Adreno1XX ) {
m_recommendedCompositor = NoCompositing ;
} else {
// all other drivers support at least GLES 2
m_recommendedCompositor = OpenGL2Compositing ;
}
}
2012-10-05 20:00:49 +04:00
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 ;
m_supportsGLSL = true ;
2011-05-06 20:13:54 +04:00
}
2012-10-13 12:33:38 +04:00
if ( isVirtualBox ( ) ) {
m_virtualMachine = true ;
2014-07-22 15:21:23 +04:00
m_recommendedCompositor = OpenGL2Compositing ;
2012-10-13 12:33:38 +04:00
}
2012-10-13 18:40:17 +04:00
if ( isVMware ( ) ) {
m_virtualMachine = true ;
2014-07-22 15:21:23 +04:00
m_recommendedCompositor = OpenGL2Compositing ;
2012-10-13 18:40:17 +04:00
}
2015-11-02 13:13:26 +03:00
// and force back to shader supported on gles, we wouldn't have got a context if not supported
if ( isGLES ( ) ) {
m_supportsGLSL = true ;
m_limitedGLSL = false ;
}
2010-11-12 08:30:38 +03:00
}
2015-11-05 17:14:06 +03:00
static void print ( const QByteArray & label , const QByteArray & setting )
2010-11-28 20:07:23 +03:00
{
std : : cout < < std : : setw ( 40 ) < < std : : left
2015-11-05 17:14:06 +03:00
< < label . data ( ) < < setting . data ( ) < < std : : endl ;
2010-11-28 20:07:23 +03:00
}
void GLPlatform : : printResults ( ) const
{
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " OpenGL vendor string: " ) , m_vendor ) ;
print ( QByteArrayLiteral ( " OpenGL renderer string: " ) , m_renderer ) ;
print ( QByteArrayLiteral ( " OpenGL version string: " ) , m_version ) ;
2010-11-28 20:07:23 +03:00
if ( m_supportsGLSL )
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " OpenGL shading language version string: " ) , m_glsl_version ) ;
2010-11-28 20:07:23 +03:00
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " Driver: " ) , driverToString8 ( m_driver ) ) ;
2010-11-28 20:07:23 +03:00
if ( ! isMesaDriver ( ) )
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " Driver version: " ) , versionToString8 ( m_driverVersion ) ) ;
2010-11-28 20:07:23 +03:00
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " GPU class: " ) , chipClassToString8 ( m_chipClass ) ) ;
2011-01-30 17:34:42 +03:00
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " OpenGL version: " ) , versionToString8 ( m_glVersion ) ) ;
2011-01-11 23:16:50 +03:00
if ( m_supportsGLSL )
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " GLSL version: " ) , versionToString8 ( m_glslVersion ) ) ;
2010-11-28 20:07:23 +03:00
if ( isMesaDriver ( ) )
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " Mesa version: " ) , versionToString8 ( mesaVersion ( ) ) ) ;
2010-11-28 20:07:23 +03:00
//if (galliumVersion() > 0)
// print("Gallium version:", versionToString(m_galliumVersion));
if ( serverVersion ( ) > 0 )
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " X server version: " ) , versionToString8 ( m_serverVersion ) ) ;
2010-11-28 20:07:23 +03:00
if ( kernelVersion ( ) > 0 )
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " Linux kernel version: " ) , versionToString8 ( m_kernelVersion ) ) ;
2010-11-28 20:07:23 +03:00
2015-11-05 17:14:06 +03:00
print ( QByteArrayLiteral ( " Requires strict binding: " ) , ! m_looseBinding ? QByteArrayLiteral ( " yes " ) : QByteArrayLiteral ( " no " ) ) ;
print ( QByteArrayLiteral ( " GLSL shaders: " ) , m_supportsGLSL ? ( m_limitedGLSL ? QByteArrayLiteral ( " limited " ) : QByteArrayLiteral ( " yes " ) ) : QByteArrayLiteral ( " no " ) ) ;
print ( QByteArrayLiteral ( " Texture NPOT support: " ) , m_textureNPOT ? ( m_limitedNPOT ? QByteArrayLiteral ( " limited " ) : QByteArrayLiteral ( " yes " ) ) : QByteArrayLiteral ( " no " ) ) ;
print ( QByteArrayLiteral ( " Virtual Machine: " ) , m_virtualMachine ? QByteArrayLiteral ( " yes " ) : QByteArrayLiteral ( " no " ) ) ;
2010-11-28 20:07:23 +03:00
}
2010-11-12 08:30:38 +03:00
bool GLPlatform : : supports ( GLFeature feature ) const
{
2011-01-30 17:34:42 +03:00
switch ( feature ) {
2010-11-12 08:30:38 +03:00
case LooseBinding :
return m_looseBinding ;
case GLSL :
return m_supportsGLSL ;
case LimitedGLSL :
return m_limitedGLSL ;
2010-11-19 00:47:29 +03:00
case TextureNPOT :
return m_textureNPOT ;
case LimitedNPOT :
return m_limitedNPOT ;
2010-11-12 08:30:38 +03:00
default :
return false ;
}
}
qint64 GLPlatform : : glVersion ( ) const
{
return m_glVersion ;
}
qint64 GLPlatform : : glslVersion ( ) const
{
2011-02-19 16:03:04 +03:00
return m_glslVersion ;
2010-11-12 08:30:38 +03:00
}
qint64 GLPlatform : : mesaVersion ( ) const
{
return m_mesaVersion ;
}
qint64 GLPlatform : : galliumVersion ( ) const
{
return m_galliumVersion ;
}
qint64 GLPlatform : : serverVersion ( ) const
{
return m_serverVersion ;
}
qint64 GLPlatform : : kernelVersion ( ) const
{
return m_kernelVersion ;
}
qint64 GLPlatform : : driverVersion ( ) const
{
if ( isMesaDriver ( ) )
return mesaVersion ( ) ;
return m_driverVersion ;
}
Driver GLPlatform : : driver ( ) const
{
return m_driver ;
}
ChipClass GLPlatform : : chipClass ( ) const
{
return m_chipClass ;
}
bool GLPlatform : : isMesaDriver ( ) const
{
return mesaVersion ( ) > 0 ;
}
2011-01-12 01:32:51 +03:00
bool GLPlatform : : isGalliumDriver ( ) const
{
return galliumVersion ( ) > 0 ;
}
2010-11-12 08:30:38 +03:00
bool GLPlatform : : isRadeon ( ) const
{
return m_chipClass > = R100 & & m_chipClass < = UnknownRadeon ;
}
bool GLPlatform : : isNvidia ( ) const
{
return m_chipClass > = NV10 & & m_chipClass < = UnknownNVidia ;
}
bool GLPlatform : : isIntel ( ) const
{
return m_chipClass > = I8XX & & m_chipClass < = UnknownIntel ;
}
2012-10-13 12:33:38 +04:00
bool GLPlatform : : isVirtualBox ( ) const
{
return m_driver = = Driver_VirtualBox ;
}
2012-10-13 18:40:17 +04:00
bool GLPlatform : : isVMware ( ) const
{
return m_driver = = Driver_VMware ;
}
2011-05-06 20:13:54 +04:00
bool GLPlatform : : isSoftwareEmulation ( ) const
{
return m_driver = = Driver_Softpipe | | m_driver = = Driver_Swrast | | m_driver = = Driver_Llvmpipe ;
}
2016-08-12 10:57:41 +03:00
bool GLPlatform : : isAdreno ( ) const
{
return m_chipClass > = Adreno1XX & & m_chipClass < = UnknownAdreno ;
}
2012-03-04 18:10:45 +04:00
const QByteArray & GLPlatform : : glRendererString ( ) const
{
return m_renderer ;
}
const QByteArray & GLPlatform : : glVendorString ( ) const
{
return m_vendor ;
}
const QByteArray & GLPlatform : : glVersionString ( ) const
{
return m_version ;
}
const QByteArray & GLPlatform : : glShadingLanguageVersionString ( ) const
{
return m_glsl_version ;
}
bool GLPlatform : : isLooseBinding ( ) const
{
return m_looseBinding ;
}
2012-10-13 12:33:38 +04:00
bool GLPlatform : : isVirtualMachine ( ) const
{
return m_virtualMachine ;
}
2012-10-05 20:00:49 +04:00
CompositingType GLPlatform : : recommendedCompositor ( ) const
{
return m_recommendedCompositor ;
}
2013-06-28 22:04:33 +04:00
bool GLPlatform : : preferBufferSubData ( ) const
{
return m_preferBufferSubData ;
}
2014-04-22 11:27:05 +04:00
OpenGLPlatformInterface GLPlatform : : platformInterface ( ) const
{
return m_platformInterface ;
}
2012-11-14 00:41:02 +04:00
bool GLPlatform : : isGLES ( ) const
{
2015-11-02 12:43:48 +03:00
return m_gles ;
2012-11-14 00:41:02 +04:00
}
2014-04-10 17:32:48 +04:00
void GLPlatform : : cleanup ( )
{
delete s_platform ;
s_platform = nullptr ;
}
2010-11-12 08:30:38 +03:00
} // namespace KWin