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