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