Fix missing dependency on sparse binds
[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_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, const int *piAttributes, int *piValues);
137 typedef BOOL            (WINAPI* wglGetPixelFormatAttribfvARBFunc)      (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
138 typedef BOOL            (WINAPI* wglChoosePixelFormatARBFunc)           (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
139
140 // WGL_ARB_create_context
141 typedef HGLRC           (WINAPI* wglCreateContextAttribsARBFunc)        (HDC hdc, HGLRC hshareContext, const int* attribList);
142 typedef const char*     (WINAPI* wglGetExtensionsStringARBFunc)         (HDC hdc);
143
144 // WGL_EXT_swap_control
145 typedef BOOL            (WINAPI* wglSwapIntervalEXTFunc)                        (int interval);
146
147 DE_END_EXTERN_C
148
149 namespace tcu
150 {
151 namespace wgl
152 {
153
154 // Functions
155
156 struct 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
195 class Library
196 {
197 public:
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
205 private:
206         de::DynamicLibrary                      m_library;
207         Functions                                       m_functions;
208         std::set<std::string>           m_extensions;
209 };
210
211 Library::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
283 Library::~Library (void)
284 {
285 }
286
287 bool Library::isWglExtensionSupported (const char* extName) const
288 {
289         return m_extensions.find(extName) != m_extensions.end();
290 }
291
292 // Core
293
294 Core::Core (HINSTANCE instance)
295         : m_library(new Library(instance))
296 {
297 }
298
299 Core::~Core (void)
300 {
301         delete m_library;
302 }
303
304 std::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
321 static 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
332 static 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
344 static 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
355 PixelFormatInfo 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
421 Context::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
552 Context::~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
560 FunctionPtr 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
574 void 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
581 void 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
588 bool 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
614 int 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