wglPipe.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "wglPipe.h"
00020
00021 #include "global.h"
00022 #include "pipe.h"
00023 #include "wglEventHandler.h"
00024
00025 namespace eq
00026 {
00027
00028 WGLPipe::WGLPipe( Pipe* parent )
00029 : OSPipe( parent )
00030 {
00031 }
00032
00033 WGLPipe::~WGLPipe( )
00034 {
00035 }
00036
00037 using namespace std;
00038
00039
00040
00041
00042 bool WGLPipe::configInit()
00043 {
00044 _configInitWGLEW();
00045
00046 PixelViewport pvp = _pipe->getPixelViewport();
00047 if( pvp.isValid( ))
00048 return true;
00049
00050
00051
00052 HGPUNV hGPU = 0;
00053 if( !_getGPUHandle( hGPU ))
00054 return false;
00055
00056 if( hGPU != 0 )
00057 {
00058 GPU_DEVICE gpuDevice;
00059 gpuDevice.cb = sizeof( gpuDevice );
00060 const bool found = wglEnumGpuDevicesNV( hGPU, 0, &gpuDevice );
00061 EQASSERT( found );
00062
00063 if( gpuDevice.Flags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP )
00064 {
00065 const RECT& rect = gpuDevice.rcVirtualScreen;
00066 pvp.x = rect.left;
00067 pvp.y = rect.top;
00068 pvp.w = rect.right - rect.left;
00069 pvp.h = rect.bottom - rect.top;
00070 }
00071 else
00072 {
00073 pvp.x = 0;
00074 pvp.y = 0;
00075 pvp.w = 4096;
00076 pvp.h = 4096;
00077 }
00078 }
00079 else
00080 {
00081 HDC dc = createWGLDisplayDC();
00082 EQASSERT( dc );
00083
00084 pvp.x = 0;
00085 pvp.y = 0;
00086 pvp.w = GetDeviceCaps( dc, HORZRES );
00087 pvp.h = GetDeviceCaps( dc, VERTRES );
00088 _pipe->setPixelViewport( pvp );
00089
00090 DeleteDC( dc );
00091 }
00092
00093 _pipe->setPixelViewport( pvp );
00094 EQINFO << "Pipe pixel viewport " << pvp << endl;
00095 return true;
00096 }
00097
00098
00099 void WGLPipe::configExit()
00100 {
00101 _pipe->setPixelViewport( eq::PixelViewport( ));
00102 }
00103
00104
00105 bool WGLPipe::createWGLAffinityDC( HDC& affinityDC )
00106 {
00107 affinityDC = 0;
00108
00109 HGPUNV hGPU[2] = { 0 };
00110 if( !_getGPUHandle( hGPU[0] ))
00111 return false;
00112
00113 if( hGPU[0] == 0 )
00114 return true;
00115
00116 affinityDC = wglCreateAffinityDCNV( hGPU );
00117 if( !affinityDC )
00118 {
00119 setErrorMessage( "Can't create affinity DC: " +
00120 base::getErrorString( GetLastError( )));
00121 return false;
00122 }
00123
00124 return true;
00125 }
00126
00127 HDC WGLPipe::createWGLDisplayDC()
00128 {
00129 uint32_t device = _pipe->getDevice();
00130 if( device == EQ_UNDEFINED_UINT32 )
00131 device = 0;
00132
00133 DISPLAY_DEVICE devInfo;
00134 devInfo.cb = sizeof( devInfo );
00135
00136 if( !EnumDisplayDevices( 0, device, &devInfo, 0 ))
00137 {
00138 _pipe->setErrorMessage( "Can't enumerate display devices: " +
00139 base::getLastErrorString());
00140 return 0;
00141 }
00142
00143 const HDC displayDC = CreateDC( "DISPLAY", devInfo.DeviceName, 0, 0 );
00144 if( !displayDC )
00145 {
00146 _pipe->setErrorMessage( "Can't create device context: " +
00147 base::getLastErrorString( ));
00148 return 0;
00149 }
00150
00151 return displayDC;
00152 }
00153
00154 bool WGLPipe::_getGPUHandle( HGPUNV& handle )
00155 {
00156 handle = 0;
00157
00158 const uint32_t device = _pipe->getDevice();
00159 if( device == EQ_UNDEFINED_UINT32 )
00160 return true;
00161
00162 if( !WGLEW_NV_gpu_affinity )
00163 {
00164 EQWARN <<"WGL_NV_gpu_affinity unsupported, ignoring pipe device setting"
00165 << endl;
00166 return true;
00167 }
00168
00169 if( !wglEnumGpusNV( device, &handle ))
00170 {
00171 stringstream error;
00172 error << "Can't enumerate GPU #" << device;
00173 setErrorMessage( error.str( ));
00174 return false;
00175 }
00176
00177 return true;
00178 }
00179
00180
00181 void WGLPipe::_configInitWGLEW()
00182 {
00183
00184
00185
00186 ostringstream className;
00187 className << "TMP" << (void*)this;
00188 const string& classStr = className.str();
00189
00190 HINSTANCE instance = GetModuleHandle( 0 );
00191 WNDCLASS wc = { 0 };
00192 wc.lpfnWndProc = DefWindowProc;
00193 wc.hInstance = instance;
00194 wc.hIcon = LoadIcon( 0, IDI_WINLOGO );
00195 wc.hCursor = LoadCursor( 0, IDC_ARROW );
00196 wc.lpszClassName = classStr.c_str();
00197
00198 if( !RegisterClass( &wc ))
00199 {
00200 EQWARN << "Can't register temporary window class: "
00201 << base::getErrorString( GetLastError( )) << endl;
00202 return;
00203 }
00204
00205
00206 DWORD windowStyleEx = WS_EX_APPWINDOW;
00207 DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW;
00208
00209 HWND hWnd = CreateWindowEx( windowStyleEx,
00210 wc.lpszClassName, "TMP",
00211 windowStyle, 0, 0, 1, 1,
00212 0, 0,
00213 instance, 0 );
00214
00215 if( !hWnd )
00216 {
00217 EQWARN << "Can't create temporary window: "
00218 << base::getErrorString( GetLastError( )) << endl;
00219 UnregisterClass( classStr.c_str(), instance );
00220 return;
00221 }
00222
00223 HDC dc = GetDC( hWnd );
00224 PIXELFORMATDESCRIPTOR pfd = {0};
00225 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00226 pfd.nVersion = 1;
00227 pfd.dwFlags = PFD_DRAW_TO_WINDOW |
00228 PFD_SUPPORT_OPENGL;
00229
00230 int pf = ChoosePixelFormat( dc, &pfd );
00231 if( pf == 0 )
00232 {
00233 EQWARN << "Can't find temporary pixel format: "
00234 << base::getErrorString( GetLastError( )) << endl;
00235 DestroyWindow( hWnd );
00236 UnregisterClass( classStr.c_str(), instance );
00237 return;
00238 }
00239
00240 if( !SetPixelFormat( dc, pf, &pfd ))
00241 {
00242 EQWARN << "Can't set pixel format: "
00243 << base::getErrorString( GetLastError( )) << endl;
00244 ReleaseDC( hWnd, dc );
00245 DestroyWindow( hWnd );
00246 UnregisterClass( classStr.c_str(), instance );
00247 return;
00248 }
00249
00250
00251 HGLRC context = wglCreateContext( dc );
00252 if( !context )
00253 {
00254 EQWARN << "Can't create temporary OpenGL context: "
00255 << base::getErrorString( GetLastError( )) << endl;
00256 ReleaseDC( hWnd, dc );
00257 DestroyWindow( hWnd );
00258 UnregisterClass( classStr.c_str(), instance );
00259 return;
00260 }
00261
00262 HDC oldDC = wglGetCurrentDC();
00263 HGLRC oldContext = wglGetCurrentContext();
00264
00265 wglMakeCurrent( dc, context );
00266
00267 const GLenum result = wglewInit();
00268 if( result != GLEW_OK )
00269 EQWARN << "Pipe WGLEW initialization failed with error " << result
00270 << endl;
00271 else
00272 EQINFO << "Pipe WGLEW initialization successful" << endl;
00273
00274 wglDeleteContext( context );
00275 ReleaseDC( hWnd, dc );
00276 DestroyWindow( hWnd );
00277 UnregisterClass( classStr.c_str(), instance );
00278
00279 wglMakeCurrent( oldDC, oldContext );
00280 }
00281
00282
00283 }
00284