1/*-------------------------------------------------------------------------
2 * drawElements Quality Program EGL Module
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 Simple context construction test for EGL_KHR_create_context.
22 *//*--------------------------------------------------------------------*/
23
24#include "teglCreateContextExtTests.hpp"
25
26#include "tcuTestLog.hpp"
27
28#include "egluNativeDisplay.hpp"
29#include "egluNativeWindow.hpp"
30#include "egluNativePixmap.hpp"
31#include "egluConfigFilter.hpp"
32#include "egluStrUtil.hpp"
33#include "egluUtil.hpp"
34#include "egluUnique.hpp"
35
36#include "eglwLibrary.hpp"
37#include "eglwEnums.hpp"
38
39#include "gluDefs.hpp"
40#include "gluRenderConfig.hpp"
41
42#include "glwFunctions.hpp"
43#include "glwEnums.hpp"
44
45#include "deStringUtil.hpp"
46#include "deUniquePtr.hpp"
47#include "deSTLUtil.hpp"
48
49#include <string>
50#include <vector>
51#include <set>
52#include <sstream>
53
54#include <cstring>
55
56using std::set;
57using std::string;
58using std::vector;
59using tcu::TestLog;
60
61using namespace eglw;
62
63// Make sure KHR / core values match to those in GL_ARB_robustness and GL_EXT_robustness
64DE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY	== 0x8256);
65DE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET		== 0x8252);
66DE_STATIC_ASSERT(GL_NO_RESET_NOTIFICATION		== 0x8261);
67
68#if !defined(GL_CONTEXT_ROBUST_ACCESS)
69#	define GL_CONTEXT_ROBUST_ACCESS		0x90F3
70#endif
71
72namespace deqp
73{
74namespace egl
75{
76
77namespace
78{
79
80size_t getAttribListLength (const EGLint* attribList)
81{
82	size_t size = 0;
83
84	while (attribList[size] != EGL_NONE)
85		size++;
86
87	return size + 1;
88}
89
90string eglContextFlagsToString (EGLint flags)
91{
92	std::ostringstream	stream;
93
94	if (flags == 0)
95		stream << "<None>";
96	else
97	{
98		bool first = true;
99
100		if ((flags & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0)
101		{
102			if (!first)
103				stream << "|";
104
105			first = false;
106
107			stream << "EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR";
108		}
109
110		if ((flags & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
111		{
112			if (!first)
113				stream << "|";
114
115			first = false;
116
117			stream << "EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR";
118		}
119
120		if ((flags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0)
121		{
122			if (!first)
123				stream << "|";
124
125			stream << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR";
126		}
127	}
128
129	return stream.str();
130}
131
132string eglProfileMaskToString (EGLint mask)
133{
134	std::ostringstream	stream;
135
136	if (mask == 0)
137		stream << "<None>";
138	else
139	{
140		bool first = true;
141
142		if ((mask & EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) != 0)
143		{
144			if (!first)
145				stream << "|";
146
147			first = false;
148
149			stream << "EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR";
150		}
151
152		if ((mask & EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR) != 0)
153		{
154			if (!first)
155				stream << "|";
156
157			stream << "EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR";
158		}
159	}
160
161	return stream.str();
162}
163
164const char* eglResetNotificationStrategyToString (EGLint strategy)
165{
166	switch (strategy)
167	{
168		case EGL_NO_RESET_NOTIFICATION_KHR:		return "EGL_NO_RESET_NOTIFICATION_KHR";
169		case EGL_LOSE_CONTEXT_ON_RESET_KHR:		return "EGL_LOSE_CONTEXT_ON_RESET_KHR";
170		default:
171			return "<Unknown>";
172	}
173}
174
175class CreateContextExtCase : public TestCase
176{
177public:
178								CreateContextExtCase	(EglTestContext& eglTestCtx, EGLenum api, const EGLint* attribList, const eglu::FilterList& filter, const char* name, const char* description);
179								~CreateContextExtCase	(void);
180
181	void						executeForSurface		(EGLConfig config, EGLSurface surface);
182
183	void						init					(void);
184	void						deinit					(void);
185
186	IterateResult				iterate					(void);
187	void						checkRequiredExtensions	(void);
188	void						logAttribList			(void);
189	bool						validateCurrentContext	(const glw::Functions& gl);
190
191private:
192	bool						m_isOk;
193	int							m_iteration;
194
195	const eglu::FilterList		m_filter;
196	vector<EGLint>				m_attribList;
197	const EGLenum				m_api;
198
199	EGLDisplay					m_display;
200	vector<EGLConfig>			m_configs;
201	glu::ContextType			m_glContextType;
202};
203
204glu::ContextType attribListToContextType (EGLenum api, const EGLint* attribList)
205{
206	EGLint				majorVersion	= 1;
207	EGLint				minorVersion	= 0;
208	glu::ContextFlags	flags			= glu::ContextFlags(0);
209	glu::Profile		profile			= api == EGL_OPENGL_ES_API ? glu::PROFILE_ES : glu::PROFILE_CORE;
210	const EGLint*		iter			= attribList;
211
212	while ((*iter) != EGL_NONE)
213	{
214		switch (*iter)
215		{
216			case EGL_CONTEXT_MAJOR_VERSION_KHR:
217				iter++;
218				majorVersion = (*iter);
219				iter++;
220				break;
221
222			case EGL_CONTEXT_MINOR_VERSION_KHR:
223				iter++;
224				minorVersion = (*iter);
225				iter++;
226				break;
227
228			case EGL_CONTEXT_FLAGS_KHR:
229				iter++;
230
231				if ((*iter & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) != 0)
232					flags = flags | glu::CONTEXT_ROBUST;
233
234				if ((*iter & EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) != 0)
235					flags = flags | glu::CONTEXT_DEBUG;
236
237				if ((*iter & EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) != 0)
238					flags = flags | glu::CONTEXT_FORWARD_COMPATIBLE;
239
240				iter++;
241				break;
242
243			case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
244				iter++;
245
246				if (*iter == EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR)
247					profile = glu::PROFILE_COMPATIBILITY;
248				else if (*iter != EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR)
249					throw tcu::InternalError("Indeterminate OpenGL profile");
250
251				iter++;
252				break;
253
254			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
255				iter += 2;
256				break;
257
258			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
259				iter += 2;
260				break;
261
262			case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
263				iter += 2;
264				break;
265
266			default:
267				DE_ASSERT(DE_FALSE);
268		}
269	}
270
271	return glu::ContextType(majorVersion, minorVersion, profile, flags);
272}
273
274CreateContextExtCase::CreateContextExtCase (EglTestContext& eglTestCtx, EGLenum api, const EGLint* attribList, const eglu::FilterList& filter, const char* name, const char* description)
275	: TestCase			(eglTestCtx, name, description)
276	, m_isOk			(true)
277	, m_iteration		(0)
278	, m_filter			(filter)
279	, m_attribList		(attribList, attribList + getAttribListLength(attribList))
280	, m_api				(api)
281	, m_display			(EGL_NO_DISPLAY)
282	, m_glContextType	(attribListToContextType(api, attribList))
283{
284}
285
286CreateContextExtCase::~CreateContextExtCase (void)
287{
288	deinit();
289}
290
291void CreateContextExtCase::init (void)
292{
293	m_display	= eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
294	m_configs	= eglu::chooseConfigs(m_eglTestCtx.getLibrary(), m_display, m_filter);
295}
296
297void CreateContextExtCase::deinit (void)
298{
299	m_attribList.clear();
300	m_configs.clear();
301
302	if (m_display != EGL_NO_DISPLAY)
303	{
304		m_eglTestCtx.getLibrary().terminate(m_display);
305		m_display = EGL_NO_DISPLAY;
306	}
307}
308
309void CreateContextExtCase::logAttribList (void)
310{
311	const EGLint*		iter = &(m_attribList[0]);
312	std::ostringstream	attribListString;
313
314	while ((*iter) != EGL_NONE)
315	{
316		switch (*iter)
317		{
318			case EGL_CONTEXT_MAJOR_VERSION_KHR:
319				iter++;
320				attribListString << "EGL_CONTEXT_MAJOR_VERSION_KHR(EGL_CONTEXT_CLIENT_VERSION), " << (*iter) << ", ";
321				iter++;
322				break;
323
324			case EGL_CONTEXT_MINOR_VERSION_KHR:
325				iter++;
326				attribListString << "EGL_CONTEXT_MINOR_VERSION_KHR, " << (*iter) << ", ";
327				iter++;
328				break;
329
330			case EGL_CONTEXT_FLAGS_KHR:
331				iter++;
332				attribListString << "EGL_CONTEXT_FLAGS_KHR, " << eglContextFlagsToString(*iter) << ", ";
333				iter++;
334				break;
335
336			case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
337				iter++;
338				attribListString << "EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, " << eglProfileMaskToString(*iter) << ", ";
339				iter++;
340				break;
341
342			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
343				iter++;
344				attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR, " << eglResetNotificationStrategyToString(*iter) << ", ";
345				iter++;
346				break;
347
348			case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
349				iter++;
350				attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, ";
351
352				if (*iter == EGL_FALSE || *iter == EGL_TRUE)
353					attribListString << (*iter ? "EGL_TRUE" : "EGL_FALSE");
354				else
355					attribListString << (*iter);
356				iter++;
357				break;
358
359			default:
360				DE_ASSERT(DE_FALSE);
361		}
362	}
363
364	attribListString << "EGL_NONE";
365	m_testCtx.getLog() << TestLog::Message << "EGL attrib list: { " << attribListString.str() << " }" << TestLog::EndMessage;
366}
367
368void CreateContextExtCase::checkRequiredExtensions (void)
369{
370	bool			isOk = true;
371	set<string>		requiredExtensions;
372	vector<string>	extensions			= eglu::getClientExtensions(m_eglTestCtx.getLibrary(), m_display);
373
374	{
375		const EGLint* iter = &(m_attribList[0]);
376
377		while ((*iter) != EGL_NONE)
378		{
379			switch (*iter)
380			{
381				case EGL_CONTEXT_MAJOR_VERSION_KHR:
382					iter++;
383					iter++;
384					break;
385
386				case EGL_CONTEXT_MINOR_VERSION_KHR:
387					iter++;
388					requiredExtensions.insert("EGL_KHR_create_context");
389					iter++;
390					break;
391
392				case EGL_CONTEXT_FLAGS_KHR:
393					iter++;
394					requiredExtensions.insert("EGL_KHR_create_context");
395					iter++;
396					break;
397
398				case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
399					iter++;
400					requiredExtensions.insert("EGL_KHR_create_context");
401					iter++;
402					break;
403
404				case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
405					iter++;
406					requiredExtensions.insert("EGL_KHR_create_context");
407					iter++;
408					break;
409
410				case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
411					iter++;
412					requiredExtensions.insert("EGL_EXT_create_context_robustness");
413					iter++;
414					break;
415
416				case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
417					iter++;
418					requiredExtensions.insert("EGL_EXT_create_context_robustness");
419					iter++;
420					break;
421
422				default:
423					DE_ASSERT(DE_FALSE);
424			}
425		}
426	}
427
428	for (std::set<string>::const_iterator reqExt = requiredExtensions.begin(); reqExt != requiredExtensions.end(); ++reqExt)
429	{
430		if (!de::contains(extensions.begin(), extensions.end(), *reqExt))
431		{
432			m_testCtx.getLog() << TestLog::Message << "Required extension '" << (*reqExt) << "' not supported" << TestLog::EndMessage;
433			isOk = false;
434		}
435	}
436
437	if (!isOk)
438		TCU_THROW(NotSupportedError, "Required extensions not supported");
439}
440
441bool hasExtension (const glw::Functions& gl, const char* extension)
442{
443	std::istringstream	stream((const char*)gl.getString(GL_EXTENSIONS));
444	string				ext;
445
446	while (std::getline(stream, ext, ' '))
447	{
448		if (ext == extension)
449			return true;
450	}
451
452	return false;
453}
454
455bool checkVersionString (TestLog& log, const glw::Functions& gl, bool desktop, int major, int minor)
456{
457	const char* const	versionStr	= (const char*)gl.getString(GL_VERSION);
458	const char*			iter		= versionStr;
459
460	int majorVersion = 0;
461	int minorVersion = 0;
462
463	// Check embedded version prefixes
464	if (!desktop)
465	{
466		const char* prefix		= NULL;
467		const char* prefixIter	= NULL;
468
469		if (major == 1)
470			prefix = "OpenGL ES-CM ";
471		else
472			prefix = "OpenGL ES ";
473
474		prefixIter = prefix;
475
476		while (*prefixIter)
477		{
478			if ((*prefixIter) != (*iter))
479			{
480				log << TestLog::Message << "Invalid version string prefix. Expected '" << prefix << "'." << TestLog::EndMessage;
481				return false;
482			}
483
484			prefixIter++;
485			iter++;
486		}
487	}
488
489	while ((*iter) && (*iter) != '.')
490	{
491		const int val = (*iter) - '0';
492
493		// Not a number
494		if (val < 0 || val > 9)
495		{
496			log << TestLog::Message << "Failed to parse major version number. Not a number." << TestLog::EndMessage;
497			return false;
498		}
499
500		// Leading zero
501		if (majorVersion == 0 && val == 0)
502		{
503			log << TestLog::Message << "Failed to parse major version number. Begins with zero." << TestLog::EndMessage;
504			return false;
505		}
506
507		majorVersion = majorVersion * 10 + val;
508
509		iter++;
510	}
511
512	// Invalid format
513	if ((*iter) != '.')
514	{
515		log << TestLog::Message << "Failed to parse version. Expected '.' after major version number." << TestLog::EndMessage;
516		return false;
517	}
518
519	iter++;
520
521	while ((*iter) && (*iter) != ' ' && (*iter) != '.')
522	{
523		const int val = (*iter) - '0';
524
525		// Not a number
526		if (val < 0 || val > 9)
527		{
528			log << TestLog::Message << "Failed to parse minor version number. Not a number." << TestLog::EndMessage;
529			return false;
530		}
531
532		// Leading zero
533		if (minorVersion == 0 && val == 0)
534		{
535			// Leading zeros in minor version
536			if ((*(iter + 1)) != ' ' && (*(iter + 1)) != '.' && (*(iter + 1)) != '\0')
537			{
538				log << TestLog::Message << "Failed to parse minor version number. Leading zeros." << TestLog::EndMessage;
539				return false;
540			}
541		}
542
543		minorVersion = minorVersion * 10 + val;
544
545		iter++;
546	}
547
548	// Invalid format
549	if ((*iter) != ' ' && (*iter) != '.' && (*iter) != '\0')
550		return false;
551
552	if (desktop)
553	{
554		if (majorVersion < major)
555		{
556			log << TestLog::Message << "Major version is less than required." << TestLog::EndMessage;
557			return false;
558		}
559		else if (majorVersion == major && minorVersion < minor)
560		{
561			log << TestLog::Message << "Minor version is less than required." << TestLog::EndMessage;
562			return false;
563		}
564		else if (majorVersion == major && minorVersion == minor)
565			return true;
566
567		if (major < 3 || (major == 3 && minor == 0))
568		{
569			if (majorVersion == 3 && minorVersion == 1)
570			{
571				if (hasExtension(gl, "GL_ARB_compatibility"))
572					return true;
573				else
574				{
575					log << TestLog::Message << "Required OpenGL 3.0 or earlier. Got OpenGL 3.1 without GL_ARB_compatibility." << TestLog::EndMessage;
576					return false;
577				}
578			}
579			else if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= minor))
580			{
581				deInt32 profile = 0;
582
583				gl.getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
584				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
585
586				if (profile == GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
587					return true;
588				else
589				{
590					log << TestLog::Message << "Required OpenGL 3.0 or earlier. Got later version without compatibility profile." << TestLog::EndMessage;
591					return false;
592				}
593			}
594			else
595				DE_ASSERT(false);
596
597			return false;
598		}
599		else if (major == 3 && minor == 1)
600		{
601			if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= minor))
602			{
603				deInt32 profile = 0;
604
605				gl.getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
606				GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
607
608				if (profile == GL_CONTEXT_CORE_PROFILE_BIT)
609					return true;
610				else
611				{
612					log << TestLog::Message << "Required OpenGL 3.1. Got later version without core profile." << TestLog::EndMessage;
613					return false;
614				}
615			}
616			else
617				DE_ASSERT(false);
618
619			return false;
620		}
621		else
622		{
623			log << TestLog::Message << "Couldn't do any further compatibilyt checks." << TestLog::EndMessage;
624			return true;
625		}
626	}
627	else
628	{
629		if (majorVersion < major)
630		{
631			log << TestLog::Message << "Major version is less than required." << TestLog::EndMessage;
632			return false;
633		}
634		else if (majorVersion == major && minorVersion < minor)
635		{
636			log << TestLog::Message << "Minor version is less than required." << TestLog::EndMessage;
637			return false;
638		}
639		else
640			return true;
641	}
642}
643
644bool checkVersionQueries (TestLog& log, const glw::Functions& gl, int major, int minor)
645{
646	deInt32 majorVersion = 0;
647	deInt32	minorVersion = 0;
648
649	gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
650	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
651
652	gl.getIntegerv(GL_MINOR_VERSION, &minorVersion);
653	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
654
655	if (majorVersion < major || (majorVersion == major && minorVersion < minor))
656	{
657		if (majorVersion < major)
658			log << TestLog::Message << "glGetIntegerv(GL_MAJOR_VERSION) returned '" << majorVersion << "' expected at least '" << major << "'" << TestLog::EndMessage;
659		else if (majorVersion == major && minorVersion < minor)
660			log << TestLog::Message << "glGetIntegerv(GL_MINOR_VERSION) returned '" << minorVersion << "' expected '" << minor << "'" << TestLog::EndMessage;
661		else
662			DE_ASSERT(false);
663
664		return false;
665	}
666	else
667		return true;
668}
669
670bool CreateContextExtCase::validateCurrentContext (const glw::Functions& gl)
671{
672	bool				isOk					= true;
673	TestLog&			log						= m_testCtx.getLog();
674	const EGLint*		iter					= &(m_attribList[0]);
675
676	EGLint				majorVersion			= -1;
677	EGLint				minorVersion			= -1;
678	EGLint				contextFlags			= -1;
679	EGLint				profileMask				= -1;
680	EGLint				notificationStrategy	= -1;
681	EGLint				robustAccessExt			= -1;
682	EGLint				notificationStrategyExt	= -1;
683
684	while ((*iter) != EGL_NONE)
685	{
686		switch (*iter)
687		{
688			case EGL_CONTEXT_MAJOR_VERSION_KHR:
689				iter++;
690				majorVersion = (*iter);
691				iter++;
692				break;
693
694			case EGL_CONTEXT_MINOR_VERSION_KHR:
695				iter++;
696				minorVersion = (*iter);
697				iter++;
698				break;
699
700			case EGL_CONTEXT_FLAGS_KHR:
701				iter++;
702				contextFlags = (*iter);
703				iter++;
704				break;
705
706			case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
707				iter++;
708				profileMask = (*iter);
709				iter++;
710				break;
711
712			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
713				iter++;
714				notificationStrategy = (*iter);
715				iter++;
716				break;
717
718			case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
719				iter++;
720				robustAccessExt = *iter;
721				iter++;
722				break;
723
724			case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
725				iter++;
726				notificationStrategyExt = *iter;
727				iter++;
728				break;
729
730			default:
731				DE_ASSERT(DE_FALSE);
732		}
733	}
734
735	const string version = (const char*)gl.getString(GL_VERSION);
736
737	log << TestLog::Message << "GL_VERSION: '" << version << "'" << TestLog::EndMessage;
738
739	if (majorVersion == -1)
740		majorVersion = 1;
741
742	if (minorVersion == -1)
743		minorVersion = 0;
744
745	if (m_api == EGL_OPENGL_ES_API)
746	{
747		if (!checkVersionString(log, gl, false, majorVersion, minorVersion))
748			isOk = false;
749
750		if (majorVersion == 3)
751		{
752			if (!checkVersionQueries(log, gl, majorVersion, minorVersion))
753				isOk = false;
754		}
755	}
756	else if (m_api == EGL_OPENGL_API)
757	{
758		if (!checkVersionString(log, gl, true, majorVersion, minorVersion))
759			isOk = false;
760
761		if (majorVersion >= 3)
762		{
763			if (!checkVersionQueries(log, gl, majorVersion, minorVersion))
764				isOk = false;
765		}
766	}
767	else
768		DE_ASSERT(false);
769
770
771	if (contextFlags != -1)
772	{
773		if (m_api == EGL_OPENGL_API && (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)))
774		{
775			deInt32 contextFlagsGL;
776
777			DE_ASSERT(m_api == EGL_OPENGL_API);
778
779			if (contextFlags == -1)
780				contextFlags = 0;
781
782			gl.getIntegerv(GL_CONTEXT_FLAGS, &contextFlagsGL);
783
784			if (contextFlags != contextFlagsGL)
785			{
786				log << TestLog::Message << "Invalid GL_CONTEXT_FLAGS. Expected '" << eglContextFlagsToString(contextFlags) << "' got '" << eglContextFlagsToString(contextFlagsGL) << "'" << TestLog::EndMessage;
787				isOk = false;
788			}
789		}
790	}
791
792	if (profileMask != -1 || (m_api == EGL_OPENGL_API && (majorVersion >= 3)))
793	{
794		if (profileMask == -1)
795			profileMask = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
796
797		DE_ASSERT(m_api == EGL_OPENGL_API);
798
799		if (majorVersion < 3 || (majorVersion == 3 && minorVersion < 2))
800		{
801			// \note Ignore profile masks. This is not an error
802		}
803		else
804		{
805			deInt32 profileMaskGL = 0;
806
807			gl.getIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask);
808			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
809
810			if (profileMask != profileMaskGL)
811			{
812				log << TestLog::Message << "Invalid GL_CONTEXT_PROFILE_MASK. Expected '" << eglProfileMaskToString(profileMask) << "' got '" << eglProfileMaskToString(profileMaskGL) << "'" << TestLog::EndMessage;
813				isOk = false;
814			}
815		}
816	}
817
818	DE_ASSERT(notificationStrategy == -1 || notificationStrategyExt == -1);
819
820	if (notificationStrategy != -1 || notificationStrategyExt != -1)
821	{
822		const deInt32	expected	= notificationStrategy != -1 ? notificationStrategy : notificationStrategyExt;
823		deInt32			strategy	= 0;
824
825		gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &strategy);
826		GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
827
828		if (expected == EGL_NO_RESET_NOTIFICATION && strategy != GL_NO_RESET_NOTIFICATION)
829		{
830			log << TestLog::Message << "glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY) returned '" << strategy << "', expected 'GL_NO_RESET_NOTIFICATION'" << TestLog::EndMessage;
831			isOk = false;
832		}
833		else if (expected == EGL_LOSE_CONTEXT_ON_RESET && strategy != GL_LOSE_CONTEXT_ON_RESET)
834		{
835			log << TestLog::Message << "glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY) returned '" << strategy << "', expected 'GL_LOSE_CONTEXT_ON_RESET'" << TestLog::EndMessage;
836			isOk = false;
837		}
838	}
839
840	if (robustAccessExt == EGL_TRUE)
841	{
842		if (m_api == EGL_OPENGL_API)
843		{
844			if (!hasExtension(gl, "GL_ARB_robustness"))
845			{
846				log << TestLog::Message << "Created robustness context but it doesn't support GL_ARB_robustness." << TestLog::EndMessage;
847				isOk = false;
848			}
849		}
850		else if (m_api == EGL_OPENGL_ES_API)
851		{
852			if (!hasExtension(gl, "GL_EXT_robustness"))
853			{
854				log << TestLog::Message << "Created robustness context but it doesn't support GL_EXT_robustness." << TestLog::EndMessage;
855				isOk = false;
856			}
857		}
858
859		if (m_api == EGL_OPENGL_API && (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)))
860		{
861			deInt32 contextFlagsGL;
862
863			DE_ASSERT(m_api == EGL_OPENGL_API);
864
865			gl.getIntegerv(GL_CONTEXT_FLAGS, &contextFlagsGL);
866
867			if ((contextFlagsGL & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT) != 0)
868			{
869				log << TestLog::Message << "Invalid GL_CONTEXT_FLAGS. GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT to be set, got '" << eglContextFlagsToString(contextFlagsGL) << "'" << TestLog::EndMessage;
870				isOk = false;
871			}
872		}
873		else if (m_api == EGL_OPENGL_ES_API)
874		{
875			deUint8 robustAccessGL;
876
877			gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS, &robustAccessGL);
878			GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
879
880			if (robustAccessGL != GL_TRUE)
881			{
882				log << TestLog::Message << "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '" << robustAccessGL << "' expected GL_TRUE." << TestLog::EndMessage;
883				isOk = false;
884			}
885		}
886
887	}
888
889	return isOk;
890}
891
892TestCase::IterateResult CreateContextExtCase::iterate (void)
893{
894	if (m_iteration == 0)
895	{
896		logAttribList();
897		checkRequiredExtensions();
898	}
899
900	if (m_iteration < (int)m_configs.size())
901	{
902		const Library&		egl				= m_eglTestCtx.getLibrary();
903		const EGLConfig		config			= m_configs[m_iteration];
904		const EGLint		surfaceTypes	= eglu::getConfigAttribInt(egl, m_display, config, EGL_SURFACE_TYPE);
905		const EGLint		configId		= eglu::getConfigAttribInt(egl, m_display, config, EGL_CONFIG_ID);
906
907		if ((surfaceTypes & EGL_PBUFFER_BIT) != 0)
908		{
909			tcu::ScopedLogSection	section			(m_testCtx.getLog(), ("EGLConfig ID: " + de::toString(configId) + " with PBuffer").c_str(), ("EGLConfig ID: " + de::toString(configId)).c_str());
910			const EGLint			attribList[]	=
911			{
912				EGL_WIDTH,	64,
913				EGL_HEIGHT,	64,
914				EGL_NONE
915			};
916			eglu::UniqueSurface		surface			(egl, m_display, egl.createPbufferSurface(m_display, config, attribList));
917			EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface");
918
919			executeForSurface(config, *surface);
920		}
921		else if ((surfaceTypes & EGL_WINDOW_BIT) != 0)
922		{
923			const eglu::NativeWindowFactory&	factory	= eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
924
925			de::UniquePtr<eglu::NativeWindow>	window	(factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, config, DE_NULL, eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
926			eglu::UniqueSurface					surface	(egl, m_display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_display, config, DE_NULL));
927
928			executeForSurface(config, *surface);
929		}
930		else if ((surfaceTypes & EGL_PIXMAP_BIT) != 0)
931		{
932			const eglu::NativePixmapFactory&	factory	= eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
933
934			de::UniquePtr<eglu::NativePixmap>	pixmap	(factory.createPixmap(&m_eglTestCtx.getNativeDisplay(), m_display, config, DE_NULL, 256, 256));
935			eglu::UniqueSurface					surface	(egl, m_display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, m_display, config, DE_NULL));
936
937			executeForSurface(config, *surface);
938		}
939		else // No supported surface type
940			TCU_FAIL("Invalid or empty surface type bits");
941
942		m_iteration++;
943		return CONTINUE;
944	}
945	else
946	{
947		if (m_configs.size() == 0)
948		{
949			m_testCtx.getLog() << TestLog::Message << "No supported configs found" << TestLog::EndMessage;
950			m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "No supported configs found");
951		}
952		else if (m_isOk)
953			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
954		else
955			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
956
957		return STOP;
958	}
959}
960
961void CreateContextExtCase::executeForSurface (EGLConfig config, EGLSurface surface)
962{
963	const Library&	egl		= m_eglTestCtx.getLibrary();
964
965	EGLU_CHECK_CALL(egl, bindAPI(m_api));
966
967	try
968	{
969		glw::Functions		gl;
970		eglu::UniqueContext	context	(egl, m_display, egl.createContext(m_display, config, EGL_NO_CONTEXT, &m_attribList[0]));
971		EGLU_CHECK_MSG(egl, "eglCreateContext");
972
973		EGLU_CHECK_CALL(egl, makeCurrent(m_display, surface, surface, *context));
974
975		m_eglTestCtx.initGLFunctions(&gl, m_glContextType.getAPI());
976
977		if (!validateCurrentContext(gl))
978			m_isOk = false;
979	}
980	catch (const eglu::Error& error)
981	{
982		if (error.getError() == EGL_BAD_MATCH)
983			m_testCtx.getLog() << TestLog::Message << "Context creation failed with error EGL_BAD_CONTEXT. Config doesn't support api version." << TestLog::EndMessage;
984		else if (error.getError() == EGL_BAD_CONFIG)
985			m_testCtx.getLog() << TestLog::Message << "Context creation failed with error EGL_BAD_MATCH. Context attribute compination not supported." << TestLog::EndMessage;
986		else
987		{
988			m_testCtx.getLog() << TestLog::Message << "Context creation failed with error " << eglu::getErrorStr(error.getError()) << ". Error is not result of unsupported api etc." << TestLog::EndMessage;
989			m_isOk = false;
990		}
991	}
992
993	EGLU_CHECK_CALL(egl, makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
994}
995
996class CreateContextExtGroup : public TestCaseGroup
997{
998public:
999						CreateContextExtGroup	(EglTestContext& eglTestCtx, EGLenum api, EGLint apiBit, const EGLint* attribList, const char* name, const char* description);
1000	virtual				~CreateContextExtGroup	(void);
1001
1002	void				init					(void);
1003
1004private:
1005	const EGLenum		m_api;
1006	const EGLint		m_apiBit;
1007	vector<EGLint>		m_attribList;
1008};
1009
1010CreateContextExtGroup::CreateContextExtGroup (EglTestContext& eglTestCtx, EGLenum api, EGLint apiBit, const EGLint* attribList, const char* name, const char* description)
1011	: TestCaseGroup (eglTestCtx, name, description)
1012	, m_api			(api)
1013	, m_apiBit		(apiBit)
1014	, m_attribList	(attribList, attribList + getAttribListLength(attribList))
1015{
1016}
1017
1018CreateContextExtGroup::~CreateContextExtGroup (void)
1019{
1020}
1021
1022
1023template <int Red, int Green, int Blue, int Alpha>
1024static bool colorBits (const eglu::CandidateConfig& c)
1025{
1026	return c.redSize()		== Red		&&
1027		   c.greenSize()	== Green	&&
1028		   c.blueSize()		== Blue		&&
1029		   c.alphaSize()	== Alpha;
1030}
1031
1032static bool	hasDepth	(const eglu::CandidateConfig& c)	{ return c.depthSize() > 0;		}
1033static bool	noDepth		(const eglu::CandidateConfig& c)	{ return c.depthSize() == 0;	}
1034static bool	hasStencil	(const eglu::CandidateConfig& c)	{ return c.stencilSize() > 0;	}
1035static bool	noStencil	(const eglu::CandidateConfig& c)	{ return c.stencilSize() == 0;	}
1036
1037template <deUint32 Type>
1038static bool renderable (const eglu::CandidateConfig& c)
1039{
1040	return (c.renderableType() & Type) == Type;
1041}
1042
1043static eglu::ConfigFilter getRenderableFilter (deUint32 bits)
1044{
1045	switch (bits)
1046	{
1047		case EGL_OPENGL_ES2_BIT:	return renderable<EGL_OPENGL_ES2_BIT>;
1048		case EGL_OPENGL_ES3_BIT:	return renderable<EGL_OPENGL_ES3_BIT>;
1049		case EGL_OPENGL_BIT:		return renderable<EGL_OPENGL_BIT>;
1050		default:
1051			DE_ASSERT(false);
1052			return renderable<0>;
1053	}
1054}
1055
1056void CreateContextExtGroup::init (void)
1057{
1058	const struct
1059	{
1060		const char*				name;
1061		const char*				description;
1062
1063		eglu::ConfigFilter		colorFilter;
1064		eglu::ConfigFilter		depthFilter;
1065		eglu::ConfigFilter		stencilFilter;
1066	} groups[] =
1067	{
1068		{ "rgb565_no_depth_no_stencil",		"RGB565 configs without depth or stencil",		colorBits<5, 6, 5, 0>, noDepth, 	noStencil	},
1069		{ "rgb565_no_depth_stencil",		"RGB565 configs with stencil and no depth",		colorBits<5, 6, 5, 0>, noDepth,		hasStencil	},
1070		{ "rgb565_depth_no_stencil",		"RGB565 configs with depth and no stencil",		colorBits<5, 6, 5, 0>, hasDepth,	noStencil	},
1071		{ "rgb565_depth_stencil",			"RGB565 configs with depth and stencil",		colorBits<5, 6, 5, 0>, hasDepth,	hasStencil	},
1072
1073		{ "rgb888_no_depth_no_stencil",		"RGB888 configs without depth or stencil",		colorBits<8, 8, 8, 0>, noDepth, 	noStencil	},
1074		{ "rgb888_no_depth_stencil",		"RGB888 configs with stencil and no depth",		colorBits<8, 8, 8, 0>, noDepth,		hasStencil	},
1075		{ "rgb888_depth_no_stencil",		"RGB888 configs with depth and no stencil",		colorBits<8, 8, 8, 0>, hasDepth,	noStencil	},
1076		{ "rgb888_depth_stencil",			"RGB888 configs with depth and stencil",		colorBits<8, 8, 8, 0>, hasDepth,	hasStencil	},
1077
1078		{ "rgba4444_no_depth_no_stencil",	"RGBA4444 configs without depth or stencil",	colorBits<4, 4, 4, 4>, noDepth, 	noStencil	},
1079		{ "rgba4444_no_depth_stencil",		"RGBA4444 configs with stencil and no depth",	colorBits<4, 4, 4, 4>, noDepth,		hasStencil	},
1080		{ "rgba4444_depth_no_stencil",		"RGBA4444 configs with depth and no stencil",	colorBits<4, 4, 4, 4>, hasDepth, 	noStencil	},
1081		{ "rgba4444_depth_stencil",			"RGBA4444 configs with depth and stencil",		colorBits<4, 4, 4, 4>, hasDepth,	hasStencil	},
1082
1083		{ "rgba5551_no_depth_no_stencil",	"RGBA5551 configs without depth or stencil",	colorBits<5, 5, 5, 1>, noDepth, 	noStencil	},
1084		{ "rgba5551_no_depth_stencil",		"RGBA5551 configs with stencil and no depth",	colorBits<5, 5, 5, 1>, noDepth,		hasStencil	},
1085		{ "rgba5551_depth_no_stencil",		"RGBA5551 configs with depth and no stencil",	colorBits<5, 5, 5, 1>, hasDepth,	noStencil	},
1086		{ "rgba5551_depth_stencil",			"RGBA5551 configs with depth and stencil",		colorBits<5, 5, 5, 1>, hasDepth,	hasStencil	},
1087
1088		{ "rgba8888_no_depth_no_stencil",	"RGBA8888 configs without depth or stencil",	colorBits<8, 8, 8, 8>, noDepth, 	noStencil	},
1089		{ "rgba8888_no_depth_stencil",		"RGBA8888 configs with stencil and no depth",	colorBits<8, 8, 8, 8>, noDepth,		hasStencil	},
1090		{ "rgba8888_depth_no_stencil",		"RGBA8888 configs with depth and no stencil",	colorBits<8, 8, 8, 8>, hasDepth,	noStencil	},
1091		{ "rgba8888_depth_stencil",			"RGBA8888 configs with depth and stencil",		colorBits<8, 8, 8, 8>, hasDepth,	hasStencil	}
1092	};
1093
1094	for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groups); groupNdx++)
1095	{
1096		eglu::FilterList filter;
1097
1098		filter << groups[groupNdx].colorFilter
1099			   << groups[groupNdx].depthFilter
1100			   << groups[groupNdx].stencilFilter
1101			   << getRenderableFilter(m_apiBit);
1102
1103		addChild(new CreateContextExtCase(m_eglTestCtx, m_api, &(m_attribList[0]), filter, groups[groupNdx].name, groups[groupNdx].description));
1104	}
1105	// \todo [mika] Add other group
1106}
1107
1108} // anonymous
1109
1110CreateContextExtTests::CreateContextExtTests (EglTestContext& eglTestCtx)
1111	: TestCaseGroup(eglTestCtx, "create_context_ext", "EGL_KHR_create_context tests.")
1112{
1113}
1114
1115CreateContextExtTests::~CreateContextExtTests (void)
1116{
1117}
1118
1119void CreateContextExtTests::init (void)
1120{
1121	const size_t	maxAttributeCount = 10;
1122	const struct
1123	{
1124		const char*	name;
1125		const char*	description;
1126		EGLenum		api;
1127		EGLint		apiBit;
1128		EGLint		attribList[maxAttributeCount];
1129	} groupList[] =
1130	{
1131#if 0
1132		// \todo [mika] Not supported by glw
1133		// OpenGL ES 1.x
1134		{ "gles_10", "Create OpenGL ES 1.0 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES_BIT,
1135			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE} },
1136		{ "gles_11", "Create OpenGL ES 1.1 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES_BIT,
1137			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1138#endif
1139		// OpenGL ES 2.x
1140		{ "gles_20", "Create OpenGL ES 2.0 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES2_BIT,
1141			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 2, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1142		// OpenGL ES 3.x
1143		{ "gles_30", "Create OpenGL ES 3.0 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES3_BIT_KHR,
1144			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE} },
1145#if 0
1146		// \todo [mika] Not supported by glw
1147		// \note [mika] Should we really test 1.x?
1148		{ "gl_10", "Create OpenGL 1.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1149			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE} },
1150		{ "gl_11", "Create OpenGL 1.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1151			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1152
1153		// OpenGL 2.x
1154		{ "gl_20", "Create OpenGL 2.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1155			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 2, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1156		{ "gl_21", "Create OpenGL 2.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1157			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 2, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1158#endif
1159		// OpenGL 3.x
1160		{ "gl_30", "Create OpenGL 3.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1161			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1162		{ "robust_gl_30", "Create robust OpenGL 3.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1163			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1164		{ "gl_31", "Create OpenGL 3.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1165			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1166		{ "robust_gl_31", "Create robust OpenGL 3.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1167			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1168		{ "gl_32", "Create OpenGL 3.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1169			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_NONE } },
1170		{ "robust_gl_32", "Create robust OpenGL 3.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1171			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1172		{ "gl_33", "Create OpenGL 3.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1173			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 3, EGL_NONE } },
1174		{ "robust_gl_33", "Create robust OpenGL 3.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1175			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 3, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1176
1177		// OpenGL 4.x
1178		{ "gl_40", "Create OpenGL 4.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1179			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1180		{ "robust_gl_40", "Create robust OpenGL 4.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1181			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1182		{ "gl_41", "Create OpenGL 4.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1183			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1184		{ "robust_gl_41", "Create robust OpenGL 4.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1185			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1186		{ "gl_42", "Create OpenGL 4.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1187			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_NONE } },
1188		{ "robust_gl_42", "Create robust OpenGL 4.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1189			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1190		{ "gl_43", "Create OpenGL 4.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1191			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 3, EGL_NONE } },
1192		{ "robust_gl_43", "Create robust OpenGL 4.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1193			{ EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 3, EGL_CONTEXT_FLAGS_KHR, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR, EGL_NONE } },
1194
1195		// Robust contexts with EGL_EXT_create_context_robustness
1196		{ "robust_gles_2_ext", "Create robust OpenGL ES 2.0 context with EGL_EXT_create_context_robustness.", EGL_OPENGL_ES_API, EGL_OPENGL_ES2_BIT,
1197			{ EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_NONE } },
1198		{ "robust_gles_3_ext", "Create robust OpenGL ES 3.0 context with EGL_EXT_create_context_robustness.", EGL_OPENGL_ES_API, EGL_OPENGL_ES3_BIT_KHR,
1199			{ EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_NONE } },
1200#if 0
1201	// glu/glw doesn't support any version of OpenGL and EGL doesn't allow use of EGL_CONTEXT_CLIENT_VERSION with OpenGL and doesn't define which OpenGL version should be returned.
1202		{ "robust_gl_ext", "Create robust OpenGL context with EGL_EXT_create_context_robustness.", EGL_OPENGL_API, EGL_OPENGL_BIT,
1203			{ EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_NONE } }
1204#endif
1205	};
1206
1207	for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groupList); groupNdx++)
1208		addChild(new CreateContextExtGroup(m_eglTestCtx, groupList[groupNdx].api, groupList[groupNdx].apiBit, groupList[groupNdx].attribList, groupList[groupNdx].name, groupList[groupNdx].description));
1209}
1210
1211} // egl
1212} // deqp
1213