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