Merge vk-gl-cts/vulkan-cts-1.1.3 into vk-gl-cts/master
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglCreateContextExtTests.cpp
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
56 using std::set;
57 using std::string;
58 using std::vector;
59 using tcu::TestLog;
60
61 using namespace eglw;
62
63 // Make sure KHR / core values match to those in GL_ARB_robustness and GL_EXT_robustness
64 DE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY == 0x8256);
65 DE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET               == 0x8252);
66 DE_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
72 namespace deqp
73 {
74 namespace egl
75 {
76
77 namespace
78 {
79
80 size_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
90 string 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
132 string 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
164 const 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
175 class CreateContextExtCase : public TestCase
176 {
177 public:
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
191 private:
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
204 glu::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
274 CreateContextExtCase::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
286 CreateContextExtCase::~CreateContextExtCase (void)
287 {
288         deinit();
289 }
290
291 void 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
297 void 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
309 void 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
368 void CreateContextExtCase::checkRequiredExtensions (void)
369 {
370         bool                    isOk = true;
371         set<string>             requiredExtensions;
372         vector<string>  extensions                      = eglu::getDisplayExtensions(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
441 bool checkVersionString (TestLog& log, const glw::Functions& gl, bool desktop, int major, int minor)
442 {
443         const char* const       versionStr      = (const char*)gl.getString(GL_VERSION);
444         const char*                     iter            = versionStr;
445
446         int majorVersion = 0;
447         int minorVersion = 0;
448
449         // Check embedded version prefixes
450         if (!desktop)
451         {
452                 const char* prefix              = NULL;
453                 const char* prefixIter  = NULL;
454
455                 if (major == 1)
456                         prefix = "OpenGL ES-CM ";
457                 else
458                         prefix = "OpenGL ES ";
459
460                 prefixIter = prefix;
461
462                 while (*prefixIter)
463                 {
464                         if ((*prefixIter) != (*iter))
465                         {
466                                 log << TestLog::Message << "Invalid version string prefix. Expected '" << prefix << "'." << TestLog::EndMessage;
467                                 return false;
468                         }
469
470                         prefixIter++;
471                         iter++;
472                 }
473         }
474
475         while ((*iter) && (*iter) != '.')
476         {
477                 const int val = (*iter) - '0';
478
479                 // Not a number
480                 if (val < 0 || val > 9)
481                 {
482                         log << TestLog::Message << "Failed to parse major version number. Not a number." << TestLog::EndMessage;
483                         return false;
484                 }
485
486                 // Leading zero
487                 if (majorVersion == 0 && val == 0)
488                 {
489                         log << TestLog::Message << "Failed to parse major version number. Begins with zero." << TestLog::EndMessage;
490                         return false;
491                 }
492
493                 majorVersion = majorVersion * 10 + val;
494
495                 iter++;
496         }
497
498         // Invalid format
499         if ((*iter) != '.')
500         {
501                 log << TestLog::Message << "Failed to parse version. Expected '.' after major version number." << TestLog::EndMessage;
502                 return false;
503         }
504
505         iter++;
506
507         while ((*iter) && (*iter) != ' ' && (*iter) != '.')
508         {
509                 const int val = (*iter) - '0';
510
511                 // Not a number
512                 if (val < 0 || val > 9)
513                 {
514                         log << TestLog::Message << "Failed to parse minor version number. Not a number." << TestLog::EndMessage;
515                         return false;
516                 }
517
518                 // Leading zero
519                 if (minorVersion == 0 && val == 0)
520                 {
521                         // Leading zeros in minor version
522                         if ((*(iter + 1)) != ' ' && (*(iter + 1)) != '.' && (*(iter + 1)) != '\0')
523                         {
524                                 log << TestLog::Message << "Failed to parse minor version number. Leading zeros." << TestLog::EndMessage;
525                                 return false;
526                         }
527                 }
528
529                 minorVersion = minorVersion * 10 + val;
530
531                 iter++;
532         }
533
534         // Invalid format
535         if ((*iter) != ' ' && (*iter) != '.' && (*iter) != '\0')
536                 return false;
537
538         if (desktop)
539         {
540                 if (majorVersion < major)
541                 {
542                         log << TestLog::Message << "Major version is less than required." << TestLog::EndMessage;
543                         return false;
544                 }
545                 else if (majorVersion == major && minorVersion < minor)
546                 {
547                         log << TestLog::Message << "Minor version is less than required." << TestLog::EndMessage;
548                         return false;
549                 }
550                 else if (majorVersion == major && minorVersion == minor)
551                         return true;
552
553                 if (major < 3 || (major == 3 && minor == 0))
554                 {
555                         if (majorVersion == 3 && minorVersion == 1)
556                         {
557                                 if (glu::hasExtension(gl, glu::ApiType::core(3, 1), "GL_ARB_compatibility"))
558                                         return true;
559                                 else
560                                 {
561                                         log << TestLog::Message << "Required OpenGL 3.0 or earlier. Got OpenGL 3.1 without GL_ARB_compatibility." << TestLog::EndMessage;
562                                         return false;
563                                 }
564                         }
565                         else if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= minor))
566                         {
567                                 deInt32 profile = 0;
568
569                                 gl.getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
570                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
571
572                                 if (profile == GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
573                                         return true;
574                                 else
575                                 {
576                                         log << TestLog::Message << "Required OpenGL 3.0 or earlier. Got later version without compatibility profile." << TestLog::EndMessage;
577                                         return false;
578                                 }
579                         }
580                         else
581                                 DE_ASSERT(false);
582
583                         return false;
584                 }
585                 else if (major == 3 && minor == 1)
586                 {
587                         if (majorVersion > 3 || (majorVersion == 3 && minorVersion >= minor))
588                         {
589                                 deInt32 profile = 0;
590
591                                 gl.getIntegerv(GL_CONTEXT_PROFILE_MASK, &profile);
592                                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
593
594                                 if (profile == GL_CONTEXT_CORE_PROFILE_BIT)
595                                         return true;
596                                 else
597                                 {
598                                         log << TestLog::Message << "Required OpenGL 3.1. Got later version without core profile." << TestLog::EndMessage;
599                                         return false;
600                                 }
601                         }
602                         else
603                                 DE_ASSERT(false);
604
605                         return false;
606                 }
607                 else
608                 {
609                         log << TestLog::Message << "Couldn't do any further compatibilyt checks." << TestLog::EndMessage;
610                         return true;
611                 }
612         }
613         else
614         {
615                 if (majorVersion < major)
616                 {
617                         log << TestLog::Message << "Major version is less than required." << TestLog::EndMessage;
618                         return false;
619                 }
620                 else if (majorVersion == major && minorVersion < minor)
621                 {
622                         log << TestLog::Message << "Minor version is less than required." << TestLog::EndMessage;
623                         return false;
624                 }
625                 else
626                         return true;
627         }
628 }
629
630 bool checkVersionQueries (TestLog& log, const glw::Functions& gl, int major, int minor)
631 {
632         deInt32 majorVersion = 0;
633         deInt32 minorVersion = 0;
634
635         gl.getIntegerv(GL_MAJOR_VERSION, &majorVersion);
636         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
637
638         gl.getIntegerv(GL_MINOR_VERSION, &minorVersion);
639         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
640
641         if (majorVersion < major || (majorVersion == major && minorVersion < minor))
642         {
643                 if (majorVersion < major)
644                         log << TestLog::Message << "glGetIntegerv(GL_MAJOR_VERSION) returned '" << majorVersion << "' expected at least '" << major << "'" << TestLog::EndMessage;
645                 else if (majorVersion == major && minorVersion < minor)
646                         log << TestLog::Message << "glGetIntegerv(GL_MINOR_VERSION) returned '" << minorVersion << "' expected '" << minor << "'" << TestLog::EndMessage;
647                 else
648                         DE_ASSERT(false);
649
650                 return false;
651         }
652         else
653                 return true;
654 }
655
656 bool CreateContextExtCase::validateCurrentContext (const glw::Functions& gl)
657 {
658         bool                            isOk                                    = true;
659         TestLog&                        log                                             = m_testCtx.getLog();
660         const EGLint*           iter                                    = &(m_attribList[0]);
661
662         EGLint                          majorVersion                    = -1;
663         EGLint                          minorVersion                    = -1;
664         EGLint                          contextFlags                    = -1;
665         EGLint                          profileMask                             = -1;
666         EGLint                          notificationStrategy    = -1;
667         EGLint                          robustAccessExt                 = -1;
668         EGLint                          notificationStrategyExt = -1;
669
670         while ((*iter) != EGL_NONE)
671         {
672                 switch (*iter)
673                 {
674                         case EGL_CONTEXT_MAJOR_VERSION_KHR:
675                                 iter++;
676                                 majorVersion = (*iter);
677                                 iter++;
678                                 break;
679
680                         case EGL_CONTEXT_MINOR_VERSION_KHR:
681                                 iter++;
682                                 minorVersion = (*iter);
683                                 iter++;
684                                 break;
685
686                         case EGL_CONTEXT_FLAGS_KHR:
687                                 iter++;
688                                 contextFlags = (*iter);
689                                 iter++;
690                                 break;
691
692                         case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
693                                 iter++;
694                                 profileMask = (*iter);
695                                 iter++;
696                                 break;
697
698                         case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
699                                 iter++;
700                                 notificationStrategy = (*iter);
701                                 iter++;
702                                 break;
703
704                         case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
705                                 iter++;
706                                 robustAccessExt = *iter;
707                                 iter++;
708                                 break;
709
710                         case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
711                                 iter++;
712                                 notificationStrategyExt = *iter;
713                                 iter++;
714                                 break;
715
716                         default:
717                                 DE_ASSERT(DE_FALSE);
718                 }
719         }
720
721         const string version = (const char*)gl.getString(GL_VERSION);
722
723         log << TestLog::Message << "GL_VERSION: '" << version << "'" << TestLog::EndMessage;
724
725         if (majorVersion == -1)
726                 majorVersion = 1;
727
728         if (minorVersion == -1)
729                 minorVersion = 0;
730
731         if (m_api == EGL_OPENGL_ES_API)
732         {
733                 if (!checkVersionString(log, gl, false, majorVersion, minorVersion))
734                         isOk = false;
735
736                 if (majorVersion == 3)
737                 {
738                         if (!checkVersionQueries(log, gl, majorVersion, minorVersion))
739                                 isOk = false;
740                 }
741         }
742         else if (m_api == EGL_OPENGL_API)
743         {
744                 if (!checkVersionString(log, gl, true, majorVersion, minorVersion))
745                         isOk = false;
746
747                 if (majorVersion >= 3)
748                 {
749                         if (!checkVersionQueries(log, gl, majorVersion, minorVersion))
750                                 isOk = false;
751                 }
752         }
753         else
754                 DE_ASSERT(false);
755
756
757         if (contextFlags != -1)
758         {
759                 if (m_api == EGL_OPENGL_API && (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)))
760                 {
761                         deInt32 contextFlagsGL;
762
763                         DE_ASSERT(m_api == EGL_OPENGL_API);
764
765                         if (contextFlags == -1)
766                                 contextFlags = 0;
767
768                         gl.getIntegerv(GL_CONTEXT_FLAGS, &contextFlagsGL);
769
770                         if (contextFlags != contextFlagsGL)
771                         {
772                                 log << TestLog::Message << "Invalid GL_CONTEXT_FLAGS. Expected '" << eglContextFlagsToString(contextFlags) << "' got '" << eglContextFlagsToString(contextFlagsGL) << "'" << TestLog::EndMessage;
773                                 isOk = false;
774                         }
775                 }
776         }
777
778         if (profileMask != -1 || (m_api == EGL_OPENGL_API && (majorVersion >= 3)))
779         {
780                 if (profileMask == -1)
781                         profileMask = EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
782
783                 DE_ASSERT(m_api == EGL_OPENGL_API);
784
785                 if (majorVersion < 3 || (majorVersion == 3 && minorVersion < 2))
786                 {
787                         // \note Ignore profile masks. This is not an error
788                 }
789                 else
790                 {
791                         deInt32 profileMaskGL = 0;
792
793                         gl.getIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMaskGL);
794                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
795
796                         if (profileMask != profileMaskGL)
797                         {
798                                 log << TestLog::Message << "Invalid GL_CONTEXT_PROFILE_MASK. Expected '" << eglProfileMaskToString(profileMask) << "' got '" << eglProfileMaskToString(profileMaskGL) << "'" << TestLog::EndMessage;
799                                 isOk = false;
800                         }
801                 }
802         }
803
804         DE_ASSERT(notificationStrategy == -1 || notificationStrategyExt == -1);
805
806         if (notificationStrategy != -1 || notificationStrategyExt != -1)
807         {
808                 const deInt32   expected        = notificationStrategy != -1 ? notificationStrategy : notificationStrategyExt;
809                 deInt32                 strategy        = 0;
810
811                 gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &strategy);
812                 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
813
814                 if (expected == EGL_NO_RESET_NOTIFICATION && strategy != GL_NO_RESET_NOTIFICATION)
815                 {
816                         log << TestLog::Message << "glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY) returned '" << strategy << "', expected 'GL_NO_RESET_NOTIFICATION'" << TestLog::EndMessage;
817                         isOk = false;
818                 }
819                 else if (expected == EGL_LOSE_CONTEXT_ON_RESET && strategy != GL_LOSE_CONTEXT_ON_RESET)
820                 {
821                         log << TestLog::Message << "glGetIntegerv(GL_RESET_NOTIFICATION_STRATEGY) returned '" << strategy << "', expected 'GL_LOSE_CONTEXT_ON_RESET'" << TestLog::EndMessage;
822                         isOk = false;
823                 }
824         }
825
826         if (robustAccessExt == EGL_TRUE)
827         {
828                 if (m_api == EGL_OPENGL_API)
829                 {
830                         if (!glu::hasExtension(gl, glu::ApiType::core(majorVersion, minorVersion), "GL_ARB_robustness"))
831                         {
832                                 log << TestLog::Message << "Created robustness context but it doesn't support GL_ARB_robustness." << TestLog::EndMessage;
833                                 isOk = false;
834                         }
835                 }
836                 else if (m_api == EGL_OPENGL_ES_API)
837                 {
838                         if (!glu::hasExtension(gl, glu::ApiType::es(majorVersion, minorVersion), "GL_EXT_robustness"))
839                         {
840                                 log << TestLog::Message << "Created robustness context but it doesn't support GL_EXT_robustness." << TestLog::EndMessage;
841                                 isOk = false;
842                         }
843                 }
844
845                 if (m_api == EGL_OPENGL_API && (majorVersion > 3 || (majorVersion == 3 && minorVersion >= 1)))
846                 {
847                         deInt32 contextFlagsGL;
848
849                         DE_ASSERT(m_api == EGL_OPENGL_API);
850
851                         gl.getIntegerv(GL_CONTEXT_FLAGS, &contextFlagsGL);
852
853                         if ((contextFlagsGL & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT) != 0)
854                         {
855                                 log << TestLog::Message << "Invalid GL_CONTEXT_FLAGS. GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT to be set, got '" << eglContextFlagsToString(contextFlagsGL) << "'" << TestLog::EndMessage;
856                                 isOk = false;
857                         }
858                 }
859                 else if (m_api == EGL_OPENGL_ES_API)
860                 {
861                         deUint8 robustAccessGL;
862
863                         gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS, &robustAccessGL);
864                         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
865
866                         if (robustAccessGL != GL_TRUE)
867                         {
868                                 log << TestLog::Message << "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '" << robustAccessGL << "' expected GL_TRUE." << TestLog::EndMessage;
869                                 isOk = false;
870                         }
871                 }
872
873         }
874
875         return isOk;
876 }
877
878 TestCase::IterateResult CreateContextExtCase::iterate (void)
879 {
880         if (m_iteration == 0)
881         {
882                 logAttribList();
883                 checkRequiredExtensions();
884         }
885
886         if (m_iteration < (int)m_configs.size())
887         {
888                 const Library&          egl                             = m_eglTestCtx.getLibrary();
889                 const EGLConfig         config                  = m_configs[m_iteration];
890                 const EGLint            surfaceTypes    = eglu::getConfigAttribInt(egl, m_display, config, EGL_SURFACE_TYPE);
891                 const EGLint            configId                = eglu::getConfigAttribInt(egl, m_display, config, EGL_CONFIG_ID);
892
893                 if ((surfaceTypes & EGL_PBUFFER_BIT) != 0)
894                 {
895                         tcu::ScopedLogSection   section                 (m_testCtx.getLog(), ("EGLConfig ID: " + de::toString(configId) + " with PBuffer").c_str(), ("EGLConfig ID: " + de::toString(configId)).c_str());
896                         const EGLint                    attribList[]    =
897                         {
898                                 EGL_WIDTH,      64,
899                                 EGL_HEIGHT,     64,
900                                 EGL_NONE
901                         };
902                         eglu::UniqueSurface             surface                 (egl, m_display, egl.createPbufferSurface(m_display, config, attribList));
903                         EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface");
904
905                         executeForSurface(config, *surface);
906                 }
907                 else if ((surfaceTypes & EGL_WINDOW_BIT) != 0)
908                 {
909                         const eglu::NativeWindowFactory&        factory = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
910
911                         de::UniquePtr<eglu::NativeWindow>       window  (factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_display, config, DE_NULL, eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
912                         eglu::UniqueSurface                                     surface (egl, m_display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, m_display, config, DE_NULL));
913
914                         executeForSurface(config, *surface);
915                 }
916                 else if ((surfaceTypes & EGL_PIXMAP_BIT) != 0)
917                 {
918                         const eglu::NativePixmapFactory&        factory = eglu::selectNativePixmapFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
919
920                         de::UniquePtr<eglu::NativePixmap>       pixmap  (factory.createPixmap(&m_eglTestCtx.getNativeDisplay(), m_display, config, DE_NULL, 256, 256));
921                         eglu::UniqueSurface                                     surface (egl, m_display, eglu::createPixmapSurface(m_eglTestCtx.getNativeDisplay(), *pixmap, m_display, config, DE_NULL));
922
923                         executeForSurface(config, *surface);
924                 }
925                 else // No supported surface type
926                         TCU_FAIL("Invalid or empty surface type bits");
927
928                 m_iteration++;
929                 return CONTINUE;
930         }
931         else
932         {
933                 if (m_configs.size() == 0)
934                 {
935                         m_testCtx.getLog() << TestLog::Message << "No supported configs found" << TestLog::EndMessage;
936                         m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "No supported configs found");
937                 }
938                 else if (m_isOk)
939                         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
940                 else
941                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
942
943                 return STOP;
944         }
945 }
946
947 void CreateContextExtCase::executeForSurface (EGLConfig config, EGLSurface surface)
948 {
949         const Library&  egl             = m_eglTestCtx.getLibrary();
950
951         EGLU_CHECK_CALL(egl, bindAPI(m_api));
952
953         try
954         {
955                 glw::Functions          gl;
956                 eglu::UniqueContext     context (egl, m_display, egl.createContext(m_display, config, EGL_NO_CONTEXT, &m_attribList[0]));
957                 EGLU_CHECK_MSG(egl, "eglCreateContext");
958
959                 EGLU_CHECK_CALL(egl, makeCurrent(m_display, surface, surface, *context));
960
961                 m_eglTestCtx.initGLFunctions(&gl, m_glContextType.getAPI());
962
963                 if (!validateCurrentContext(gl))
964                         m_isOk = false;
965         }
966         catch (const eglu::Error& error)
967         {
968                 if (error.getError() == EGL_BAD_MATCH)
969                         m_testCtx.getLog() << TestLog::Message << "Context creation failed with error EGL_BAD_CONTEXT. Config doesn't support api version." << TestLog::EndMessage;
970                 else if (error.getError() == EGL_BAD_CONFIG)
971                         m_testCtx.getLog() << TestLog::Message << "Context creation failed with error EGL_BAD_MATCH. Context attribute compination not supported." << TestLog::EndMessage;
972                 else
973                 {
974                         m_testCtx.getLog() << TestLog::Message << "Context creation failed with error " << eglu::getErrorStr(error.getError()) << ". Error is not result of unsupported api etc." << TestLog::EndMessage;
975                         m_isOk = false;
976                 }
977         }
978
979         EGLU_CHECK_CALL(egl, makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
980 }
981
982 class CreateContextExtGroup : public TestCaseGroup
983 {
984 public:
985                                                 CreateContextExtGroup   (EglTestContext& eglTestCtx, EGLenum api, EGLint apiBit, const EGLint* attribList, const char* name, const char* description);
986         virtual                         ~CreateContextExtGroup  (void);
987
988         void                            init                                    (void);
989
990 private:
991         const EGLenum           m_api;
992         const EGLint            m_apiBit;
993         vector<EGLint>          m_attribList;
994 };
995
996 CreateContextExtGroup::CreateContextExtGroup (EglTestContext& eglTestCtx, EGLenum api, EGLint apiBit, const EGLint* attribList, const char* name, const char* description)
997         : TestCaseGroup (eglTestCtx, name, description)
998         , m_api                 (api)
999         , m_apiBit              (apiBit)
1000         , m_attribList  (attribList, attribList + getAttribListLength(attribList))
1001 {
1002 }
1003
1004 CreateContextExtGroup::~CreateContextExtGroup (void)
1005 {
1006 }
1007
1008
1009 template <int Red, int Green, int Blue, int Alpha>
1010 static bool colorBits (const eglu::CandidateConfig& c)
1011 {
1012         return c.redSize()              == Red          &&
1013                    c.greenSize()        == Green        &&
1014                    c.blueSize()         == Blue         &&
1015                    c.alphaSize()        == Alpha;
1016 }
1017
1018 static bool     hasDepth        (const eglu::CandidateConfig& c)        { return c.depthSize() > 0;             }
1019 static bool     noDepth         (const eglu::CandidateConfig& c)        { return c.depthSize() == 0;    }
1020 static bool     hasStencil      (const eglu::CandidateConfig& c)        { return c.stencilSize() > 0;   }
1021 static bool     noStencil       (const eglu::CandidateConfig& c)        { return c.stencilSize() == 0;  }
1022
1023 template <deUint32 Type>
1024 static bool renderable (const eglu::CandidateConfig& c)
1025 {
1026         return (c.renderableType() & Type) == Type;
1027 }
1028
1029 static eglu::ConfigFilter getRenderableFilter (deUint32 bits)
1030 {
1031         switch (bits)
1032         {
1033                 case EGL_OPENGL_ES2_BIT:        return renderable<EGL_OPENGL_ES2_BIT>;
1034                 case EGL_OPENGL_ES3_BIT:        return renderable<EGL_OPENGL_ES3_BIT>;
1035                 case EGL_OPENGL_BIT:            return renderable<EGL_OPENGL_BIT>;
1036                 default:
1037                         DE_ASSERT(false);
1038                         return renderable<0>;
1039         }
1040 }
1041
1042 void CreateContextExtGroup::init (void)
1043 {
1044         const struct
1045         {
1046                 const char*                             name;
1047                 const char*                             description;
1048
1049                 eglu::ConfigFilter              colorFilter;
1050                 eglu::ConfigFilter              depthFilter;
1051                 eglu::ConfigFilter              stencilFilter;
1052         } groups[] =
1053         {
1054                 { "rgb565_no_depth_no_stencil",         "RGB565 configs without depth or stencil",              colorBits<5, 6, 5, 0>, noDepth,         noStencil       },
1055                 { "rgb565_no_depth_stencil",            "RGB565 configs with stencil and no depth",             colorBits<5, 6, 5, 0>, noDepth,         hasStencil      },
1056                 { "rgb565_depth_no_stencil",            "RGB565 configs with depth and no stencil",             colorBits<5, 6, 5, 0>, hasDepth,        noStencil       },
1057                 { "rgb565_depth_stencil",                       "RGB565 configs with depth and stencil",                colorBits<5, 6, 5, 0>, hasDepth,        hasStencil      },
1058
1059                 { "rgb888_no_depth_no_stencil",         "RGB888 configs without depth or stencil",              colorBits<8, 8, 8, 0>, noDepth,         noStencil       },
1060                 { "rgb888_no_depth_stencil",            "RGB888 configs with stencil and no depth",             colorBits<8, 8, 8, 0>, noDepth,         hasStencil      },
1061                 { "rgb888_depth_no_stencil",            "RGB888 configs with depth and no stencil",             colorBits<8, 8, 8, 0>, hasDepth,        noStencil       },
1062                 { "rgb888_depth_stencil",                       "RGB888 configs with depth and stencil",                colorBits<8, 8, 8, 0>, hasDepth,        hasStencil      },
1063
1064                 { "rgba4444_no_depth_no_stencil",       "RGBA4444 configs without depth or stencil",    colorBits<4, 4, 4, 4>, noDepth,         noStencil       },
1065                 { "rgba4444_no_depth_stencil",          "RGBA4444 configs with stencil and no depth",   colorBits<4, 4, 4, 4>, noDepth,         hasStencil      },
1066                 { "rgba4444_depth_no_stencil",          "RGBA4444 configs with depth and no stencil",   colorBits<4, 4, 4, 4>, hasDepth,        noStencil       },
1067                 { "rgba4444_depth_stencil",                     "RGBA4444 configs with depth and stencil",              colorBits<4, 4, 4, 4>, hasDepth,        hasStencil      },
1068
1069                 { "rgba5551_no_depth_no_stencil",       "RGBA5551 configs without depth or stencil",    colorBits<5, 5, 5, 1>, noDepth,         noStencil       },
1070                 { "rgba5551_no_depth_stencil",          "RGBA5551 configs with stencil and no depth",   colorBits<5, 5, 5, 1>, noDepth,         hasStencil      },
1071                 { "rgba5551_depth_no_stencil",          "RGBA5551 configs with depth and no stencil",   colorBits<5, 5, 5, 1>, hasDepth,        noStencil       },
1072                 { "rgba5551_depth_stencil",                     "RGBA5551 configs with depth and stencil",              colorBits<5, 5, 5, 1>, hasDepth,        hasStencil      },
1073
1074                 { "rgba8888_no_depth_no_stencil",       "RGBA8888 configs without depth or stencil",    colorBits<8, 8, 8, 8>, noDepth,         noStencil       },
1075                 { "rgba8888_no_depth_stencil",          "RGBA8888 configs with stencil and no depth",   colorBits<8, 8, 8, 8>, noDepth,         hasStencil      },
1076                 { "rgba8888_depth_no_stencil",          "RGBA8888 configs with depth and no stencil",   colorBits<8, 8, 8, 8>, hasDepth,        noStencil       },
1077                 { "rgba8888_depth_stencil",                     "RGBA8888 configs with depth and stencil",              colorBits<8, 8, 8, 8>, hasDepth,        hasStencil      }
1078         };
1079
1080         for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groups); groupNdx++)
1081         {
1082                 eglu::FilterList filter;
1083
1084                 filter << groups[groupNdx].colorFilter
1085                            << groups[groupNdx].depthFilter
1086                            << groups[groupNdx].stencilFilter
1087                            << getRenderableFilter(m_apiBit);
1088
1089                 addChild(new CreateContextExtCase(m_eglTestCtx, m_api, &(m_attribList[0]), filter, groups[groupNdx].name, groups[groupNdx].description));
1090         }
1091         // \todo [mika] Add other group
1092 }
1093
1094 } // anonymous
1095
1096 CreateContextExtTests::CreateContextExtTests (EglTestContext& eglTestCtx)
1097         : TestCaseGroup(eglTestCtx, "create_context_ext", "EGL_KHR_create_context tests.")
1098 {
1099 }
1100
1101 CreateContextExtTests::~CreateContextExtTests (void)
1102 {
1103 }
1104
1105 void CreateContextExtTests::init (void)
1106 {
1107         const size_t    maxAttributeCount = 10;
1108         const struct
1109         {
1110                 const char*     name;
1111                 const char*     description;
1112                 EGLenum         api;
1113                 EGLint          apiBit;
1114                 EGLint          attribList[maxAttributeCount];
1115         } groupList[] =
1116         {
1117 #if 0
1118                 // \todo [mika] Not supported by glw
1119                 // OpenGL ES 1.x
1120                 { "gles_10", "Create OpenGL ES 1.0 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES_BIT,
1121                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE} },
1122                 { "gles_11", "Create OpenGL ES 1.1 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES_BIT,
1123                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1124 #endif
1125                 // OpenGL ES 2.x
1126                 { "gles_20", "Create OpenGL ES 2.0 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES2_BIT,
1127                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 2, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1128                 // OpenGL ES 3.x
1129                 { "gles_30", "Create OpenGL ES 3.0 context", EGL_OPENGL_ES_API, EGL_OPENGL_ES3_BIT_KHR,
1130                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE} },
1131 #if 0
1132                 // \todo [mika] Not supported by glw
1133                 // \note [mika] Should we really test 1.x?
1134                 { "gl_10", "Create OpenGL 1.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1135                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE} },
1136                 { "gl_11", "Create OpenGL 1.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1137                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 1, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1138
1139                 // OpenGL 2.x
1140                 { "gl_20", "Create OpenGL 2.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1141                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 2, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1142                 { "gl_21", "Create OpenGL 2.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1143                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 2, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1144 #endif
1145                 // OpenGL 3.x
1146                 { "gl_30", "Create OpenGL 3.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1147                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1148                 { "robust_gl_30", "Create robust OpenGL 3.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1149                         { 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 } },
1150                 { "gl_31", "Create OpenGL 3.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1151                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1152                 { "robust_gl_31", "Create robust OpenGL 3.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1153                         { 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 } },
1154                 { "gl_32", "Create OpenGL 3.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1155                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_NONE } },
1156                 { "robust_gl_32", "Create robust OpenGL 3.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1157                         { 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 } },
1158                 { "gl_33", "Create OpenGL 3.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1159                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 3, EGL_CONTEXT_MINOR_VERSION_KHR, 3, EGL_NONE } },
1160                 { "robust_gl_33", "Create robust OpenGL 3.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1161                         { 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 } },
1162
1163                 // OpenGL 4.x
1164                 { "gl_40", "Create OpenGL 4.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1165                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 0, EGL_NONE } },
1166                 { "robust_gl_40", "Create robust OpenGL 4.0 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1167                         { 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 } },
1168                 { "gl_41", "Create OpenGL 4.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1169                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 1, EGL_NONE } },
1170                 { "robust_gl_41", "Create robust OpenGL 4.1 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1171                         { 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 } },
1172                 { "gl_42", "Create OpenGL 4.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1173                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 2, EGL_NONE } },
1174                 { "robust_gl_42", "Create robust OpenGL 4.2 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1175                         { 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 } },
1176                 { "gl_43", "Create OpenGL 4.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1177                         { EGL_CONTEXT_MAJOR_VERSION_KHR, 4, EGL_CONTEXT_MINOR_VERSION_KHR, 3, EGL_NONE } },
1178                 { "robust_gl_43", "Create robust OpenGL 4.3 context", EGL_OPENGL_API, EGL_OPENGL_BIT,
1179                         { 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 } },
1180
1181                 // Robust contexts with EGL_EXT_create_context_robustness
1182                 { "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,
1183                         { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_NONE } },
1184                 { "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,
1185                         { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_NONE } },
1186 #if 0
1187         // 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.
1188                 { "robust_gl_ext", "Create robust OpenGL context with EGL_EXT_create_context_robustness.", EGL_OPENGL_API, EGL_OPENGL_BIT,
1189                         { EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE, EGL_NONE } }
1190 #endif
1191         };
1192
1193         for (int groupNdx = 0; groupNdx < DE_LENGTH_OF_ARRAY(groupList); groupNdx++)
1194                 addChild(new CreateContextExtGroup(m_eglTestCtx, groupList[groupNdx].api, groupList[groupNdx].apiBit, groupList[groupNdx].attribList, groupList[groupNdx].name, groupList[groupNdx].description));
1195 }
1196
1197 } // egl
1198 } // deqp