Fix warning introduced in 2c9e3ec9 am: d8b452a753 am: 03dde47b9d am: 9333757172
[platform/upstream/VK-GL-CTS.git] / framework / platform / win32 / tcuWGL.cpp
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