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
Functionstcu::wgl::Functions166 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
getFunctions(void) const189 const Functions& getFunctions (void) const { return m_functions; }
getGLLibrary(void) const190 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
Library(HINSTANCE instance)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
~Library(void)268 Library::~Library (void)
269 {
270 }
271
isWglExtensionSupported(const char * extName) const272 bool Library::isWglExtensionSupported (const char* extName) const
273 {
274 return m_extensions.find(extName) != m_extensions.end();
275 }
276
277 // Core
278
Core(HINSTANCE instance)279 Core::Core (HINSTANCE instance)
280 : m_library(new Library(instance))
281 {
282 }
283
~Core(void)284 Core::~Core (void)
285 {
286 delete m_library;
287 }
288
getPixelFormats(HDC deviceCtx) const289 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
translateAcceleration(int accel)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
translatePixelType(int type)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
getPixelFormatAttribs(const Functions & wgl,HDC deviceCtx,int pixelFormat,int numAttribs,const int * attribs,std::map<int,int> * dst)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
getPixelFormatInfo(HDC deviceCtx,int pixelFormat) const340 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[WGL_ACCELERATION_ARB]);
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
Context(const Core * core,HDC deviceCtx,const Context * sharedContext,glu::ContextType ctxType,int pixelFormat,glu::ResetNotificationStrategy resetNotificationStrategy)402 Context::Context (const Core* core,
403 HDC deviceCtx,
404 const Context* sharedContext,
405 glu::ContextType ctxType,
406 int pixelFormat,
407 glu::ResetNotificationStrategy resetNotificationStrategy)
408 : m_core (core)
409 , m_deviceCtx (deviceCtx)
410 , m_context (0)
411 {
412 const Functions& wgl = core->getLibrary()->getFunctions();
413 std::vector<int> attribList;
414
415 // Context version and profile
416 {
417 int profileBit = 0;
418 HGLRC sharedCtx = DE_NULL;
419 int minor = ctxType.getMinorVersion();
420 int major = ctxType.getMajorVersion();
421
422 switch (ctxType.getProfile())
423 {
424 case glu::PROFILE_CORE:
425 profileBit = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
426 if (major == 3 && minor < 3)
427 minor = 3;
428 break;
429
430 case glu::PROFILE_ES:
431 profileBit = WGL_CONTEXT_ES_PROFILE_BIT_EXT;
432 break;
433
434 case glu::PROFILE_COMPATIBILITY:
435 profileBit = WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
436 break;
437
438 default:
439 TCU_THROW(NotSupportedError, "Unsupported context type for WGL");
440 }
441
442 attribList.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
443 attribList.push_back(major);
444 attribList.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
445 attribList.push_back(minor);
446 attribList.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
447 attribList.push_back(profileBit);
448 }
449
450 // Context flags
451 {
452 int flags = 0;
453
454 if ((ctxType.getFlags() & glu::CONTEXT_FORWARD_COMPATIBLE) != 0)
455 {
456 if (glu::isContextTypeES(ctxType))
457 TCU_THROW(InternalError, "Only OpenGL core contexts can be forward-compatible");
458
459 flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
460 }
461
462 if ((ctxType.getFlags() & glu::CONTEXT_DEBUG) != 0)
463 flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
464
465 if ((ctxType.getFlags() & glu::CONTEXT_ROBUST) != 0)
466 flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
467
468 if ((ctxType.getFlags() & glu::CONTEXT_NO_ERROR) != 0)
469 {
470 if (core->getLibrary()->isWglExtensionSupported("WGL_ARB_create_context_no_error"))
471 {
472 attribList.push_back(WGL_CONTEXT_OPENGL_NO_ERROR_ARB);
473 attribList.push_back(1);
474 }
475 else
476 TCU_THROW(NotSupportedError, "WGL_ARB_create_context_no_error is required for creating no-error contexts");
477 }
478
479 if (flags != 0)
480 {
481 attribList.push_back(WGL_CONTEXT_FLAGS_ARB);
482 attribList.push_back(flags);
483 }
484 }
485
486 if (resetNotificationStrategy != glu::RESET_NOTIFICATION_STRATEGY_NOT_SPECIFIED)
487 {
488 attribList.push_back(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
489
490 if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_NO_RESET_NOTIFICATION)
491 attribList.push_back(WGL_NO_RESET_NOTIFICATION_ARB);
492 else if (resetNotificationStrategy == glu::RESET_NOTIFICATION_STRATEGY_LOSE_CONTEXT_ON_RESET)
493 attribList.push_back(WGL_LOSE_CONTEXT_ON_RESET_ARB);
494 else
495 TCU_THROW(InternalError, "Unknown reset notification strategy");
496 }
497
498 // Set pixel format
499 {
500 PIXELFORMATDESCRIPTOR pixelFormatDesc;
501 deMemset(&pixelFormatDesc, 0, sizeof(pixelFormatDesc));
502
503 if (!DescribePixelFormat(deviceCtx, pixelFormat, sizeof(pixelFormatDesc), &pixelFormatDesc))
504 throw ResourceError("DescribePixelFormat() failed");
505
506 if (!SetPixelFormat(deviceCtx, pixelFormat, &pixelFormatDesc))
507 throw ResourceError("Failed to set pixel format");
508 }
509
510 HGLRC sharedCtx = DE_NULL;
511 if (DE_NULL != sharedContext)
512 sharedCtx = sharedContext->m_context;
513
514 // Terminate attribList
515 attribList.push_back(0);
516
517 // Create context
518 m_context = wgl.createContextAttribsARB(deviceCtx, sharedCtx, &attribList[0]);
519
520 if (!m_context)
521 TCU_THROW(ResourceError, "Failed to create WGL context");
522
523 if (!wgl.makeCurrent(deviceCtx, m_context))
524 {
525 wgl.deleteContext(m_context);
526 TCU_THROW(ResourceError, "wglMakeCurrent() failed");
527 }
528 }
529
~Context(void)530 Context::~Context (void)
531 {
532 const Functions& wgl = m_core->getLibrary()->getFunctions();
533
534 wgl.makeCurrent(m_deviceCtx, NULL);
535 wgl.deleteContext(m_context);
536 }
537
getGLFunction(const char * name) const538 FunctionPtr Context::getGLFunction (const char* name) const
539 {
540 FunctionPtr ptr = DE_NULL;
541
542 // Try first with wglGeProcAddress()
543 ptr = (FunctionPtr)m_core->getLibrary()->getFunctions().getProcAddress(name);
544
545 // Fall-back to dynlib
546 if (!ptr)
547 ptr = (FunctionPtr)m_core->getLibrary()->getGLLibrary().getFunction(name);
548
549 return ptr;
550 }
551
makeCurrent(void)552 void Context::makeCurrent (void)
553 {
554 const Functions& wgl = m_core->getLibrary()->getFunctions();
555 if (!wgl.makeCurrent(m_deviceCtx, m_context))
556 TCU_THROW(ResourceError, "wglMakeCurrent() failed");
557 }
558
swapBuffers(void) const559 void Context::swapBuffers (void) const
560 {
561 const Functions& wgl = m_core->getLibrary()->getFunctions();
562 if (!wgl.swapLayerBuffers(m_deviceCtx, WGL_SWAP_MAIN_PLANE))
563 TCU_THROW(ResourceError, "wglSwapBuffers() failed");
564 }
565
isSupportedByTests(const PixelFormatInfo & info)566 bool isSupportedByTests (const PixelFormatInfo& info)
567 {
568 if (!info.supportOpenGL)
569 return false;
570
571 if (info.acceleration != wgl::PixelFormatInfo::ACCELERATION_FULL)
572 return false;
573
574 if (info.pixelType != wgl::PixelFormatInfo::PIXELTYPE_RGBA)
575 return false;
576
577 if ((info.surfaceTypes & wgl::PixelFormatInfo::SURFACE_WINDOW) == 0)
578 return false;
579
580 if (info.needPalette || info.needSystemPalette)
581 return false;
582
583 if (info.numOverlays != 0 || info.numUnderlays != 0)
584 return false;
585
586 if (info.stereo)
587 return false;
588
589 return true;
590 }
591
choosePixelFormat(const Core & wgl,HDC deviceCtx,const glu::RenderConfig & config)592 int choosePixelFormat (const Core& wgl, HDC deviceCtx, const glu::RenderConfig& config)
593 {
594 std::vector<int> pixelFormats = wgl.getPixelFormats(deviceCtx);
595
596 for (std::vector<int>::const_iterator fmtIter = pixelFormats.begin(); fmtIter != pixelFormats.end(); ++fmtIter)
597 {
598 const PixelFormatInfo info = wgl.getPixelFormatInfo(deviceCtx, *fmtIter);
599
600 // Skip formats that are fundamentally not compatible with current tests
601 if (!isSupportedByTests(info))
602 continue;
603
604 if (config.redBits != glu::RenderConfig::DONT_CARE &&
605 config.redBits != info.redBits)
606 continue;
607
608 if (config.greenBits != glu::RenderConfig::DONT_CARE &&
609 config.greenBits != info.greenBits)
610 continue;
611
612 if (config.blueBits != glu::RenderConfig::DONT_CARE &&
613 config.blueBits != info.blueBits)
614 continue;
615
616 if (config.alphaBits != glu::RenderConfig::DONT_CARE &&
617 config.alphaBits != info.alphaBits)
618 continue;
619
620 if (config.depthBits != glu::RenderConfig::DONT_CARE &&
621 config.depthBits != info.depthBits)
622 continue;
623
624 if (config.stencilBits != glu::RenderConfig::DONT_CARE &&
625 config.stencilBits != info.stencilBits)
626 continue;
627
628 if (config.numSamples != glu::RenderConfig::DONT_CARE &&
629 config.numSamples != info.samples)
630 continue;
631
632 // Passed all tests - select this.
633 return info.pixelFormat;
634 }
635
636 return -1;
637 }
638
639 } // wgl
640 } // tcu
641