Home | History | Annotate | Download | only in win32
      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
    632