• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
Functionstcu::wgl::Functions178 	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 
getFunctions(void) const201 	const Functions&			getFunctions	(void) const	{ return m_functions;	}
getGLLibrary(void) const202 	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 
Library(HINSTANCE instance)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 
~Library(void)283 Library::~Library (void)
284 {
285 }
286 
isWglExtensionSupported(const char * extName) const287 bool Library::isWglExtensionSupported (const char* extName) const
288 {
289 	return m_extensions.find(extName) != m_extensions.end();
290 }
291 
292 // Core
293 
Core(HINSTANCE instance)294 Core::Core (HINSTANCE instance)
295 	: m_library(new Library(instance))
296 {
297 }
298 
~Core(void)299 Core::~Core (void)
300 {
301 	delete m_library;
302 }
303 
getPixelFormats(HDC deviceCtx) const304 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 
translateAcceleration(int accel)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 
translatePixelType(int type)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 
getPixelFormatAttribs(const Functions & wgl,HDC deviceCtx,int pixelFormat,int numAttribs,const int * attribs,std::map<int,int> * dst)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 
getPixelFormatInfo(HDC deviceCtx,int pixelFormat) const355 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 
Context(const Core * core,HDC deviceCtx,const Context * sharedContext,glu::ContextType ctxType,int pixelFormat,glu::ResetNotificationStrategy resetNotificationStrategy)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 
~Context(void)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 
getGLFunction(const char * name) const560 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 
makeCurrent(void)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 
swapBuffers(void) const581 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 
isSupportedByTests(const PixelFormatInfo & info)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 
choosePixelFormat(const Core & wgl,HDC deviceCtx,const glu::RenderConfig & config)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
663