|
GPU-SD
1.1.2
|
00001 00002 /* Copyright (c) 2011-2012, Stefan Eilemann <eile@eyescale.ch> 00003 * 00004 * This library is free software; you can redistribute it and/or modify it under 00005 * the terms of the GNU Lesser General Public License version 2.1 as published 00006 * by the Free Software Foundation. 00007 * 00008 * This library is distributed in the hope that it will be useful, but WITHOUT 00009 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00010 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 00011 * details. 00012 * 00013 * You should have received a copy of the GNU Lesser General Public License 00014 * along with this library; if not, write to the Free Software Foundation, Inc., 00015 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00016 */ 00017 00018 #include "module.h" 00019 00020 #include <gpusd/gpuInfo.h> 00021 00022 #include <X11/Xlib.h> 00023 #include <GL/glx.h> 00024 #include <cstdlib> 00025 #include <limits> 00026 #include <sstream> 00027 00028 #define TRY_PORTS 10 00029 00030 namespace gpusd 00031 { 00032 namespace glx 00033 { 00034 namespace 00035 { 00036 00037 Module* instance = 0; 00038 00039 static bool getGPUInfo_( Display* display, GPUInfo& info ) 00040 { 00041 int major, event, error; 00042 if( !display || !XQueryExtension( display, "GLX", &major, &event, &error )) 00043 return false; 00044 00045 std::string displayString = DisplayString( display ); 00046 const size_t colonPos = displayString.find( ':' ); 00047 if( colonPos != std::string::npos ) 00048 { 00049 const std::string displayNumber = displayString.substr( colonPos+1 ); 00050 info.port = atoi( displayNumber.c_str( )); 00051 info.device = DefaultScreen( display ); 00052 } 00053 00054 info.pvp[0] = 0; 00055 info.pvp[1] = 0; 00056 info.pvp[2] = DisplayWidth( display, DefaultScreen( display )); 00057 info.pvp[3] = DisplayHeight( display, DefaultScreen( display )); 00058 00059 const char* vendor = glXGetClientString( display, GLX_VENDOR ); 00060 if( vendor && std::string( vendor ) == "VirtualGL" ) 00061 { 00062 info.flags |= GPUInfo::FLAG_VIRTUALGL; 00063 const char* vglDisplay = getenv( "VGL_DISPLAY" ); 00064 const std::string vglDisplayStr( vglDisplay ? vglDisplay : ":0.0" ); 00065 std::stringstream xDisplay; 00066 00067 xDisplay << DisplayString( display ); 00068 if( xDisplay.str() == ":0" ) 00069 xDisplay << "." << DefaultScreen( display ); 00070 00071 if( vglDisplayStr == xDisplay.str( )) 00072 info.flags |= GPUInfo::FLAG_VIRTUALGL_DISPLAY; 00073 } 00074 00075 return true; 00076 } 00077 00078 static bool queryDisplay_( const std::string display, GPUInfo& info ) 00079 { 00080 ::Display* xDisplay = XOpenDisplay( display.c_str( )); 00081 if( !xDisplay ) 00082 return false; 00083 00084 int major, event, error; 00085 if( !XQueryExtension( xDisplay, "GLX", &major, &event, &error )) 00086 { 00087 XCloseDisplay( xDisplay ); 00088 return false; 00089 } 00090 00091 getGPUInfo_( xDisplay, info ); 00092 XCloseDisplay( xDisplay ); 00093 return true; 00094 } 00095 00096 } 00097 00098 void Module::use() 00099 { 00100 if( !instance ) 00101 instance = new Module; 00102 } 00103 00104 GPUInfos Module::discoverGPUs_() const 00105 { 00106 GPUInfos result; 00107 GPUInfo defaultInfo( "GLX" ); 00108 00109 const char* displayEnv = getenv( "DISPLAY" ); 00110 if( displayEnv && displayEnv[0] != '\0' ) 00111 { 00112 const std::string display( displayEnv ); 00113 if( queryDisplay_( display, defaultInfo )) 00114 { 00115 if( display[0] != ':' && display[0] != '/' /* OS X launchd */ ) 00116 { 00117 defaultInfo.port = GPUInfo::defaultValue; 00118 defaultInfo.device = GPUInfo::defaultValue; 00119 } 00120 result.push_back( defaultInfo ); 00121 } 00122 } 00123 00124 // try x servers :0 - :n 00125 for( unsigned i = 0; i < std::numeric_limits< unsigned >::max() ; ++i ) 00126 // x screens :n.0 - :n.m 00127 for( unsigned j = 0; j < std::numeric_limits< unsigned >::max(); ++j ) 00128 { 00129 std::stringstream stream; 00130 stream << ':' << i << '.' << j; 00131 00132 GPUInfo info( "GLX" ); 00133 if( queryDisplay_( stream.str(), info )) 00134 { 00135 if( info != defaultInfo ) 00136 result.push_back( info ); 00137 } 00138 else if( j == 0 && i >= TRY_PORTS ) 00139 // X Server does not exist, stop query 00140 return result; 00141 else // X Screen does not exist, try next server 00142 break; 00143 } 00144 return result; 00145 } 00146 00147 } 00148 }
1.1.2 by
1.8.0