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_EXT_colorspace 101#define WGL_COLORSPACE_EXT 0x309D 102#define WGL_COLORSPACE_SRGB_EXT 0x3089 103#define WGL_COLORSPACE_LINEAR_EXT 0x308A 104 105// WGL_ARB_create_context 106#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 107#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 108#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 109#define WGL_CONTEXT_FLAGS_ARB 0x2094 110#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 111#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001 112#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 113#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 114#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 115#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004 116 117// WGL_ARB_create_context_robustness 118#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x0004 119#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 120#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 121#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 122 123// WGL ARB_create_context_no_error 124#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31B3 125 126DE_BEGIN_EXTERN_C 127 128// WGL core 129typedef HGLRC (WINAPI* wglCreateContextFunc) (HDC hdc); 130typedef BOOL (WINAPI* wglDeleteContextFunc) (HGLRC hglrc); 131typedef BOOL (WINAPI* wglMakeCurrentFunc) (HDC hdc, HGLRC hglrc); 132typedef PROC (WINAPI* wglGetProcAddressFunc) (LPCSTR lpszProc); 133typedef BOOL (WINAPI* wglSwapLayerBuffersFunc) (HDC dhc, UINT fuPlanes); 134 135// WGL_ARB_pixel_format 136typedef BOOL (WINAPI* wglGetPixelFormatAttribivARBFunc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); 137typedef BOOL (WINAPI* wglGetPixelFormatAttribfvARBFunc) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); 138typedef BOOL (WINAPI* wglChoosePixelFormatARBFunc) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); 139 140// WGL_ARB_create_context 141typedef HGLRC (WINAPI* wglCreateContextAttribsARBFunc) (HDC hdc, HGLRC hshareContext, const int* attribList); 142typedef const char* (WINAPI* wglGetExtensionsStringARBFunc) (HDC hdc); 143 144// WGL_EXT_swap_control 145typedef BOOL (WINAPI* wglSwapIntervalEXTFunc) (int interval); 146 147DE_END_EXTERN_C 148 149namespace tcu 150{ 151namespace wgl 152{ 153 154// Functions 155 156struct Functions 157{ 158 // Core 159 wglCreateContextFunc createContext; 160 wglDeleteContextFunc deleteContext; 161 wglMakeCurrentFunc makeCurrent; 162 wglGetProcAddressFunc getProcAddress; 163 wglSwapLayerBuffersFunc swapLayerBuffers; 164 165 // WGL_ARB_pixel_format 166 wglGetPixelFormatAttribivARBFunc getPixelFormatAttribivARB; 167 wglGetPixelFormatAttribfvARBFunc getPixelFormatAttribfvARB; 168 wglChoosePixelFormatARBFunc choosePixelFormatARB; 169 170 // WGL_ARB_create_context 171 wglCreateContextAttribsARBFunc createContextAttribsARB; 172 wglGetExtensionsStringARBFunc getExtensionsStringARB; 173 174 // WGL_EXT_swap_control 175 wglSwapIntervalEXTFunc swapIntervalEXT; 176 177 178 Functions (void) 179 : createContext (DE_NULL) 180 , deleteContext (DE_NULL) 181 , makeCurrent (DE_NULL) 182 , getProcAddress (DE_NULL) 183 , swapLayerBuffers (DE_NULL) 184 , getPixelFormatAttribivARB (DE_NULL) 185 , getPixelFormatAttribfvARB (DE_NULL) 186 , choosePixelFormatARB (DE_NULL) 187 , createContextAttribsARB (DE_NULL) 188 , getExtensionsStringARB (DE_NULL) 189 { 190 } 191}; 192 193// Library 194 195class Library 196{ 197public: 198 Library (HINSTANCE instance); 199 ~Library (void); 200 201 const Functions& getFunctions (void) const { return m_functions; } 202 const de::DynamicLibrary& getGLLibrary (void) const { return m_library; } 203 bool isWglExtensionSupported (const char* extName) const; 204 205private: 206 de::DynamicLibrary m_library; 207 Functions m_functions; 208 std::set<std::string> m_extensions; 209}; 210 211Library::Library (HINSTANCE instance) 212 : m_library("opengl32.dll") 213{ 214 // Temporary 1x1 window for creating context 215 win32::Window tmpWindow(instance, 1, 1); 216 217 // Load WGL core. 218 m_functions.createContext = (wglCreateContextFunc) m_library.getFunction("wglCreateContext"); 219 m_functions.deleteContext = (wglDeleteContextFunc) m_library.getFunction("wglDeleteContext"); 220 m_functions.getProcAddress = (wglGetProcAddressFunc) m_library.getFunction("wglGetProcAddress"); 221 m_functions.makeCurrent = (wglMakeCurrentFunc) m_library.getFunction("wglMakeCurrent"); 222 m_functions.swapLayerBuffers = (wglSwapLayerBuffersFunc) m_library.getFunction("wglSwapLayerBuffers"); 223 224 if (!m_functions.createContext || 225 !m_functions.deleteContext || 226 !m_functions.getProcAddress || 227 !m_functions.makeCurrent || 228 !m_functions.swapLayerBuffers) 229 throw ResourceError("Failed to load core WGL functions"); 230 231 { 232 PIXELFORMATDESCRIPTOR pixelFormatDesc; 233 deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc)); 234 235 pixelFormatDesc.nSize = sizeof(pixelFormatDesc); 236 pixelFormatDesc.nVersion = 1; 237 pixelFormatDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; 238 pixelFormatDesc.iPixelType = PFD_TYPE_RGBA; 239 pixelFormatDesc.iLayerType = PFD_MAIN_PLANE; 240 241 int pixelFormat = ChoosePixelFormat(tmpWindow.getDeviceContext(), &pixelFormatDesc); 242 if (!SetPixelFormat(tmpWindow.getDeviceContext(), pixelFormat, &pixelFormatDesc)) 243 throw ResourceError("Failed to set pixel format for temporary context creation"); 244 } 245 246 // Create temporary context for loading extension functions. 247 HGLRC tmpCtx = m_functions.createContext(tmpWindow.getDeviceContext()); 248 if (!tmpCtx || !m_functions.makeCurrent(tmpWindow.getDeviceContext(), tmpCtx)) 249 { 250 if (tmpCtx) 251 m_functions.deleteContext(tmpCtx); 252 throw ResourceError("Failed to create temporary WGL context"); 253 } 254 255 // WGL_ARB_pixel_format 256 m_functions.getPixelFormatAttribivARB = (wglGetPixelFormatAttribivARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribivARB"); 257 m_functions.getPixelFormatAttribfvARB = (wglGetPixelFormatAttribfvARBFunc)m_functions.getProcAddress("wglGetPixelFormatAttribfvARB"); 258 m_functions.choosePixelFormatARB = (wglChoosePixelFormatARBFunc)m_functions.getProcAddress("wglChoosePixelFormatARB"); 259 260 // WGL_ARB_create_context 261 m_functions.createContextAttribsARB = (wglCreateContextAttribsARBFunc)m_functions.getProcAddress("wglCreateContextAttribsARB"); 262 m_functions.getExtensionsStringARB = (wglGetExtensionsStringARBFunc)m_functions.getProcAddress("wglGetExtensionsStringARB"); 263 264 // WGL_EXT_swap_control 265 m_functions.swapIntervalEXT = (wglSwapIntervalEXTFunc)m_functions.getProcAddress("wglSwapIntervalEXT"); 266 267 m_functions.makeCurrent(tmpWindow.getDeviceContext(), NULL); 268 m_functions.deleteContext(tmpCtx); 269 270 if (!m_functions.getPixelFormatAttribivARB || 271 !m_functions.getPixelFormatAttribfvARB || 272 !m_functions.choosePixelFormatARB || 273 !m_functions.createContextAttribsARB || 274 !m_functions.getExtensionsStringARB) 275 throw ResourceError("Failed to load WGL extension functions"); 276 277 const char* extensions = m_functions.getExtensionsStringARB(tmpWindow.getDeviceContext()); 278 std::istringstream extStream(extensions); 279 m_extensions = std::set<std::string>(std::istream_iterator<std::string>(extStream), 280 std::istream_iterator<std::string>()); 281} 282 283Library::~Library (void) 284{ 285} 286 287bool Library::isWglExtensionSupported (const char* extName) const 288{ 289 return m_extensions.find(extName) != m_extensions.end(); 290} 291 292// Core 293 294Core::Core (HINSTANCE instance) 295 : m_library(new Library(instance)) 296{ 297} 298 299Core::~Core (void) 300{ 301 delete m_library; 302} 303 304std::vector<int> Core::getPixelFormats (HDC deviceCtx) const 305{ 306 const Functions& wgl = m_library->getFunctions(); 307 308 int attribs[] = { WGL_NUMBER_PIXEL_FORMATS_ARB }; 309 int values[DE_LENGTH_OF_ARRAY(attribs)]; 310 311 if (!wgl.getPixelFormatAttribivARB(deviceCtx, 0, 0, DE_LENGTH_OF_ARRAY(attribs), &attribs[0], &values[0])) 312 TCU_THROW(ResourceError, "Failed to query number of WGL pixel formats"); 313 314 std::vector<int> pixelFormats(values[0]); 315 for (int i = 0; i < values[0]; i++) 316 pixelFormats[i] = i+1; 317 318 return pixelFormats; 319} 320 321static PixelFormatInfo::Acceleration translateAcceleration (int accel) 322{ 323 switch (accel) 324 { 325 case WGL_NO_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_NONE; 326 case WGL_GENERIC_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_GENERIC; 327 case WGL_FULL_ACCELERATION_ARB: return PixelFormatInfo::ACCELERATION_FULL; 328 default: return PixelFormatInfo::ACCELERATION_UNKNOWN; 329 } 330} 331 332static PixelFormatInfo::PixelType translatePixelType (int type) 333{ 334 switch (type) 335 { 336 case WGL_TYPE_RGBA_ARB: return PixelFormatInfo::PIXELTYPE_RGBA; 337 case WGL_TYPE_RGBA_FLOAT_ARB: return PixelFormatInfo::PIXELTYPE_RGBA_FLOAT; 338 case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT: return PixelFormatInfo::PIXELTYPE_RGBA_UNSIGNED_FLOAT; 339 case WGL_TYPE_COLORINDEX_ARB: return PixelFormatInfo::PIXELTYPE_COLOR_INDEX; 340 default: return PixelFormatInfo::PIXELTYPE_UNKNOWN; 341 } 342} 343 344static void getPixelFormatAttribs (const Functions& wgl, HDC deviceCtx, int pixelFormat, int numAttribs, const int* attribs, std::map<int, int>* dst) 345{ 346 std::vector<int> values (numAttribs); 347 348 if (!wgl.getPixelFormatAttribivARB(deviceCtx, pixelFormat, 0, numAttribs, &attribs[0], &values[0])) 349 TCU_THROW(ResourceError, "Pixel format query failed"); 350 351 for (int ndx = 0; ndx < numAttribs; ++ndx) 352 (*dst)[attribs[ndx]] = values[ndx]; 353} 354 355PixelFormatInfo Core::getPixelFormatInfo (HDC deviceCtx, int pixelFormat) const 356{ 357 std::vector<int> s_attribsToQuery 358 { 359 WGL_DRAW_TO_WINDOW_ARB, 360 WGL_DRAW_TO_BITMAP_ARB, 361 WGL_ACCELERATION_ARB, 362 WGL_NEED_PALETTE_ARB, 363 WGL_NEED_SYSTEM_PALETTE_ARB, 364 WGL_NUMBER_OVERLAYS_ARB, 365 WGL_NUMBER_UNDERLAYS_ARB, 366 WGL_SUPPORT_OPENGL_ARB, 367 WGL_DOUBLE_BUFFER_ARB, 368 WGL_STEREO_ARB, 369 WGL_PIXEL_TYPE_ARB, 370 WGL_RED_BITS_ARB, 371 WGL_GREEN_BITS_ARB, 372 WGL_BLUE_BITS_ARB, 373 WGL_ALPHA_BITS_ARB, 374 WGL_ACCUM_BITS_ARB, 375 WGL_DEPTH_BITS_ARB, 376 WGL_STENCIL_BITS_ARB, 377 WGL_AUX_BUFFERS_ARB, 378 WGL_SAMPLE_BUFFERS_ARB, 379 WGL_SAMPLES_ARB, 380 }; 381 if (getLibrary()->isWglExtensionSupported("WGL_EXT_colorspace")) 382 s_attribsToQuery.push_back(WGL_COLORSPACE_EXT); 383 384 const Functions& wgl = m_library->getFunctions(); 385 std::map<int, int> values; 386 387 getPixelFormatAttribs(wgl, deviceCtx, pixelFormat, static_cast<int>(s_attribsToQuery.size()), s_attribsToQuery.data(), &values); 388 389 // Translate values. 390 PixelFormatInfo info; 391 392 info.pixelFormat = pixelFormat; 393 info.surfaceTypes |= (values[WGL_DRAW_TO_WINDOW_ARB] ? PixelFormatInfo::SURFACE_WINDOW : 0); 394 info.surfaceTypes |= (values[WGL_DRAW_TO_BITMAP_ARB] ? PixelFormatInfo::SURFACE_PIXMAP : 0); 395 info.acceleration = translateAcceleration(values[WGL_ACCELERATION_ARB]); 396 info.needPalette = values[WGL_NEED_PALETTE_ARB] != 0; 397 info.needSystemPalette = values[WGL_NEED_SYSTEM_PALETTE_ARB] != 0; 398 info.numOverlays = values[WGL_NUMBER_OVERLAYS_ARB] != 0; 399 info.numUnderlays = values[WGL_NUMBER_UNDERLAYS_ARB] != 0; 400 info.supportOpenGL = values[WGL_SUPPORT_OPENGL_ARB] != 0; 401 info.doubleBuffer = values[WGL_DOUBLE_BUFFER_ARB] != 0; 402 info.stereo = values[WGL_STEREO_ARB] != 0; 403 info.pixelType = translatePixelType(values[WGL_PIXEL_TYPE_ARB]); 404 info.redBits = values[WGL_RED_BITS_ARB]; 405 info.greenBits = values[WGL_GREEN_BITS_ARB]; 406 info.blueBits = values[WGL_BLUE_BITS_ARB]; 407 info.alphaBits = values[WGL_ALPHA_BITS_ARB]; 408 info.accumBits = values[WGL_ACCUM_BITS_ARB]; 409 info.depthBits = values[WGL_DEPTH_BITS_ARB]; 410 info.stencilBits = values[WGL_STENCIL_BITS_ARB]; 411 info.numAuxBuffers = values[WGL_AUX_BUFFERS_ARB]; 412 info.sampleBuffers = values[WGL_SAMPLE_BUFFERS_ARB]; 413 info.samples = values[WGL_SAMPLES_ARB]; 414 info.sRGB = (getLibrary()->isWglExtensionSupported("WGL_EXT_colorspace")) ? (values[WGL_COLORSPACE_EXT] == WGL_COLORSPACE_SRGB_EXT) : false; 415 416 return info; 417} 418 419// Context 420 421Context::Context (const Core* core, 422 HDC deviceCtx, 423 const Context* sharedContext, 424 glu::ContextType ctxType, 425 int pixelFormat, 426 glu::ResetNotificationStrategy resetNotificationStrategy) 427 : m_core (core) 428 , m_deviceCtx (deviceCtx) 429 , m_context (0) 430{ 431 const Functions& wgl = core->getLibrary()->getFunctions(); 432 std::vector<int> attribList; 433 434 // Context version and profile 435 { 436 int profileBit = 0; 437 HGLRC sharedCtx = DE_NULL; 438 int minor = ctxType.getMinorVersion(); 439 int major = ctxType.getMajorVersion(); 440 441 switch (ctxType.getProfile()) 442 { 443 case glu::PROFILE_CORE: 444 profileBit = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; 445 if (major == 3 && minor < 3) 446 minor = 3; 447 break; 448 449 case glu::PROFILE_ES: 450 profileBit = WGL_CONTEXT_ES_PROFILE_BIT_EXT; 451 break; 452 453 case glu::PROFILE_COMPATIBILITY: 454 profileBit = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; 455 break; 456 457 default: 458 TCU_THROW(NotSupportedError, "Unsupported context type for WGL"); 459 } 460 461 attribList.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB); 462 attribList.push_back(major); 463 attribList.push_back(WGL_CONTEXT_MINOR_VERSION_ARB); 464 attribList.push_back(minor); 465 attribList.push_back(WGL_CONTEXT_PROFILE_MASK_ARB); 466 attribList.push_back(profileBit); 467 } 468 469 // Context flags 470 { 471 int flags = 0; 472 473 if ((ctxType.getFlags() & glu::CONTEXT_FORWARD_COMPATIBLE) != 0) 474 { 475 if (glu::isContextTypeES(ctxType)) 476 TCU_THROW(InternalError, "Only OpenGL core contexts can be forward-compatible"); 477 478 flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; 479 } 480 481 if ((ctxType.getFlags() & glu::CONTEXT_DEBUG) != 0) 482 flags |= WGL_CONTEXT_DEBUG_BIT_ARB; 483 484 if ((ctxType.getFlags() & glu::CONTEXT_ROBUST) != 0) 485 flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; 486 487 if ((ctxType.getFlags() & glu::CONTEXT_NO_ERROR) != 0) 488 { 489 if (core->getLibrary()->isWglExtensionSupported("WGL_ARB_create_context_no_error")) 490 { 491 attribList.push_back(WGL_CONTEXT_OPENGL_NO_ERROR_ARB); 492 attribList.push_back(1); 493 } 494 else 495 TCU_THROW(NotSupportedError, "WGL_ARB_create_context_no_error is required for creating no-error contexts"); 496 } 497 498 if (flags != 0) 499 { 500 attribList.push_back(WGL_CONTEXT_FLAGS_ARB); 501 attribList.push_back(flags); 502 } 503 } 504 505 if (resetNotificationStrategy != glu::RESET_NOTIFICATION_STRATEGY_NOT_SPECIFIED) 506 { 507 attribList.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); 508 509 if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_NO_RESET_NOTIFICATION) 510 attribList.push_back(WGL_NO_RESET_NOTIFICATION_ARB); 511 else if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_LOSE_CONTEXT_ON_RESET) 512 attribList.push_back(WGL_LOSE_CONTEXT_ON_RESET_ARB); 513 else 514 TCU_THROW(InternalError, "Unknown reset notification strategy"); 515 } 516 517 // Set pixel format 518 { 519 PIXELFORMATDESCRIPTOR pixelFormatDesc; 520 deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc)); 521 522 if (!DescribePixelFormat(deviceCtx, pixelFormat, sizeof(pixelFormatDesc), &pixelFormatDesc)) 523 throw ResourceError("DescribePixelFormat() failed"); 524 525 if (!SetPixelFormat(deviceCtx, pixelFormat, &pixelFormatDesc)) 526 throw ResourceError("Failed to set pixel format"); 527 } 528 529 HGLRC sharedCtx = DE_NULL; 530 if (DE_NULL != sharedContext) 531 sharedCtx = sharedContext->m_context; 532 533 // Terminate attribList 534 attribList.push_back(0); 535 536 // Create context 537 m_context = wgl.createContextAttribsARB(deviceCtx, sharedCtx, &attribList[0]); 538 539 if (!m_context) 540 TCU_THROW(ResourceError, "Failed to create WGL context"); 541 542 if (!wgl.makeCurrent(deviceCtx, m_context)) 543 { 544 wgl.deleteContext(m_context); 545 TCU_THROW(ResourceError, "wglMakeCurrent() failed"); 546 } 547 548 if (core->getLibrary()->isWglExtensionSupported("WGL_EXT_swap_control")) 549 core->getLibrary()->getFunctions().swapIntervalEXT(0); 550} 551 552Context::~Context (void) 553{ 554 const Functions& wgl = m_core->getLibrary()->getFunctions(); 555 556 wgl.makeCurrent(m_deviceCtx, NULL); 557 wgl.deleteContext(m_context); 558} 559 560FunctionPtr Context::getGLFunction (const char* name) const 561{ 562 FunctionPtr ptr = DE_NULL; 563 564 // Try first with wglGeProcAddress() 565 ptr = (FunctionPtr)m_core->getLibrary()->getFunctions().getProcAddress(name); 566 567 // Fall-back to dynlib 568 if (!ptr) 569 ptr = (FunctionPtr)m_core->getLibrary()->getGLLibrary().getFunction(name); 570 571 return ptr; 572} 573 574void Context::makeCurrent (void) 575{ 576 const Functions& wgl = m_core->getLibrary()->getFunctions(); 577 if (!wgl.makeCurrent(m_deviceCtx, m_context)) 578 TCU_THROW(ResourceError, "wglMakeCurrent() failed"); 579} 580 581void Context::swapBuffers (void) const 582{ 583 const Functions& wgl = m_core->getLibrary()->getFunctions(); 584 if (!wgl.swapLayerBuffers(m_deviceCtx, WGL_SWAP_MAIN_PLANE)) 585 TCU_THROW(ResourceError, "wglSwapBuffers() failed"); 586} 587 588bool isSupportedByTests (const PixelFormatInfo& info) 589{ 590 if (!info.supportOpenGL) 591 return false; 592 593 if (info.acceleration != wgl::PixelFormatInfo::ACCELERATION_FULL) 594 return false; 595 596 if (info.pixelType != wgl::PixelFormatInfo::PIXELTYPE_RGBA) 597 return false; 598 599 if ((info.surfaceTypes & wgl::PixelFormatInfo::SURFACE_WINDOW) == 0) 600 return false; 601 602 if (info.needPalette || info.needSystemPalette) 603 return false; 604 605 if (info.numOverlays != 0 || info.numUnderlays != 0) 606 return false; 607 608 if (info.stereo) 609 return false; 610 611 return true; 612} 613 614int choosePixelFormat (const Core& wgl, HDC deviceCtx, const glu::RenderConfig& config) 615{ 616 std::vector<int> pixelFormats = wgl.getPixelFormats(deviceCtx); 617 618 for (std::vector<int>::const_iterator fmtIter = pixelFormats.begin(); fmtIter != pixelFormats.end(); ++fmtIter) 619 { 620 const PixelFormatInfo info = wgl.getPixelFormatInfo(deviceCtx, *fmtIter); 621 622 // Skip formats that are fundamentally not compatible with current tests 623 if (!isSupportedByTests(info)) 624 continue; 625 626 if (config.redBits != glu::RenderConfig::DONT_CARE && 627 config.redBits != info.redBits) 628 continue; 629 630 if (config.greenBits != glu::RenderConfig::DONT_CARE && 631 config.greenBits != info.greenBits) 632 continue; 633 634 if (config.blueBits != glu::RenderConfig::DONT_CARE && 635 config.blueBits != info.blueBits) 636 continue; 637 638 if (config.alphaBits != glu::RenderConfig::DONT_CARE && 639 config.alphaBits != info.alphaBits) 640 continue; 641 642 if (config.depthBits != glu::RenderConfig::DONT_CARE && 643 config.depthBits != info.depthBits) 644 continue; 645 646 if (config.stencilBits != glu::RenderConfig::DONT_CARE && 647 config.stencilBits != info.stencilBits) 648 continue; 649 650 if (config.numSamples != glu::RenderConfig::DONT_CARE && 651 config.numSamples != info.samples) 652 continue; 653 654 // Passed all tests - select this. 655 return info.pixelFormat; 656 } 657 658 return -1; 659} 660 661} // wgl 662} // tcu 663