1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program Tester Core 3 * ---------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief WGL Utilities. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "tcuWGL.hpp" 25 #include "tcuWin32Window.hpp" 26 #include "deDynamicLibrary.hpp" 27 #include "deMemory.h" 28 #include "deStringUtil.hpp" 29 #include "tcuFormatUtil.hpp" 30 #include "gluRenderConfig.hpp" 31 #include "glwEnums.hpp" 32 33 #include <map> 34 #include <sstream> 35 #include <iterator> 36 #include <set> 37 38 #include <WinGDI.h> 39 40 // WGL_ARB_pixel_format 41 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 42 #define WGL_DRAW_TO_WINDOW_ARB 0x2001 43 #define WGL_DRAW_TO_BITMAP_ARB 0x2002 44 #define WGL_ACCELERATION_ARB 0x2003 45 #define WGL_NEED_PALETTE_ARB 0x2004 46 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 47 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 48 #define WGL_SWAP_METHOD_ARB 0x2007 49 #define WGL_NUMBER_OVERLAYS_ARB 0x2008 50 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009 51 #define WGL_TRANSPARENT_ARB 0x200A 52 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 53 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 54 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 55 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A 56 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B 57 #define WGL_SHARE_DEPTH_ARB 0x200C 58 #define WGL_SHARE_STENCIL_ARB 0x200D 59 #define WGL_SHARE_ACCUM_ARB 0x200E 60 #define WGL_SUPPORT_GDI_ARB 0x200F 61 #define WGL_SUPPORT_OPENGL_ARB 0x2010 62 #define WGL_DOUBLE_BUFFER_ARB 0x2011 63 #define WGL_STEREO_ARB 0x2012 64 #define WGL_PIXEL_TYPE_ARB 0x2013 65 #define WGL_COLOR_BITS_ARB 0x2014 66 #define WGL_RED_BITS_ARB 0x2015 67 #define WGL_RED_SHIFT_ARB 0x2016 68 #define WGL_GREEN_BITS_ARB 0x2017 69 #define WGL_GREEN_SHIFT_ARB 0x2018 70 #define WGL_BLUE_BITS_ARB 0x2019 71 #define WGL_BLUE_SHIFT_ARB 0x201A 72 #define WGL_ALPHA_BITS_ARB 0x201B 73 #define WGL_ALPHA_SHIFT_ARB 0x201C 74 #define WGL_ACCUM_BITS_ARB 0x201D 75 #define WGL_ACCUM_RED_BITS_ARB 0x201E 76 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F 77 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 78 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 79 #define WGL_DEPTH_BITS_ARB 0x2022 80 #define WGL_STENCIL_BITS_ARB 0x2023 81 #define WGL_AUX_BUFFERS_ARB 0x2024 82 83 #define WGL_NO_ACCELERATION_ARB 0x2025 84 #define WGL_GENERIC_ACCELERATION_ARB 0x2026 85 #define WGL_FULL_ACCELERATION_ARB 0x2027 86 87 #define WGL_TYPE_RGBA_ARB 0x202B 88 #define WGL_TYPE_COLORINDEX_ARB 0x202C 89 90 // WGL_ARB_color_buffer_float 91 #define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 92 93 // WGL_EXT_pixel_type_packed_float 94 #define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 95 96 // WGL_ARB_multisample 97 #define WGL_SAMPLE_BUFFERS_ARB 0x2041 98 #define WGL_SAMPLES_ARB 0x2042 99 100 // WGL_ARB_create_context 101 #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 102 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 103 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 104 #define WGL_CONTEXT_FLAGS_ARB 0x2094 105 #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 106 #define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 107 #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 108 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 109 #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 110 #define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 111 112 // WGL_ARB_create_context_robustness 113 #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x0004 114 #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 115 #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 116 #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 117 118 // WGL ARB_create_context_no_error 119 #define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 120 121 DE_BEGIN_EXTERN_C 122 123 // WGL core 124 typedef HGLRC (WINAPI* wglCreateContextFunc) (HDC hdc); 125 typedef BOOL (WINAPI* wglDeleteContextFunc) (HGLRC hglrc); 126 typedef BOOL (WINAPI* wglMakeCurrentFunc) (HDC hdc, HGLRC hglrc); 127 typedef PROC (WINAPI* wglGetProcAddressFunc) (LPCSTR lpszProc); 128 typedef BOOL (WINAPI* wglSwapLayerBuffersFunc) (HDC dhc, UINT fuPlanes); 129 130 // WGL_ARB_pixel_format 131 typedef BOOL (WINAPI* wglGetPixelFormatAttribivARBFunc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); 132 typedef BOOL (WINAPI* wglGetPixelFormatAttribfvARBFunc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); 133 typedef BOOL (WINAPI* wglChoosePixelFormatARBFunc) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); 134 135 // WGL_ARB_create_context 136 typedef HGLRC (WINAPI* wglCreateContextAttribsARBFunc) (HDC hdc, HGLRC hshareContext, const int* attribList); 137 typedef const char* (WINAPI* wglGetExtensionsStringARBFunc) (HDC hdc); 138 139 DE_END_EXTERN_C 140 141 namespace tcu 142 { 143 namespace wgl 144 { 145 146 // Functions 147 148 struct Functions 149 { 150 // Core 151 wglCreateContextFunc createContext; 152 wglDeleteContextFunc deleteContext; 153 wglMakeCurrentFunc makeCurrent; 154 wglGetProcAddressFunc getProcAddress; 155 wglSwapLayerBuffersFunc swapLayerBuffers; 156 157 // WGL_ARB_pixel_format 158 wglGetPixelFormatAttribivARBFunc getPixelFormatAttribivARB; 159 wglGetPixelFormatAttribfvARBFunc getPixelFormatAttribfvARB; 160 wglChoosePixelFormatARBFunc choosePixelFormatARB; 161 162 // WGL_ARB_create_context 163 wglCreateContextAttribsARBFunc createContextAttribsARB; 164 wglGetExtensionsStringARBFunc getExtensionsStringARB; 165 166 Functions (void) 167 : createContext (DE_NULL) 168 , deleteContext (DE_NULL) 169 , makeCurrent (DE_NULL) 170 , getProcAddress (DE_NULL) 171 , swapLayerBuffers (DE_NULL) 172 , getPixelFormatAttribivARB (DE_NULL) 173 , getPixelFormatAttribfvARB (DE_NULL) 174 , choosePixelFormatARB (DE_NULL) 175 , createContextAttribsARB (DE_NULL) 176 , getExtensionsStringARB (DE_NULL) 177 { 178 } 179 }; 180 181 // Library 182 183 class Library 184 { 185 public: 186 Library (HINSTANCE instance); 187 ~Library (void); 188 189 const Functions& getFunctions (void) const { return m_functions; } 190 const de::DynamicLibrary& getGLLibrary (void) const { return m_library; } 191 bool isWglExtensionSupported (const char* extName) const; 192 193 private: 194 de::DynamicLibrary m_library; 195 Functions m_functions; 196 std::set<std::string> m_extensions; 197 }; 198 199 Library::Library (HINSTANCE instance) 200 : m_library("opengl32.dll") 201 { 202 // Temporary 1x1 window for creating context 203 win32::Window tmpWindow(instance, 1, 1); 204 205 // Load WGL core. 206 m_functions.createContext = (wglCreateContextFunc) m_library.getFunction("wglCreateContext"); 207 m_functions.deleteContext = (wglDeleteContextFunc) m_library.getFunction("wglDeleteContext"); 208 m_functions.getProcAddress = (wglGetProcAddressFunc) m_library.getFunction("wglGetProcAddress"); 209 m_functions.makeCurrent = (wglMakeCurrentFunc) m_library.getFunction("wglMakeCurrent"); 210 m_functions.swapLayerBuffers = (wglSwapLayerBuffersFunc) m_library.getFunction("wglSwapLayerBuffers"); 211 212 if (!m_functions.createContext || 213 !m_functions.deleteContext || 214 !m_functions.getProcAddress || 215 !m_functions.makeCurrent || 216 !m_functions.swapLayerBuffers) 217 throw ResourceError("Failed to load core WGL functions"); 218 219 { 220 PIXELFORMATDESCRIPTOR pixelFormatDesc; 221 deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc)); 222 223 pixelFormatDesc.nSize = sizeof(pixelFormatDesc); 224 pixelFormatDesc.nVersion = 1; 225 pixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 226 pixelFormatDesc.iPixelType = PFD_TYPE_RGBA; 227 pixelFormatDesc.iLayerType = PFD_MAIN_PLANE; 228 229 int pixelFormat = ChoosePixelFormat(tmpWindow.getDeviceContext(), &pixelFormatDesc); 230 if (!SetPixelFormat(tmpWindow.getDeviceContext(), pixelFormat, &pixelFormatDesc)) 231 throw ResourceError("Failed to set pixel format for temporary context creation"); 232 } 233 234 // Create temporary context for loading extension functions. 235 HGLRC tmpCtx = m_functions.createContext(tmpWindow.getDeviceContext()); 236 if (!tmpCtx || !m_functions.makeCurrent(tmpWindow.getDeviceContext(), tmpCtx)) 237 { 238 if (tmpCtx) 239 m_functions.deleteContext(tmpCtx); 240 throw ResourceError("Failed to create temporary WGL context"); 241 } 242 243 // WGL_ARB_pixel_format 244 m_functions.getPixelFormatAttribivARB = (wglGetPixelFormatAttribivARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribivARB"); 245 m_functions.getPixelFormatAttribfvARB = (wglGetPixelFormatAttribfvARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribfvARB"); 246 m_functions.choosePixelFormatARB = (wglChoosePixelFormatARBFunc)m_functions.getProcAddress("wglChoosePixelFormatARB"); 247 248 // WGL_ARB_create_context 249 m_functions.createContextAttribsARB = (wglCreateContextAttribsARBFunc)m_functions.getProcAddress("wglCreateContextAttribsARB"); 250 m_functions.getExtensionsStringARB = (wglGetExtensionsStringARBFunc)m_functions.getProcAddress("wglGetExtensionsStringARB"); 251 252 m_functions.makeCurrent(tmpWindow.getDeviceContext(), NULL); 253 m_functions.deleteContext(tmpCtx); 254 255 if (!m_functions.getPixelFormatAttribivARB || 256 !m_functions.getPixelFormatAttribfvARB || 257 !m_functions.choosePixelFormatARB || 258 !m_functions.createContextAttribsARB || 259 !m_functions.getExtensionsStringARB) 260 throw ResourceError("Failed to load WGL extension functions"); 261 262 const char* extensions = m_functions.getExtensionsStringARB(tmpWindow.getDeviceContext()); 263 std::istringstream extStream(extensions); 264 m_extensions = std::set<std::string>(std::istream_iterator<std::string>(extStream), 265 std::istream_iterator<std::string>()); 266 } 267 268 Library::~Library (void) 269 { 270 } 271 272 bool Library::isWglExtensionSupported (const char* extName) const 273 { 274 return m_extensions.find(extName) != m_extensions.end(); 275 } 276 277 // Core 278 279 Core::Core (HINSTANCE instance) 280 : m_library(new Library(instance)) 281 { 282 } 283 284 Core::~Core (void) 285 { 286 delete m_library; 287 } 288 289 std::vector<int> Core::getPixelFormats (HDC deviceCtx) const 290 { 291 const Functions& wgl = m_library->getFunctions(); 292 293 int attribs[] = { WGL_NUMBER_PIXEL_FORMATS_ARB }; 294 int values[DE_LENGTH_OF_ARRAY(attribs)]; 295 296 if (!wgl.getPixelFormatAttribivARB(deviceCtx, 0, 0, DE_LENGTH_OF_ARRAY(attribs), &attribs[0], &values[0])) 297 TCU_THROW(ResourceError, "Failed to query number of WGL pixel formats"); 298 299 std::vector<int> pixelFormats(values[0]); 300 for (int i = 0; i < values[0]; i++) 301 pixelFormats[i] = i+1; 302 303 return pixelFormats; 304 } 305 306 static PixelFormatInfo::Acceleration translateAcceleration (int accel) 307 { 308 switch (accel) 309 { 310 case WGL_NO_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_NONE; 311 case WGL_GENERIC_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_GENERIC; 312 case WGL_FULL_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_FULL; 313 default: return PixelFormatInfo::ACCELERATION_UNKNOWN; 314 } 315 } 316 317 static PixelFormatInfo::PixelType translatePixelType (int type) 318 { 319 switch (type) 320 { 321 case WGL_TYPE_RGBA_ARB: return PixelFormatInfo::PIXELTYPE_RGBA; 322 case WGL_TYPE_RGBA_FLOAT_ARB: return PixelFormatInfo::PIXELTYPE_RGBA_FLOAT; 323 case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT: return PixelFormatInfo::PIXELTYPE_RGBA_UNSIGNED_FLOAT; 324 case WGL_TYPE_COLORINDEX_ARB: return PixelFormatInfo::PIXELTYPE_COLOR_INDEX; 325 default: return PixelFormatInfo::PIXELTYPE_UNKNOWN; 326 } 327 } 328 329 static void getPixelFormatAttribs (const Functions& wgl, HDC deviceCtx, int pixelFormat, int numAttribs, const int* attribs, std::map<int, int>* dst) 330 { 331 std::vector<int> values (numAttribs); 332 333 if (!wgl.getPixelFormatAttribivARB(deviceCtx, pixelFormat, 0, numAttribs, &attribs[0], &values[0])) 334 TCU_THROW(ResourceError, "Pixel format query failed"); 335 336 for (int ndx = 0; ndx < numAttribs; ++ndx) 337 (*dst)[attribs[ndx]] = values[ndx]; 338 } 339 340 PixelFormatInfo Core::getPixelFormatInfo (HDC deviceCtx, int pixelFormat) const 341 { 342 static const int s_attribsToQuery[] = 343 { 344 WGL_DRAW_TO_WINDOW_ARB, 345 WGL_DRAW_TO_BITMAP_ARB, 346 WGL_ACCELERATION_ARB, 347 WGL_NEED_PALETTE_ARB, 348 WGL_NEED_SYSTEM_PALETTE_ARB, 349 WGL_NUMBER_OVERLAYS_ARB, 350 WGL_NUMBER_UNDERLAYS_ARB, 351 WGL_SUPPORT_OPENGL_ARB, 352 WGL_DOUBLE_BUFFER_ARB, 353 WGL_STEREO_ARB, 354 WGL_PIXEL_TYPE_ARB, 355 WGL_RED_BITS_ARB, 356 WGL_GREEN_BITS_ARB, 357 WGL_BLUE_BITS_ARB, 358 WGL_ALPHA_BITS_ARB, 359 WGL_ACCUM_BITS_ARB, 360 WGL_DEPTH_BITS_ARB, 361 WGL_STENCIL_BITS_ARB, 362 WGL_AUX_BUFFERS_ARB, 363 WGL_SAMPLE_BUFFERS_ARB, 364 WGL_SAMPLES_ARB, 365 }; 366 const Functions& wgl = m_library->getFunctions(); 367 std::map<int, int> values; 368 369 getPixelFormatAttribs(wgl, deviceCtx, pixelFormat, DE_LENGTH_OF_ARRAY(s_attribsToQuery), &s_attribsToQuery[0], &values); 370 371 // Translate values. 372 PixelFormatInfo info; 373 374 info.pixelFormat = pixelFormat; 375 info.surfaceTypes |= (values[WGL_DRAW_TO_WINDOW_ARB] ? PixelFormatInfo::SURFACE_WINDOW : 0); 376 info.surfaceTypes |= (values[WGL_DRAW_TO_BITMAP_ARB] ? PixelFormatInfo::SURFACE_PIXMAP : 0); 377 info.acceleration = translateAcceleration(values[2]); 378 info.needPalette = values[WGL_NEED_PALETTE_ARB] != 0; 379 info.needSystemPalette = values[WGL_NEED_SYSTEM_PALETTE_ARB] != 0; 380 info.numOverlays = values[WGL_NUMBER_OVERLAYS_ARB] != 0; 381 info.numUnderlays = values[WGL_NUMBER_UNDERLAYS_ARB] != 0; 382 info.supportOpenGL = values[WGL_SUPPORT_OPENGL_ARB] != 0; 383 info.doubleBuffer = values[WGL_DOUBLE_BUFFER_ARB] != 0; 384 info.stereo = values[WGL_STEREO_ARB] != 0; 385 info.pixelType = translatePixelType(values[WGL_PIXEL_TYPE_ARB]); 386 info.redBits = values[WGL_RED_BITS_ARB]; 387 info.greenBits = values[WGL_GREEN_BITS_ARB]; 388 info.blueBits = values[WGL_BLUE_BITS_ARB]; 389 info.alphaBits = values[WGL_ALPHA_BITS_ARB]; 390 info.accumBits = values[WGL_ACCUM_BITS_ARB]; 391 info.depthBits = values[WGL_DEPTH_BITS_ARB]; 392 info.stencilBits = values[WGL_STENCIL_BITS_ARB]; 393 info.numAuxBuffers = values[WGL_AUX_BUFFERS_ARB]; 394 info.sampleBuffers = values[WGL_SAMPLE_BUFFERS_ARB]; 395 info.samples = values[WGL_SAMPLES_ARB]; 396 397 return info; 398 } 399 400 // Context 401 402 Context::Context (const Core* core, 403 HDC deviceCtx, 404 glu::ContextType ctxType, 405 int pixelFormat, 406 glu::ResetNotificationStrategy resetNotificationStrategy) 407 : m_core (core) 408 , m_deviceCtx (deviceCtx) 409 , m_context (0) 410 { 411 const Functions& wgl = core->getLibrary()->getFunctions(); 412 std::vector<int> attribList; 413 414 // Context version and profile 415 { 416 int profileBit = 0; 417 int minor = ctxType.getMinorVersion(); 418 int major = ctxType.getMajorVersion(); 419 420 switch (ctxType.getProfile()) 421 { 422 case glu::PROFILE_CORE: 423 profileBit = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; 424 if (major == 3 && minor < 3) 425 minor = 3; 426 break; 427 428 case glu::PROFILE_ES: 429 profileBit = WGL_CONTEXT_ES_PROFILE_BIT_EXT; 430 break; 431 432 case glu::PROFILE_COMPATIBILITY: 433 profileBit = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 434 break; 435 436 default: 437 TCU_THROW(NotSupportedError, "Unsupported context type for WGL"); 438 } 439 440 attribList.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); 441 attribList.push_back(major); 442 attribList.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); 443 attribList.push_back(minor); 444 attribList.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); 445 attribList.push_back(profileBit); 446 } 447 448 // Context flags 449 { 450 int flags = 0; 451 452 if ((ctxType.getFlags() & glu::CONTEXT_FORWARD_COMPATIBLE) != 0) 453 { 454 if (glu::isContextTypeES(ctxType)) 455 TCU_THROW(InternalError, "Only OpenGL core contexts can be forward-compatible"); 456 457 flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; 458 } 459 460 if ((ctxType.getFlags() & glu::CONTEXT_DEBUG) != 0) 461 flags |= WGL_CONTEXT_DEBUG_BIT_ARB; 462 463 if ((ctxType.getFlags() & glu::CONTEXT_ROBUST) != 0) 464 flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; 465 466 if ((ctxType.getFlags() & glu::CONTEXT_NO_ERROR) != 0) 467 { 468 if (core->getLibrary()->isWglExtensionSupported("WGL_ARB_create_context_no_error")) 469 { 470 attribList.push_back(WGL_CONTEXT_OPENGL_NO_ERROR_ARB); 471 attribList.push_back(1); 472 } 473 else 474 TCU_THROW(NotSupportedError, "WGL_ARB_create_context_no_error is required for creating no-error contexts"); 475 } 476 477 if (flags != 0) 478 { 479 attribList.push_back(WGL_CONTEXT_FLAGS_ARB); 480 attribList.push_back(flags); 481 } 482 } 483 484 if (resetNotificationStrategy != glu::RESET_NOTIFICATION_STRATEGY_NOT_SPECIFIED) 485 { 486 attribList.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); 487 488 if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_NO_RESET_NOTIFICATION) 489 attribList.push_back(WGL_NO_RESET_NOTIFICATION_ARB); 490 else if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_LOSE_CONTEXT_ON_RESET) 491 attribList.push_back(WGL_LOSE_CONTEXT_ON_RESET_ARB); 492 else 493 TCU_THROW(InternalError, "Unknown reset notification strategy"); 494 } 495 496 // Set pixel format 497 { 498 PIXELFORMATDESCRIPTOR pixelFormatDesc; 499 deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc)); 500 501 if (!DescribePixelFormat(deviceCtx, pixelFormat, sizeof(pixelFormatDesc), &pixelFormatDesc)) 502 throw ResourceError("DescribePixelFormat() failed"); 503 504 if (!SetPixelFormat(deviceCtx, pixelFormat, &pixelFormatDesc)) 505 throw ResourceError("Failed to set pixel format"); 506 } 507 508 // Terminate attribList 509 attribList.push_back(0); 510 511 // Create context 512 m_context = wgl.createContextAttribsARB(deviceCtx, (HGLRC)0, &attribList[0]); 513 514 if (!m_context) 515 TCU_THROW(ResourceError, "Failed to create WGL context"); 516 517 if (!wgl.makeCurrent(deviceCtx, m_context)) 518 { 519 wgl.deleteContext(m_context); 520 TCU_THROW(ResourceError, "wglMakeCurrent() failed"); 521 } 522 } 523 524 Context::~Context (void) 525 { 526 const Functions& wgl = m_core->getLibrary()->getFunctions(); 527 528 wgl.makeCurrent(m_deviceCtx, NULL); 529 wgl.deleteContext(m_context); 530 } 531 532 FunctionPtr Context::getGLFunction (const char* name) const 533 { 534 FunctionPtr ptr = DE_NULL; 535 536 // Try first with wglGeProcAddress() 537 ptr = (FunctionPtr)m_core->getLibrary()->getFunctions().getProcAddress(name); 538 539 // Fall-back to dynlib 540 if (!ptr) 541 ptr = (FunctionPtr)m_core->getLibrary()->getGLLibrary().getFunction(name); 542 543 return ptr; 544 } 545 546 void Context::makeCurrent (void) 547 { 548 const Functions& wgl = m_core->getLibrary()->getFunctions(); 549 if (!wgl.makeCurrent(m_deviceCtx, m_context)) 550 TCU_THROW(ResourceError, "wglMakeCurrent() failed"); 551 } 552 553 void Context::swapBuffers (void) const 554 { 555 const Functions& wgl = m_core->getLibrary()->getFunctions(); 556 if (!wgl.swapLayerBuffers(m_deviceCtx, WGL_SWAP_MAIN_PLANE)) 557 TCU_THROW(ResourceError, "wglSwapBuffers() failed"); 558 } 559 560 bool isSupportedByTests (const PixelFormatInfo& info) 561 { 562 if (!info.supportOpenGL) 563 return false; 564 565 if (info.pixelType != wgl::PixelFormatInfo::PIXELTYPE_RGBA) 566 return false; 567 568 if ((info.surfaceTypes & wgl::PixelFormatInfo::SURFACE_WINDOW) == 0) 569 return false; 570 571 if (info.needPalette || info.needSystemPalette) 572 return false; 573 574 if (info.numOverlays != 0 || info.numUnderlays != 0) 575 return false; 576 577 if (info.stereo) 578 return false; 579 580 return true; 581 } 582 583 int choosePixelFormat (const Core& wgl, HDC deviceCtx, const glu::RenderConfig& config) 584 { 585 std::vector<int> pixelFormats = wgl.getPixelFormats(deviceCtx); 586 587 for (std::vector<int>::const_iterator fmtIter = pixelFormats.begin(); fmtIter != pixelFormats.end(); ++fmtIter) 588 { 589 const PixelFormatInfo info = wgl.getPixelFormatInfo(deviceCtx, *fmtIter); 590 591 // Skip formats that are fundamentally not compatible with current tests 592 if (!isSupportedByTests(info)) 593 continue; 594 595 if (config.redBits != glu::RenderConfig::DONT_CARE && 596 config.redBits != info.redBits) 597 continue; 598 599 if (config.greenBits != glu::RenderConfig::DONT_CARE && 600 config.greenBits != info.greenBits) 601 continue; 602 603 if (config.blueBits != glu::RenderConfig::DONT_CARE && 604 config.blueBits != info.blueBits) 605 continue; 606 607 if (config.alphaBits != glu::RenderConfig::DONT_CARE && 608 config.alphaBits != info.alphaBits) 609 continue; 610 611 if (config.depthBits != glu::RenderConfig::DONT_CARE && 612 config.depthBits != info.depthBits) 613 continue; 614 615 if (config.stencilBits != glu::RenderConfig::DONT_CARE && 616 config.stencilBits != info.stencilBits) 617 continue; 618 619 if (config.numSamples != glu::RenderConfig::DONT_CARE && 620 config.numSamples != info.samples) 621 continue; 622 623 // Passed all tests - select this. 624 return info.pixelFormat; 625 } 626 627 return -1; 628 } 629 630 } // wgl 631 } // tcu 632