Add new robustness extension tests
authorJohn Richardson <john.richardson@mobica.com>
Wed, 1 Feb 2017 15:00:53 +0000 (15:00 +0000)
committerPyry Haulos <phaulos@google.com>
Tue, 28 Feb 2017 16:45:00 +0000 (08:45 -0800)
New tests for KHR_robustness extension. Attempts to provoke context
reset scenarios and test GL state after a reset has occurred.

New test group:
- dEQP-EGL.functional.robustness.*

New tests:
- create_context.query_robust_access
- create_context.no_reset_notification
- create_context.lose_context_on_reset

- reset_context.shaders.infinite_loop.*   (various shaders)
- reset_context.shaders.out_of_bounds.*   (various resource types)
- reset_context.fixed_function_pipeline.* (index and vertex buffers)

- negative_context.invalid_robust_context_creation
- negative_context.invalid_robust_shared_context_creation

Note: Test groups ending in *_non_robust are for internal use only.

Change-Id: I91d7e3e95ec52f908dbaa1f49c56dcd94d60fd8f

Android.mk
android/cts/master/egl-master.txt
android/cts/master/src/egl-manual-robustness.txt [new file with mode: 0644]
framework/opengl/gluStrUtil.inl
framework/opengl/gluStrUtilPrototypes.inl
modules/egl/CMakeLists.txt
modules/egl/teglRobustnessTests.cpp [new file with mode: 0644]
modules/egl/teglRobustnessTests.hpp [new file with mode: 0644]
modules/egl/teglTestPackage.cpp
scripts/build_android_mustpass.py
scripts/opengl/gen_str_util.py

index 5618aa9..0997500 100644 (file)
@@ -296,6 +296,7 @@ LOCAL_SRC_FILES := \
        modules/egl/teglQuerySurfaceTests.cpp \
        modules/egl/teglRenderCase.cpp \
        modules/egl/teglRenderTests.cpp \
+       modules/egl/teglRobustnessTests.cpp \
        modules/egl/teglResizeTests.cpp \
        modules/egl/teglSimpleConfigCase.cpp \
        modules/egl/teglSurfacelessContextTests.cpp \
index ba0c55a..d3b76c1 100644 (file)
@@ -3570,3 +3570,54 @@ dEQP-EGL.functional.get_frame_timestamps.rgba8888_no_depth_stencil
 dEQP-EGL.functional.get_frame_timestamps.rgba8888_depth_no_stencil
 dEQP-EGL.functional.get_frame_timestamps.rgba8888_depth_stencil
 dEQP-EGL.functional.get_frame_timestamps.other
+dEQP-EGL.functional.robustness.create_context.query_robust_access
+dEQP-EGL.functional.robustness.create_context.no_reset_notification
+dEQP-EGL.functional.robustness.create_context.lose_context_on_reset
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.reset_status.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.reset_status.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.reset_status.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.reset_status.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.sync_status.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.sync_status.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.sync_status.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.sync_status.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.query_status.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.query_status.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.query_status.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.query_status.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.shared_context_status.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.shared_context_status.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.shared_context_status.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.shared_context_status.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.recover_from_reset.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.recover_from_reset.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.recover_from_reset.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.infinite_loop.recover_from_reset.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.uniform_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.uniform_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.uniform_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.uniform_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.shader_storage_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.shader_storage_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.shader_storage_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.shader_storage_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.local_array.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.local_array.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.local_array.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.reads.local_array.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.uniform_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.uniform_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.uniform_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.uniform_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.shader_storage_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.shader_storage_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.shader_storage_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.shader_storage_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.local_array.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.local_array.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.local_array.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds.reset_status.writes.local_array.compute
+dEQP-EGL.functional.robustness.reset_context.fixed_function_pipeline.reset_status.index_buffer_out_of_bounds
+dEQP-EGL.functional.robustness.reset_context.fixed_function_pipeline.reset_status.vertex_buffer_out_of_bounds
+dEQP-EGL.functional.robustness.negative_context.invalid_robust_context_creation
+dEQP-EGL.functional.robustness.negative_context.invalid_robust_shared_context_creation
diff --git a/android/cts/master/src/egl-manual-robustness.txt b/android/cts/master/src/egl-manual-robustness.txt
new file mode 100644 (file)
index 0000000..4d7efe9
--- /dev/null
@@ -0,0 +1,27 @@
+# OOB robustness tests for manual testing purposes
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.uniform_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.uniform_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.uniform_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.uniform_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.shader_storage_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.shader_storage_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.shader_storage_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.shader_storage_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.local_array.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.local_array.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.local_array.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.reads.local_array.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.uniform_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.uniform_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.uniform_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.uniform_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.shader_storage_block.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.shader_storage_block.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.shader_storage_block.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.shader_storage_block.compute
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.local_array.vertex
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.local_array.fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.local_array.vertex_and_fragment
+dEQP-EGL.functional.robustness.reset_context.shaders.out_of_bounds_non_robust.reset_status.writes.local_array.compute
+dEQP-EGL.functional.robustness.reset_context.fixed_function_pipeline_non_robust.reset_status.index_buffer_out_of_bounds
+dEQP-EGL.functional.robustness.reset_context.fixed_function_pipeline_non_robust.reset_status.vertex_buffer_out_of_bounds
index 2557371..f1504a6 100644 (file)
@@ -14,6 +14,7 @@ const char* getErrorName (int value)
                case GL_INVALID_OPERATION:                              return "GL_INVALID_OPERATION";
                case GL_OUT_OF_MEMORY:                                  return "GL_OUT_OF_MEMORY";
                case GL_INVALID_FRAMEBUFFER_OPERATION:  return "GL_INVALID_FRAMEBUFFER_OPERATION";
+               case GL_CONTEXT_LOST:                                   return "GL_CONTEXT_LOST";
                default:                                                                return DE_NULL;
        }
 }
@@ -1787,6 +1788,18 @@ const char* getTextureFormatName (int value)
        }
 }
 
+const char* getGraphicsResetStatusName (int value)
+{
+       switch (value)
+       {
+               case GL_NO_ERROR:                               return "GL_NO_ERROR";
+               case GL_GUILTY_CONTEXT_RESET:   return "GL_GUILTY_CONTEXT_RESET";
+               case GL_INNOCENT_CONTEXT_RESET: return "GL_INNOCENT_CONTEXT_RESET";
+               case GL_UNKNOWN_CONTEXT_RESET:  return "GL_UNKNOWN_CONTEXT_RESET";
+               default:                                                return DE_NULL;
+       }
+}
+
 tcu::Format::Bitfield<16> getBufferMaskStr (int value)
 {
        static const tcu::Format::BitDesc s_desc[] =
index a831bb8..c0505ef 100644 (file)
@@ -74,6 +74,7 @@ const char*                                                   getDebugMessageSeverityName                             (int value);
 const char*                                                    getPipelineParamName                                    (int value);
 const char*                                                    getPatchParamName                                               (int value);
 const char*                                                    getTextureFormatName                                    (int value);
+const char*                                                    getGraphicsResetStatusName                              (int value);
 tcu::Format::Bitfield<16>                      getBufferMaskStr                                                (int value);
 tcu::Format::Bitfield<16>                      getBufferMapFlagsStr                                    (int value);
 tcu::Format::Bitfield<16>                      getMemoryBarrierFlagsStr                                (int value);
@@ -149,4 +150,5 @@ inline tcu::Format::Enum<int, 2>    getDebugMessageSeverityStr                              (int value)             { re
 inline tcu::Format::Enum<int, 2>       getPipelineParamStr                                             (int value)             { return tcu::Format::Enum<int, 2>(getPipelineParamName, value); }
 inline tcu::Format::Enum<int, 2>       getPatchParamStr                                                (int value)             { return tcu::Format::Enum<int, 2>(getPatchParamName, value); }
 inline tcu::Format::Enum<int, 2>       getTextureFormatStr                                             (int value)             { return tcu::Format::Enum<int, 2>(getTextureFormatName, value); }
+inline tcu::Format::Enum<int, 2>       getGraphicsResetStatusStr                               (int value)             { return tcu::Format::Enum<int, 2>(getGraphicsResetStatusName, value); }
 inline tcu::Format::Enum<int, 1>       getBooleanStr                                                   (deUint8 value) { return tcu::Format::Enum<int, 1>(getBooleanName, (int)value); }
index 519f15c..6772b48 100644 (file)
@@ -99,6 +99,8 @@ set(DEQP_EGL_SRCS
        teglMultiContextTests.cpp
        teglThreadCleanUpTests.hpp
        teglThreadCleanUpTests.cpp
+       teglRobustnessTests.hpp
+       teglRobustnessTests.cpp
        )
 
 set(DEQP_EGL_LIBS
diff --git a/modules/egl/teglRobustnessTests.cpp b/modules/egl/teglRobustnessTests.cpp
new file mode 100644 (file)
index 0000000..5ce3848
--- /dev/null
@@ -0,0 +1,2303 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program EGL Module
+ * ---------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Robustness tests for KHR_robustness.
+ *//*--------------------------------------------------------------------*/
+
+#include "teglRobustnessTests.hpp"
+
+#include "tcuTestLog.hpp"
+#include "tcuStringTemplate.hpp"
+
+#include "egluConfigFilter.hpp"
+#include "egluStrUtil.hpp"
+#include "egluUtil.hpp"
+#include "eglwLibrary.hpp"
+
+#include "gluStrUtil.hpp"
+#include "gluShaderProgram.hpp"
+#include "gluDrawUtil.hpp"
+
+#include "glwFunctions.hpp"
+#include "glwEnums.hpp"
+
+#include "deSTLUtil.hpp"
+#include "deThread.hpp"
+#include "deSharedPtr.hpp"
+
+#include <set>
+
+using std::string;
+using std::vector;
+using std::set;
+using tcu::TestLog;
+
+using namespace eglw;
+
+DE_STATIC_ASSERT(GL_RESET_NOTIFICATION_STRATEGY        == 0x8256);
+DE_STATIC_ASSERT(GL_LOSE_CONTEXT_ON_RESET              == 0x8252);
+DE_STATIC_ASSERT(GL_NO_RESET_NOTIFICATION              == 0x8261);
+
+namespace deqp
+{
+namespace egl
+{
+namespace
+{
+
+enum ContextResetType
+{
+       CONTEXTRESETTYPE_INFINITE_LOOP,
+       CONTEXTRESETTYPE_SHADER_OOB,
+       CONTEXTRESETTYPE_FIXED_FUNC_OOB,
+};
+
+enum ShaderType
+{
+       SHADERTYPE_VERT,
+       SHADERTYPE_FRAG,
+       SHADERTYPE_COMPUTE,
+       SHADERTYPE_VERT_AND_FRAG,
+};
+
+enum ReadWriteType
+{
+       READWRITETYPE_READ,
+       READWRITETYPE_WRITE,
+};
+
+enum ResourceType
+{
+       RESOURCETYPE_UBO,
+       RESOURCETYPE_SSBO,
+       RESOURCETYPE_LOCAL_ARRAY,
+};
+
+enum FixedFunctionType
+{
+       FIXEDFUNCTIONTYPE_INDICES,
+       FIXEDFUNCTIONTYPE_VERTICES,
+};
+
+enum RobustAccessType
+{
+       ROBUSTACCESS_TRUE,
+       ROBUSTACCESS_FALSE,
+};
+
+void requireEGLExtension (const Library& egl, EGLDisplay eglDisplay, const char* requiredExtension)
+{
+       if (!eglu::hasExtension(egl, eglDisplay, requiredExtension))
+               TCU_THROW(NotSupportedError, (string(requiredExtension) + " not supported").c_str());
+}
+
+bool isWindow (const eglu::CandidateConfig& c)
+{
+       return (c.surfaceType() & EGL_WINDOW_BIT) == EGL_WINDOW_BIT;
+}
+
+template <deUint32 Type>
+bool renderable (const eglu::CandidateConfig& c)
+{
+       return (c.renderableType() & Type) == Type;
+}
+
+eglu::ConfigFilter getRenderableFilter (deUint32 bits)
+{
+       switch (bits)
+       {
+               case EGL_OPENGL_ES2_BIT:        return renderable<EGL_OPENGL_ES2_BIT>;
+               case EGL_OPENGL_ES3_BIT:        return renderable<EGL_OPENGL_ES3_BIT>;
+               case EGL_OPENGL_BIT:            return renderable<EGL_OPENGL_BIT>;
+               default:
+                       DE_FATAL("Unknown EGL bitfied value");
+                       return renderable<0>;
+       }
+}
+
+const char* eglResetNotificationStrategyToString (EGLint strategy)
+{
+       switch (strategy)
+       {
+               case EGL_NO_RESET_NOTIFICATION_KHR:             return "EGL_NO_RESET_NOTIFICATION_KHR";
+               case EGL_LOSE_CONTEXT_ON_RESET_KHR:             return "EGL_LOSE_CONTEXT_ON_RESET_KHR";
+               default:
+                       return "<Unknown>";
+       }
+}
+
+void logAttribList (const EglTestContext& eglTestCtx, const EGLint* attribList)
+{
+       const EGLint*           iter = &(attribList[0]);
+       std::ostringstream      attribListString;
+
+       while ((*iter) != EGL_NONE)
+       {
+               switch (*iter)
+               {
+               //      case EGL_CONTEXT_CLIENT_VERSION:
+                       case EGL_CONTEXT_MAJOR_VERSION_KHR:
+                               iter++;
+                               attribListString << "EGL_CONTEXT_CLIENT_VERSION, " << (*iter) << ", ";
+                               iter++;
+                               break;
+
+                       case EGL_CONTEXT_MINOR_VERSION_KHR:
+                               iter++;
+                               attribListString << "EGL_CONTEXT_MINOR_VERSION_KHR, " << (*iter) << ", ";
+                               iter++;
+                               break;
+
+                       case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
+                               iter++;
+                               attribListString << "EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, "
+                                                                << eglResetNotificationStrategyToString(*iter) << ", ";
+                               iter++;
+                               break;
+
+                       case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
+                               iter++;
+                               attribListString << "EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, ";
+
+                               if (*iter == EGL_FALSE || *iter == EGL_TRUE)
+                                       attribListString << (*iter ? "EGL_TRUE" : "EGL_FALSE") << ", ";
+                               else
+                                       attribListString << (*iter) << ", ";
+                               iter++;
+                               break;
+
+                       default:
+                               DE_FATAL("Unsupported attribute");
+               }
+       }
+
+       attribListString << "EGL_NONE";
+       eglTestCtx.getTestContext().getLog() << TestLog::Message
+                                                                                << "EGL attrib list: { " << attribListString.str() << " }\n\n"
+                                                                                << TestLog::EndMessage;
+}
+
+void parseAttributeValues (const EGLint* attribList, EGLint& majorVersion, EGLint& minorVersion, EGLint& robustAccessExt)
+{
+       const EGLint* iter = attribList;
+
+       while ((*iter) != EGL_NONE)
+       {
+               switch (*iter)
+               {
+                       case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
+                               iter++;
+                               robustAccessExt = *iter;
+                               iter++;
+                               break;
+
+                       case EGL_CONTEXT_MAJOR_VERSION_KHR:
+                               iter++;
+                               majorVersion = (*iter);
+                               iter++;
+                               break;
+
+                       case EGL_CONTEXT_MINOR_VERSION_KHR:
+                               iter++;
+                               minorVersion = (*iter);
+                               iter++;
+                               break;
+
+                       case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
+                               iter++;
+                               iter++;
+                               break;
+
+                       default:
+                               DE_FATAL("Unsupported EGL attribute");
+               }
+       }
+}
+
+glu::ContextType attribListToContextType (const EGLint* attribList)
+{
+       EGLint                          majorVersion    = 1;
+       EGLint                          minorVersion    = 0;
+       EGLint                          robustAccessExt = 0;
+
+       glu::ContextFlags       flags                   = glu::ContextFlags(0);
+       const glu::Profile      profile                 = glu::PROFILE_ES;
+       parseAttributeValues(attribList, majorVersion, minorVersion, robustAccessExt);
+
+       return glu::ContextType(majorVersion, minorVersion, profile, flags);
+}
+
+void checkRequiredGLRobustnessExtension (const EGLint* attribList, const glw::Functions& gl)
+{
+       EGLint                          majorVersion                    = 1;
+       EGLint                          minorVersion                    = 0;
+       EGLint                          robustAccessExt                 = 0;
+       parseAttributeValues(attribList, majorVersion, minorVersion, robustAccessExt);
+
+       glu::ApiType            apiType                                 = glu::ApiType::es(majorVersion, minorVersion);
+
+       if (!glu::hasExtension(gl, apiType, "GL_KHR_robustness") && !glu::hasExtension(gl, apiType, "GL_EXT_robustness"))
+               TCU_THROW(NotSupportedError, (string("GL_KHR_robustness and GL_EXT_robustness") + " not supported").c_str());
+}
+
+class RobustnessTestCase: public TestCase
+{
+public:
+       class Params
+       {
+       public:
+                                                       Params                                  (void) {};
+
+                                                       Params                                  (const string&                          name,
+                                                                                                        const string&                          description,
+                                                                                                        const RobustAccessType&        robustAccessType,
+                                                                                                        const ContextResetType&        contextResetType,
+                                                                                                        const FixedFunctionType&       fixedFunctionType);
+
+                                                       Params                                  (const string&                          name,
+                                                                                                        const string&                          description,
+                                                                                                        const ContextResetType&        contextResetType,
+                                                                                                        const ShaderType&                      shaderType);
+
+                                                       Params                                  (const string&                          name,
+                                                                                                        const string&                          description,
+                                                                                                        const RobustAccessType&        robustAccessType,
+                                                                                                        const ContextResetType&        contextResetType,
+                                                                                                        const ShaderType&                      shaderType,
+                                                                                                        const ResourceType&            resourceType,
+                                                                                                        const ReadWriteType&           readWriteType);
+
+               const string&                           getName                                 (void) const { return m_name;                           }
+               const string&                           getDescription                  (void) const { return m_description;            }
+               const ContextResetType&         getContextResetType             (void) const { return m_contextResetType;       }
+               const ShaderType&                       getShaderType                   (void) const { return m_shaderType;                     }
+               const ResourceType&                     getResourceType                 (void) const { return m_resourceType;           }
+               const ReadWriteType&            getReadWriteType                (void) const { return m_readWriteType;          }
+               const FixedFunctionType&        getFixedFunctionType    (void) const { return m_fixedFunctionType;      }
+               const RobustAccessType&         getRobustAccessType             (void) const { return m_robustAccessType;       }
+
+       private:
+               string                          m_name;
+               string                          m_description;
+               RobustAccessType        m_robustAccessType;
+               ContextResetType        m_contextResetType;
+               ShaderType                      m_shaderType;
+               ResourceType            m_resourceType;
+               ReadWriteType           m_readWriteType;
+               FixedFunctionType       m_fixedFunctionType;
+       };
+
+                       RobustnessTestCase                      (EglTestContext& eglTestCtx, const char* name, const char* description);
+                       RobustnessTestCase                      (EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
+                       ~RobustnessTestCase                     (void);
+
+       void    checkRequiredEGLExtensions      (const EGLint* attribList);
+
+protected:
+       Params                                  m_params;
+       EGLDisplay                              m_eglDisplay;
+       EGLConfig                               m_eglConfig;
+       EGLSurface                              m_eglSurface;
+
+private:
+       void                                    init                                    (void);
+       void                                    deinit                                  (void);
+       void                                    initEGLSurface                  (void);
+       EGLConfig                               getEGLConfig                    (void);
+
+       eglu::NativeWindow*             m_window;
+       glu::ContextType                m_glContextType;
+
+};
+
+RobustnessTestCase::Params::Params (const string&                              name,
+                                                                       const string&                           description,
+                                                                       const RobustAccessType&         robustAccessType,
+                                                                       const ContextResetType&         contextResetType,
+                                                                       const FixedFunctionType&        fixedFunctionType)
+       : m_name                                (name)
+       , m_description                 (description)
+       , m_robustAccessType    (robustAccessType)
+       , m_contextResetType    (contextResetType)
+       , m_fixedFunctionType   (fixedFunctionType)
+{
+}
+
+RobustnessTestCase::Params::Params (const string&                              name,
+                                                                       const string&                           description,
+                                                                       const ContextResetType&         contextResetType,
+                                                                       const ShaderType&                       shaderType)
+       : m_name                                (name)
+       , m_description                 (description)
+       , m_contextResetType    (contextResetType)
+       , m_shaderType                  (shaderType)
+{
+}
+
+RobustnessTestCase::Params::Params (const string&                              name,
+                                                                       const string&                           description,
+                                                                       const RobustAccessType&         robustAccessType,
+                                                                       const ContextResetType&         contextResetType,
+                                                                       const ShaderType&                       shaderType,
+                                                                       const ResourceType&                     resourceType,
+                                                                       const ReadWriteType&            readWriteType)
+       : m_name                                (name)
+       , m_description                 (description)
+       , m_robustAccessType    (robustAccessType)
+       , m_contextResetType    (contextResetType)
+       , m_shaderType                  (shaderType)
+       , m_resourceType                (resourceType)
+       , m_readWriteType               (readWriteType)
+{
+}
+
+RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description)
+       : TestCase                      (eglTestCtx, name, description)
+       , m_eglDisplay          (EGL_NO_DISPLAY)
+       , m_eglConfig           (0)
+       , m_eglSurface          (EGL_NO_SURFACE)
+       , m_window                      (DE_NULL)
+{
+}
+
+RobustnessTestCase::RobustnessTestCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
+       : TestCase                      (eglTestCtx, name, description)
+       , m_params                      (params)
+       , m_eglDisplay          (EGL_NO_DISPLAY)
+       , m_eglConfig           (0)
+       , m_eglSurface          (EGL_NO_SURFACE)
+       , m_window                      (DE_NULL)
+{
+}
+
+RobustnessTestCase::~RobustnessTestCase (void)
+{
+       deinit();
+}
+
+void RobustnessTestCase::init (void)
+{
+       m_eglDisplay    = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
+       m_eglConfig             = getEGLConfig();
+
+       initEGLSurface();
+}
+
+void RobustnessTestCase::deinit (void)
+{
+       const Library& egl = m_eglTestCtx.getLibrary();
+
+       if (m_eglSurface != EGL_NO_SURFACE)
+       {
+               egl.destroySurface(m_eglDisplay, m_eglSurface);
+               m_eglSurface = EGL_NO_SURFACE;
+       }
+       if (m_eglDisplay != EGL_NO_DISPLAY)
+       {
+               egl.terminate(m_eglDisplay);
+               m_eglDisplay = EGL_NO_DISPLAY;
+       }
+
+       delete m_window;
+       m_window = DE_NULL;
+}
+
+EGLConfig RobustnessTestCase::getEGLConfig (void)
+{
+       eglu::FilterList filters;
+       filters << isWindow << getRenderableFilter(EGL_OPENGL_ES3_BIT);
+       return eglu::chooseSingleConfig(m_eglTestCtx.getLibrary(), m_eglDisplay, filters);
+}
+
+void RobustnessTestCase::initEGLSurface (void)
+{
+       EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), bindAPI(EGL_OPENGL_ES_API));
+
+       const eglu::NativeWindowFactory& factory =      eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
+
+       const eglu::WindowParams        windowParams    =       eglu::WindowParams(256, 256, eglu::parseWindowVisibility(m_testCtx.getCommandLine()));
+       m_window                                                                        =       factory.createWindow(&m_eglTestCtx.getNativeDisplay(), m_eglDisplay, m_eglConfig, DE_NULL, windowParams);
+       m_eglSurface                                                            =       eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *m_window, m_eglDisplay, m_eglConfig, DE_NULL);
+}
+
+void RobustnessTestCase::checkRequiredEGLExtensions (const EGLint* attribList)
+{
+       set<string>             requiredExtensions;
+       vector<string>  extensions                      = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_eglDisplay);
+
+       {
+               const EGLint* iter = attribList;
+
+               while ((*iter) != EGL_NONE)
+               {
+                       switch (*iter)
+                       {
+                               case EGL_CONTEXT_MAJOR_VERSION_KHR: iter++;
+                                       iter++;
+                                       break;
+
+                               case EGL_CONTEXT_MINOR_VERSION_KHR:
+                                       iter++;
+                                       requiredExtensions.insert("EGL_KHR_create_context");
+                                       iter++;
+                                       break;
+
+                               case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
+                               case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
+                                       iter++;
+                                       requiredExtensions.insert("EGL_EXT_create_context_robustness");
+                                       iter++;
+                                       break;
+
+                               default:
+                                       DE_ASSERT(DE_FALSE);
+                       }
+               }
+       }
+
+       for (std::set<string>::const_iterator reqExt = requiredExtensions.begin(); reqExt != requiredExtensions.end(); ++reqExt)
+       {
+               if (!de::contains(extensions.begin(), extensions.end(), *reqExt))
+               {
+                       const char* const extension = reqExt->c_str();
+                       requireEGLExtension(m_eglTestCtx.getLibrary(), m_eglDisplay, extension);
+               }
+       }
+}
+
+
+class RenderingContext
+{
+public:
+                                                       RenderingContext                                        (const EglTestContext&  eglTestCtx,
+                                                                                                                                const EGLint*                  attribList,
+                                                                                                                                const EGLConfig&               config,
+                                                                                                                                const EGLDisplay&              display,
+                                                                                                                                const EGLContext&              sharedContext);
+                                                       ~RenderingContext                                       (void);
+
+       void                                    initGLFunctions                                         (glw::Functions* gl);
+       void                                    makeCurrent                                                     (const EGLSurface& surface);
+       EGLContext                              getContext                                                      (void);
+
+private:
+       const EglTestContext&   m_eglTestCtx;
+       const EGLint*                   m_attribList;
+       const EGLConfig&                m_config;
+       const EGLDisplay&               m_display;
+       const Library&                  m_egl;
+
+       EGLContext                              m_context;
+
+       void                                    createContext                                           (const EGLConfig& sharedConfig);
+       void                                    destroyContext                                          (void);
+
+                                                       RenderingContext                                        (const RenderingContext&);
+       RenderingContext&               operator=                                                       (const RenderingContext&);
+};
+
+RenderingContext::RenderingContext (const EglTestContext&       eglTestCtx,
+                                                                       const EGLint*                    attribList,
+                                                                       const EGLConfig&                 config,
+                                                                       const EGLDisplay&                display,
+                                                                       const EGLContext&                sharedContext)
+       : m_eglTestCtx          (eglTestCtx)
+       , m_attribList          (attribList)
+       , m_config                      (config)
+       , m_display                     (display)
+       , m_egl                         (eglTestCtx.getLibrary())
+       , m_context                     (EGL_NO_CONTEXT)
+{
+       logAttribList(eglTestCtx, m_attribList);
+       createContext(sharedContext);
+}
+
+RenderingContext::~RenderingContext (void)
+{
+       destroyContext();
+}
+
+void RenderingContext::createContext (const EGLConfig& sharedContext)
+{
+       m_context = m_egl.createContext(m_display, m_config, sharedContext, m_attribList);
+       EGLU_CHECK_MSG(m_egl, "eglCreateContext()");
+}
+
+void RenderingContext::destroyContext (void)
+{
+       EGLU_CHECK_CALL(m_eglTestCtx.getLibrary(), makeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+
+       if (m_context != EGL_NO_CONTEXT)
+               m_egl.destroyContext(m_display, m_context);
+}
+
+void RenderingContext::makeCurrent (const EGLSurface& surface)
+{
+       EGLU_CHECK_CALL(m_egl, makeCurrent(m_display, surface, surface, m_context));
+}
+
+void RenderingContext::initGLFunctions (glw::Functions *gl)
+{
+       const char* extensions[] = { "GL_KHR_robustness" };
+       m_eglTestCtx.initGLFunctions(gl, attribListToContextType(m_attribList).getAPI(), DE_LENGTH_OF_ARRAY(extensions), &extensions[0]);
+}
+
+EGLContext RenderingContext::getContext (void)
+{
+       return m_context;
+}
+
+class ContextReset
+{
+public:
+                                               ContextReset                            (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
+                                               ContextReset                            (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType);
+                                               ContextReset                            (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);
+
+       virtual                         ~ContextReset                           (void) {};
+
+       virtual void            setup                                           (void) = 0;
+       virtual void            draw                                            (void) = 0;
+       virtual void            teardown                                        (void) = 0;
+
+       void                            finish                                          (void);
+       void                            createSyncObject                        (void);
+       glw::GLint                      getSyncStatus                           (void);
+
+       void                            beginQuery                                      (void);
+       void                            endQuery                                        (void);
+       glw::GLint                      getError                                        (void);
+       glw::GLint                      getGraphicsResetStatus          (void);
+       glw::GLuint                     getQueryAvailability            (void);
+
+       glw::GLsync                     getSyncObject                           (void) const { return m_sync; }
+       glw::GLuint                     getQueryID                                      (void) const { return m_queryID; }
+
+       glw::Functions&         m_gl;
+       tcu::TestLog&           m_log;
+       ShaderType                      m_shaderType;
+       ResourceType            m_resourceType;
+       ReadWriteType           m_readWriteType;
+       FixedFunctionType       m_fixedFunctionType;
+
+private:
+                                               ContextReset                            (const ContextReset&);
+       ContextReset&           operator=                                       (const ContextReset&);
+
+       glw::GLuint                     m_queryID;
+       glw::GLsync                     m_sync;
+};
+
+ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
+       : m_gl                                  (gl)
+       , m_log                                 (log)
+       , m_fixedFunctionType   (fixedFunctionType)
+{
+}
+
+ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
+       : m_gl                          (gl)
+       , m_log                         (log)
+       , m_shaderType          (shaderType)
+       , m_resourceType        (resourceType)
+       , m_readWriteType       (readWriteType)
+{
+}
+
+ContextReset::ContextReset (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType)
+       : m_gl                  (gl)
+       , m_log                 (log)
+       , m_shaderType  (shaderType)
+{
+}
+
+void ContextReset::finish (void)
+{
+       GLU_CHECK_GLW_CALL(m_gl, finish());
+}
+
+void ContextReset::createSyncObject (void)
+{
+       m_sync = m_gl.fenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+       GLU_EXPECT_NO_ERROR(m_gl.getError(), "glFenceSync()");
+}
+
+glw::GLint ContextReset::getError (void)
+{
+       glw::GLint error;
+       error = m_gl.getError();
+
+       return error;
+}
+
+glw::GLint ContextReset::getGraphicsResetStatus (void)
+{
+       glw::GLint resetStatus;
+       resetStatus = m_gl.getGraphicsResetStatus();
+
+       return resetStatus;
+}
+
+glw::GLint ContextReset::getSyncStatus (void)
+{
+       glw::GLint syncStatus;
+       m_gl.getSynciv(m_sync, GL_SYNC_STATUS, sizeof(glw::GLint), NULL, &syncStatus);
+
+       return syncStatus;
+}
+
+void ContextReset::beginQuery (void)
+{
+       GLU_CHECK_GLW_CALL(m_gl, genQueries(1, &m_queryID));
+       GLU_CHECK_GLW_CALL(m_gl, beginQuery(GL_ANY_SAMPLES_PASSED, m_queryID));
+}
+
+void ContextReset::endQuery (void)
+{
+       GLU_CHECK_GLW_CALL(m_gl, endQuery(GL_ANY_SAMPLES_PASSED));
+}
+
+glw::GLuint ContextReset::getQueryAvailability (void)
+{
+       glw::GLuint queryReady = GL_FALSE;
+       m_gl.getQueryObjectuiv(m_queryID, GL_QUERY_RESULT_AVAILABLE, &queryReady);
+
+       return queryReady;
+}
+
+class InfiniteLoop : public ContextReset
+{
+public:
+                                               InfiniteLoop                    (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType);
+                                               ~InfiniteLoop                   (void) {}
+
+       virtual void            setup                                   (void);
+       virtual void            draw                                    (void);
+       virtual void            teardown                                (void);
+
+private:
+       glu::ProgramSources genComputeSource            (void);
+       glu::ProgramSources genNonComputeSource         (void);
+       glu::ProgramSources     genSources                              (void);
+
+       glw::GLint                      m_coordLocation;
+};
+
+InfiniteLoop::InfiniteLoop (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType)
+       : ContextReset(gl, log, shaderType)
+{
+}
+
+glu::ProgramSources InfiniteLoop::genSources(void)
+{
+       if (m_shaderType == SHADERTYPE_COMPUTE)
+               return genComputeSource();
+       else
+               return genNonComputeSource();
+}
+
+glu::ProgramSources InfiniteLoop::genComputeSource(void)
+{
+       const char* const computeSource =
+               "#version 310 es\n"
+               "layout(local_size_x = 1, local_size_y = 1) in;\n"
+               "uniform highp int u_iterCount;\n"
+               "writeonly buffer Output { highp int b_output_int; };\n"
+               "void main ()\n"
+               "{\n"
+               "       for (highp int i = 0; i < u_iterCount || u_iterCount < 0; ++i)\n"
+               "               b_output_int = u_iterCount;\n"
+               "}\n";
+
+       return glu::ProgramSources() << glu::ComputeSource(computeSource);
+}
+
+glu::ProgramSources InfiniteLoop::genNonComputeSource (void)
+{
+       const bool isVertCase                   = m_shaderType == SHADERTYPE_VERT;
+       const bool isFragCase                   = m_shaderType == SHADERTYPE_FRAG;
+       const bool isVertAndFragment    = m_shaderType == SHADERTYPE_VERT_AND_FRAG;
+
+       std::ostringstream vert, frag;
+
+       vert << "#version 300 es\n"
+                << "in highp vec2 a_position;\n";
+
+       frag << "#version 300 es\n";
+
+       vert << "uniform highp int u_iterCount;\n";
+       if (isFragCase || isVertAndFragment)
+       {
+               vert << "flat out highp int v_iterCount;\n";
+               frag << "flat in highp int v_iterCount;\n";
+       }
+
+       if (isVertCase || isVertAndFragment)
+       {
+               vert << "out mediump vec4 v_color;\n";
+               frag << "in mediump vec4 v_color;\n";
+       }
+
+       frag << "out mediump vec4 o_color;\n";
+
+       vert << "\nvoid main (void)\n{\n"
+                << "   gl_Position = vec4(a_position, 0.0, 1.0);\n"
+                << "   gl_PointSize = 1.0;\n";
+
+       if (isFragCase || isVertAndFragment)
+               vert << "       v_iterCount = u_iterCount;\n";
+
+       frag << "\nvoid main (void)\n{\n";
+
+       const std::string       iterCount       = (isVertCase ? "u_iterCount" : "v_iterCount");
+       const std::string       loopHeader      = "     for (highp int i = 0; i < " + iterCount + " || " + iterCount + " < 0; ++i)\n";
+       const char* const       body            = "color = cos(sin(color*1.25)*0.8);";
+
+       if (isVertAndFragment)
+       {
+               vert << "       mediump vec4 color = " << "a_position.xyxy" << ";\n";
+               vert << loopHeader << "         " << body << "\n";
+
+               frag << "       mediump vec4 color = " << "gl_FragCoord" << ";\n";
+               frag << loopHeader << "         " << body << "\n";
+       }
+       else
+       {
+               std::ostringstream&     op                      = isVertCase ? vert : frag;
+               op << " mediump vec4 color = " << (isVertCase ? "a_position.xyxy" : "gl_FragCoord") << ";\n";
+               op << loopHeader << "           " << body << "\n";
+       }
+
+       if (isVertCase || isVertAndFragment)
+       {
+               vert << "       v_color = color;\n";
+               frag << "       o_color = v_color;\n";
+       }
+       else
+               frag << "       o_color = color;\n";
+
+       vert << "}\n";
+       frag << "}\n";
+
+       return glu::ProgramSources() << glu::VertexSource(vert.str()) << glu::FragmentSource(frag.str());
+}
+
+void InfiniteLoop::setup (void)
+{
+       glu::ShaderProgram program (m_gl, genSources());
+       m_log << program;
+
+       if (!program.isOk())
+               TCU_FAIL("Failed to compile shader program");
+
+       GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
+
+       if (m_shaderType == SHADERTYPE_COMPUTE)
+       {
+               // Output buffer setup
+               glw::GLuint outputBuffer = 0;
+               GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &outputBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, outputBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), DE_NULL, GL_DYNAMIC_DRAW));
+               GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, 0));
+       }
+       else
+       {
+               const glw::GLfloat coords[] =
+               {
+                       -1.0f, -1.0f,
+                       +1.0f, -1.0f,
+                       +1.0f, +1.0f,
+                       -1.0f, +1.0f
+               };
+
+               m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
+               GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
+               TCU_CHECK(m_coordLocation != (glw::GLint)-1);
+
+               // Load the vertex data
+               GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
+               GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
+       }
+
+       glw::GLint iterCountLocation = m_gl.getUniformLocation(program.getProgram(), "u_iterCount");
+       GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
+       TCU_CHECK(iterCountLocation != (glw::GLint)-1);
+
+       // Set the iteration count (infinite)
+       glw::GLint iterCount = -1;
+       GLU_CHECK_GLW_CALL(m_gl, uniform1i(iterCountLocation, iterCount));
+}
+
+void InfiniteLoop::draw (void)
+{
+       if (m_shaderType == SHADERTYPE_COMPUTE)
+               m_gl.dispatchCompute(1, 1, 1);
+       else
+       {
+               const glw::GLushort indices[] = { 0, 1, 2, 2, 3, 0 };
+               m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
+       }
+}
+
+void InfiniteLoop::teardown (void)
+{
+       if (m_shaderType != SHADERTYPE_COMPUTE)
+               GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
+
+       GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
+}
+
+class FixedFunctionOOB : public ContextReset
+{
+public:
+                                                       FixedFunctionOOB                        (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType);
+                                                       ~FixedFunctionOOB                       (void) {}
+
+       struct TestConfig
+       {
+               int textureWidth;
+               int textureHeight;
+       };
+
+       virtual void                    setup                                           (void);
+       virtual void                    draw                                            (void);
+       virtual void                    teardown                                        (void);
+
+private:
+       glu::ProgramSources             genSources                                      (void);
+       glw::GLint                              m_coordLocation;
+};
+
+FixedFunctionOOB::FixedFunctionOOB (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
+       : ContextReset(gl, log, fixedFunctionType)
+{
+}
+
+glu::ProgramSources FixedFunctionOOB::genSources (void)
+{
+       const char* const vert =
+               "#version 310 es\n"
+               "in highp vec4 a_position;\n"
+               "void main (void)\n"
+               "{\n"
+               "       gl_Position = a_position;\n"
+               "}\n";
+
+       const char* const frag =
+               "#version 310 es\n"
+               "layout(location = 0) out highp vec4 fragColor;\n"
+               "void main (void)\n"
+               "{\n"
+               "       fragColor = vec4(1.0f);\n"
+               "}\n";
+
+       return glu::ProgramSources() << glu::VertexSource(vert) << glu::FragmentSource(frag);
+}
+
+void FixedFunctionOOB::setup (void)
+{
+       glu::ShaderProgram program(m_gl, genSources());
+
+       m_log << program;
+
+       if (!program.isOk())
+               TCU_FAIL("Failed to compile shader program");
+
+       GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
+
+       const glw::GLfloat coords[] =
+       {
+               -1.0f, -1.0f,
+                1.0f, -1.0f,
+                1.0f,  1.0f,
+               -1.0f,  1.0f
+       };
+
+       m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
+       GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
+       TCU_CHECK(m_coordLocation != (glw::GLint)-1);
+
+       GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
+       GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
+}
+
+void FixedFunctionOOB::draw (void)
+{
+       const glw::GLint bad_indices[] = {0, 10, 100, 1000, 10000, 100000};
+
+       if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_INDICES)
+               m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, bad_indices);
+       else if (m_fixedFunctionType == FIXEDFUNCTIONTYPE_VERTICES)
+               m_gl.drawArrays(GL_TRIANGLES, 0, 1000);
+       else
+               DE_FATAL("Unknown fixed function type");
+}
+
+void FixedFunctionOOB::teardown (void)
+{
+       GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
+       GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
+}
+
+class ShadersOOB : public ContextReset
+{
+public:
+                                               ShadersOOB                                      (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType);
+                                               ~ShadersOOB                                     (void) {}
+
+       virtual void            setup                                           (void);
+       virtual void            draw                                            (void);
+       virtual void            teardown                                        (void);
+
+private:
+       static const int        s_numBindings                           = 3;
+
+       glw::GLint                      m_coordLocation;
+
+       bool                            m_isUBO;
+       bool                            m_isRead;
+       bool                            m_isLocalArray;
+
+       std::string                     genVertexShader                         (const std::string& shaderDecl, const std::string& shaderBody);
+       std::string                     genFragmentShader                       (const std::string& shaderDecl, const std::string& shaderBody);
+       std::string                     genComputeShader                        (const std::string& shaderDecl, const std::string& shaderBody);
+
+       glu::ProgramSources genNonComputeSource                 (void);
+       glu::ProgramSources genComputeSource                    (void);
+       glu::ProgramSources genSources                                  (void);
+
+};
+
+ShadersOOB::ShadersOOB (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType, ResourceType resourceType, ReadWriteType readWriteType)
+       : ContextReset(gl, log, shaderType, resourceType, readWriteType)
+{
+       m_isUBO                 = (m_resourceType == RESOURCETYPE_UBO);
+       m_isLocalArray  = (m_resourceType == RESOURCETYPE_LOCAL_ARRAY);
+       m_isRead                = (m_readWriteType == READWRITETYPE_READ);
+}
+
+std::string ShadersOOB::genVertexShader (const std::string& shaderDecl, const std::string& shaderBody)
+{
+       static const char* const s_simpleVertexShaderSource     =
+               "#version 310 es\n"
+               "in highp vec4 a_position;\n"
+               "void main (void)\n"
+               "{\n"
+               "       gl_Position = a_position;\n"
+               "}\n";
+
+       switch (m_shaderType)
+       {
+               case SHADERTYPE_VERT:
+               case SHADERTYPE_VERT_AND_FRAG:
+               {
+                       std::ostringstream vertexShaderSource;
+                       vertexShaderSource      <<      "#version 310 es\n"
+                                                               <<      "in highp vec4 a_position;\n"
+                                                               <<      "out highp vec4 v_color;\n"
+                                                               <<      shaderDecl << "\n"
+                                                               <<      "void main (void)\n"
+                                                               <<      "{\n"
+                                                               <<      "       highp vec4 color;\n"
+                                                               <<      shaderBody << "\n"
+                                                               <<      "       v_color = color;\n"
+                                                               <<      "       gl_Position = a_position;\n"
+                                                               <<      "}\n";
+
+                       return vertexShaderSource.str();
+               }
+
+               case SHADERTYPE_FRAG:
+                       return s_simpleVertexShaderSource;
+
+               default:
+                       DE_FATAL("Unknown shader type");
+                       return "";
+       }
+}
+
+std::string ShadersOOB::genFragmentShader (const std::string& shaderDecl, const std::string& shaderBody)
+{
+       static const char* const s_simpleFragmentShaderSource =
+               "#version 310 es\n"
+               "in highp vec4 v_color;\n"
+               "layout(location = 0) out highp vec4 fragColor;\n"
+               "void main (void)\n"
+               "{\n"
+               "       fragColor = v_color;\n"
+               "}\n";
+
+       switch (m_shaderType)
+       {
+               case SHADERTYPE_VERT:
+                       return s_simpleFragmentShaderSource;
+
+               case SHADERTYPE_FRAG:
+               {
+                       std::ostringstream fragmentShaderSource;
+                       fragmentShaderSource    <<      "#version 310 es\n"
+                                                                       <<      "layout(location = 0) out highp vec4 fragColor;\n"
+                                                                       <<      shaderDecl << "\n"
+                                                                       <<      "void main (void)\n"
+                                                                       <<      "{\n"
+                                                                       <<      "       highp vec4 color = vec4(0.0f);\n"
+                                                                       <<      shaderBody << "\n"
+                                                                       <<      "       fragColor = color;\n"
+                                                                       <<      "}\n";
+
+                       return fragmentShaderSource.str();
+               }
+               case SHADERTYPE_VERT_AND_FRAG:
+               {
+                       std::ostringstream fragmentShaderSource;
+                       fragmentShaderSource    <<      "#version 310 es\n"
+                                                                       <<      "in highp vec4 v_color;\n"
+                                                                       <<      "layout(location = 0) out highp vec4 fragColor;\n"
+                                                                       <<      shaderDecl << "\n"
+                                                                       <<      "void main (void)\n"
+                                                                       <<      "{\n"
+                                                                       <<      "       highp vec4 color = vec4(0.0f);\n"
+                                                                       <<      shaderBody << "\n"
+                                                                       <<      "       fragColor = color;\n"
+                                                                       <<      "}\n";
+
+                       return fragmentShaderSource.str();
+               }
+
+               default:
+                       DE_FATAL("Unknown shader type");
+                       return "";
+       }
+}
+
+std::string ShadersOOB::genComputeShader (const std::string& shaderDecl, const std::string& shaderBody)
+{
+       std::ostringstream computeShaderSource;
+
+       computeShaderSource             <<      "#version 310 es\n"
+                                                       <<      "layout(local_size_x = 1, local_size_y = 1) in;\n"
+                                                       <<      "\n"
+                                                       <<      "layout(binding = 0) buffer Output {\n"
+                                                       <<      "       highp vec4 values;\n"
+                                                       <<      "} sb_out;\n"
+                                                       <<      "\n"
+                                                       <<      shaderDecl
+                                                       <<      "void main ()\n"
+                                                       <<      "{\n"
+                                                       <<      shaderBody
+                                                       <<      "}\n";
+
+       return computeShaderSource.str();
+}
+
+glu::ProgramSources ShadersOOB::genNonComputeSource (void)
+{
+       std::ostringstream              shaderDecl;
+       std::ostringstream              shaderBody;
+
+       shaderDecl << "uniform highp int u_index;\n";
+
+       if (m_isLocalArray)
+       {
+               const char* const readWriteStatement = (m_isRead)
+                                                                                        ? "    color.x = color_out[u_index];\n"
+                                                                                        : "    color[u_index] = color_out.x;\n";
+
+               shaderBody      << "    highp vec4 color_out = vec4(1.0f);\n"
+                                       << readWriteStatement;
+       }
+       else
+       {
+               const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
+
+               shaderDecl << "layout(std140, binding = 0) " << ((m_isUBO) ? "uniform" : "buffer") << " Block\n"
+                       << "{\n"
+                       << "    highp vec4 color_out;\n"
+                       << "} " << resName << "[" << s_numBindings << "];\n";
+
+               const std::string readWriteStatement = (m_isRead)
+                                                                                        ? "    color.x = " + resName + "[0].color_out[u_index];\n"
+                                                                                        : "    color[u_index] = " + resName + "[0].color_out.x;\n";
+
+               shaderBody << readWriteStatement;
+       }
+
+       return glu::ProgramSources() << glu::VertexSource(genVertexShader(shaderDecl.str(), shaderBody.str()))
+                                                                << glu::FragmentSource(genFragmentShader(shaderDecl.str(), shaderBody.str()));
+}
+
+glu::ProgramSources ShadersOOB::genComputeSource (void)
+{
+       std::ostringstream              shaderDecl;
+       std::ostringstream              shaderBody;
+
+       shaderDecl << "uniform highp int u_index;\n";
+
+       shaderBody      << "    uvec3 size = gl_NumWorkGroups * gl_WorkGroupSize;\n"
+                               << "    uint groupNdx = size.x*gl_GlobalInvocationID.y + gl_GlobalInvocationID.x;\n";
+
+       if (m_isLocalArray)
+       {
+               const char* const readWriteStatement = (m_isRead)
+                                                                                        ? "    sb_out.values.x = values[u_index];\n"
+                                                                                        : "    sb_out.values[u_index] = values.x;\n";
+
+               shaderBody      << "    highp vec4 values = vec4(1.0f) * float(groupNdx);\n"
+                                       << readWriteStatement;
+       }
+       else
+       {
+               const std::string resName = (m_isUBO) ? "ub_in" : "sb_in";
+
+               shaderDecl      << "layout(std140, binding = 1) " << ((m_isUBO) ? "uniform" : "buffer") << " Input\n"
+                                       << "{\n"
+                                       << "    highp vec4 values;\n"
+                                       << "} " << resName << "[" << s_numBindings << "];\n";
+
+               std::string readWriteStatement = (m_isRead)
+                                                                          ? "  sb_out.values.x = " + resName + "[0].values[u_index] * float(groupNdx);\n"
+                                                                          : "  sb_out.values[u_index] = " + resName + "[0].values.x * float(groupNdx);\n";
+
+               shaderBody << readWriteStatement;
+       }
+
+       return glu::ProgramSources() << glu::ComputeSource(genComputeShader(shaderDecl.str(), shaderBody.str()));
+}
+
+glu::ProgramSources ShadersOOB::genSources (void)
+{
+       if (m_shaderType == SHADERTYPE_COMPUTE)
+               return genComputeSource();
+       else
+               return genNonComputeSource();
+}
+
+void ShadersOOB::setup (void)
+{
+       glu::ShaderProgram program(m_gl, genSources());
+
+       m_log << program;
+
+       if (!program.isOk())
+               TCU_FAIL("Failed to compile shader program");
+
+       GLU_CHECK_GLW_CALL(m_gl, useProgram(program.getProgram()));
+
+       const glw::GLint indexLocation = m_gl.getUniformLocation(program.getProgram(), "u_index");
+       GLU_CHECK_GLW_MSG(m_gl, "glGetUniformLocation()");
+       TCU_CHECK(indexLocation != (glw::GLint)-1);
+
+       const glw::GLint index = -1;
+       GLU_CHECK_GLW_CALL(m_gl, uniform1i(indexLocation, index));
+
+       if (m_shaderType != SHADERTYPE_COMPUTE)
+       {
+               const glw::GLfloat coords[] =
+               {
+                       -1.0f, -1.0f,
+                       +1.0f, -1.0f,
+                       +1.0f, +1.0f,
+                       -1.0f, +1.0f
+               };
+
+               // Setup vertices position
+               m_coordLocation = m_gl.getAttribLocation(program.getProgram(), "a_position");
+               GLU_CHECK_GLW_MSG(m_gl, "glGetAttribLocation()");
+               TCU_CHECK(m_coordLocation != (glw::GLint)-1);
+
+               GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
+               GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, coords));
+       }
+
+       // Create dummy data for filling buffer objects
+       const std::vector<tcu::Vec4> refValues(s_numBindings, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
+       glw::GLenum resType = (m_isUBO) ? GL_UNIFORM_BUFFER : GL_SHADER_STORAGE_BUFFER;
+
+       if (!m_isLocalArray)
+       {
+               // Set up interface block of buffer bindings
+               std::vector<glw::GLuint> buffers(s_numBindings, 0);
+               GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)buffers.size(), &buffers[0]));
+
+               for (int bufNdx = 0; bufNdx < (int)buffers.size(); ++bufNdx)
+               {
+                       GLU_CHECK_GLW_CALL(m_gl, bindBuffer(resType, buffers[bufNdx]));
+                       GLU_CHECK_GLW_CALL(m_gl, bufferData(resType, sizeof(tcu::Vec4), &(refValues[bufNdx]), GL_STATIC_DRAW));
+                       GLU_CHECK_GLW_CALL(m_gl, bindBufferBase(resType, bufNdx, buffers[bufNdx]));
+               }
+       }
+}
+
+void ShadersOOB::draw (void)
+{
+       if (m_shaderType == SHADERTYPE_COMPUTE)
+               m_gl.dispatchCompute(1, 1, 1);
+       else
+       {
+               const glw::GLuint indices[] = {0, 1, 2, 2, 3, 0};
+               m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, indices);
+       }
+}
+
+void ShadersOOB::teardown (void)
+{
+       if (m_shaderType != SHADERTYPE_COMPUTE)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
+       }
+
+       GLU_CHECK_GLW_CALL(m_gl, useProgram(0));
+}
+
+class QueryRobustAccessCase : public RobustnessTestCase
+{
+public:
+       QueryRobustAccessCase (EglTestContext& eglTestCtx, const char* name, const char* description)
+               : RobustnessTestCase (eglTestCtx, name, description) {}
+
+       TestCase::IterateResult iterate         (void)
+       {
+               TestLog&        log             = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "Check that after successfully creating a robust context the robust access query returned by glBooleanv() equals GL_TRUE\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const EGLint attribList[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
+                       EGL_NONE
+               };
+
+               checkRequiredEGLExtensions(attribList);
+
+               RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+               context.makeCurrent(m_eglSurface);
+
+               glw::Functions gl;
+               context.initGLFunctions(&gl);
+               checkRequiredGLRobustnessExtension(attribList, gl);
+
+               deUint8 robustAccessGL;
+               gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
+
+               if (robustAccessGL != GL_TRUE)
+               {
+                       log << TestLog::Message
+                               << "Invalid GL_CONTEXT_ROBUST_ACCESS returned by glGetBooleanv(). Got '" << robustAccessGL << "' expected GL_TRUE."
+                               << TestLog::EndMessage;
+
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+                       return STOP;
+               }
+
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               return STOP;
+       }
+};
+
+class NoResetNotificationCase : public RobustnessTestCase
+{
+public:
+       NoResetNotificationCase (EglTestContext& eglTestCtx, const char* name, const char* description)
+               : RobustnessTestCase (eglTestCtx, name, description) {}
+
+       TestCase::IterateResult iterate         (void)
+       {
+               TestLog&        log             = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "Check the reset notification strategy returned by glGetIntegerv() equals GL_NO_RESET_NOTIFICATION\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const EGLint attribList[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
+                       EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
+                       EGL_NONE
+               };
+
+               checkRequiredEGLExtensions(attribList);
+
+               RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+               context.makeCurrent(m_eglSurface);
+
+               glw::Functions gl;
+               context.initGLFunctions(&gl);
+               checkRequiredGLRobustnessExtension(attribList, gl);
+
+               deUint8 robustAccessGL;
+               gl.getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &robustAccessGL);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glGetBooleanv()");
+
+               glw::GLint reset = 0;
+               gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
+
+               if (reset != GL_NO_RESET_NOTIFICATION)
+               {
+                       log     << tcu::TestLog::Message
+                               << "Test failed! glGetIntegerv() returned wrong value. [" << glu::getErrorStr(reset) << ", expected " << glu::getErrorStr(GL_NO_RESET_NOTIFICATION) << "]"
+                               << tcu::TestLog::EndMessage;
+
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+                       return STOP;
+               }
+
+               GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
+
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               return STOP;
+       }
+};
+
+class LoseContextOnResetCase : public RobustnessTestCase
+{
+public:
+       LoseContextOnResetCase (EglTestContext& eglTestCtx, const char* name, const char* description)
+               : RobustnessTestCase(eglTestCtx, name, description) {}
+
+       TestCase::IterateResult iterate         (void)
+       {
+               TestLog&        log             = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "Check the reset notification strategy returned by glGetIntegerv() equals GL_LOSE_CONTEXT_ON_RESET\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const EGLint attribList[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
+                       EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
+                       EGL_NONE
+               };
+
+               checkRequiredEGLExtensions(attribList);
+
+               RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+               context.makeCurrent(m_eglSurface);
+
+               glw::Functions gl;
+               context.initGLFunctions(&gl);
+               checkRequiredGLRobustnessExtension(attribList, gl);
+
+               glw::GLint reset = 0;
+               gl.getIntegerv(GL_RESET_NOTIFICATION_STRATEGY, &reset);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glGetIntegerv()");
+
+               if (reset != GL_LOSE_CONTEXT_ON_RESET)
+               {
+                       log     << tcu::TestLog::Message
+                               << "Test failed! glGetIntegerv() returned wrong value. [" << reset << ", expected " << glu::getErrorStr(GL_LOSE_CONTEXT_ON_RESET) << "]"
+                               << tcu::TestLog::EndMessage;
+
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+                       return STOP;
+               }
+
+               log << tcu::TestLog::Message
+                       << "Check the graphics reset status returned by glGetGraphicsResetStatus() "
+                       << "equals GL_NO_ERROR\n"
+                       << tcu::TestLog::EndMessage;
+
+               GLU_CHECK_GLW_CALL(gl, getGraphicsResetStatus());
+
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               return STOP;
+       }
+};
+
+de::SharedPtr<ContextReset> contextResetFactory (const RobustnessTestCase::Params params, glw::Functions& gl, tcu::TestLog& log)
+{
+       if (params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP)
+               return de::SharedPtr<ContextReset>(new InfiniteLoop(gl, log, params.getShaderType()));
+
+       if (params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
+               return de::SharedPtr<ContextReset>(new FixedFunctionOOB(gl, log, params.getFixedFunctionType()));
+
+       if (params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB)
+               return de::SharedPtr<ContextReset>(new ShadersOOB(gl, log, params.getShaderType(), params.getResourceType(), params.getReadWriteType()));
+       else
+       {
+               DE_FATAL("Unknown context reset type");
+               return de::SharedPtr<ContextReset>(DE_NULL);
+       }
+}
+
+class ContextResetCase : public RobustnessTestCase
+{
+
+public:
+                                                       ContextResetCase                (EglTestContext& eglTestCtx, const char* name, const char* description, Params params);
+       virtual                                 ~ContextResetCase               (void) {};
+
+       virtual void                    provokeReset                    (de::SharedPtr<ContextReset>& contextReset) = 0;
+       virtual void                    waitForReset                    (de::SharedPtr<ContextReset>& contextReset) = 0;
+       virtual void                    passAndLog                              (de::SharedPtr<ContextReset>& contextReset) = 0;
+
+       TestCase::IterateResult iterate                                 (void);
+       void                                    execute                                 (glw::Functions& gl);
+
+private:
+                                               ContextResetCase                        (const ContextResetCase&);
+       ContextResetCase&       operator=                                       (const ContextResetCase&);
+};
+
+ContextResetCase::ContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
+       : RobustnessTestCase (eglTestCtx, name, description, params) {}
+
+TestCase::IterateResult ContextResetCase::iterate (void)
+{
+       glw::Functions  gl;
+
+       const EGLint attribList[] =
+       {
+               EGL_CONTEXT_CLIENT_VERSION, 3,
+               EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+               EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, (m_params.getRobustAccessType() == ROBUSTACCESS_TRUE) ? EGL_TRUE : EGL_FALSE,
+               EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
+               EGL_NONE
+       };
+
+       checkRequiredEGLExtensions(attribList);
+
+       RenderingContext context(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+       context.makeCurrent(m_eglSurface);
+
+       context.initGLFunctions(&gl);
+       checkRequiredGLRobustnessExtension(attribList, gl);
+
+       execute(gl);
+
+       return STOP;
+}
+
+void ContextResetCase::execute (glw::Functions& gl)
+{
+       de::SharedPtr<ContextReset> contextReset                                        = contextResetFactory(m_params, gl, m_testCtx.getLog());
+       glw::GLboolean                          isContextRobust                                 = GL_FALSE;
+
+       GLU_CHECK_GLW_CALL(gl, getBooleanv(GL_CONTEXT_ROBUST_ACCESS_EXT, &isContextRobust));
+       provokeReset(contextReset);
+
+       if (m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP)
+       {
+               try
+               {
+                       waitForReset(contextReset);
+
+                       const glw::GLenum       status  = gl.getGraphicsResetStatus();
+
+                       if (status == GL_NO_ERROR)
+                               m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Context was NOT lost");
+                       else
+                       {
+                               m_testCtx.getLog() << tcu::TestLog::Message << "glGetGraphicsResetStatus() returned " << glu::getGraphicsResetStatusStr(status) << tcu::TestLog::EndMessage;
+                               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was lost");
+                       }
+               }
+               catch (const glu::Error& error)
+               {
+                       if (error.getError() == GL_CONTEXT_LOST)
+                               passAndLog(contextReset);
+                       else
+                       {
+                               m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+                               m_testCtx.getLog()      << tcu::TestLog::Message
+                                                                       << "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
+                                                                       << tcu::TestLog::EndMessage;
+                       }
+               }
+       }
+       else if (m_params.getContextResetType() == CONTEXTRESETTYPE_SHADER_OOB || m_params.getContextResetType() == CONTEXTRESETTYPE_FIXED_FUNC_OOB)
+       {
+               try
+               {
+                       waitForReset(contextReset);
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Context was NOT lost. Test skipped");
+               }
+               catch (const glu::Error& error)
+               {
+                       if (error.getError() == GL_CONTEXT_LOST)
+                       {
+                               if (isContextRobust)
+                                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "No context reset should of occurred GL_CONTEXT_ROBUST_ACCESS == TRUE");
+                               else
+                                       passAndLog(contextReset);
+                       }
+                       else if (isContextRobust)
+                                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Got unknown error.");
+                       else
+                       {
+                               m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Warning: glGetError() returned wrong value. Expected GL_CONTEXT_LOST");
+
+                               m_testCtx.getLog()      << tcu::TestLog::Message
+                                                                       << "Warning: glGetError() returned wrong value [" << error.what() << ", expected " << glu::getErrorStr(GL_CONTEXT_LOST) << "]"
+                                                                       << tcu::TestLog::EndMessage;
+                       }
+               }
+       }
+       else
+               DE_FATAL("Unknown context reset type");
+}
+
+class BasicResetCase : public ContextResetCase
+{
+public:
+
+       BasicResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
+               : ContextResetCase (eglTestCtx, name, description, params) {}
+
+       virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->setup();
+               contextReset->draw();
+       }
+
+       virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->teardown();
+               contextReset->finish();
+       }
+
+       virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
+       {
+               TestLog& log = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "Check the graphics reset status returned by glGetGraphicsResetStatus() equals "
+                       << "GL_GUILTY_CONTEXT_RESET after a context reset\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const glw::GLint status = contextReset->getGraphicsResetStatus();
+
+               if (status == GL_NO_ERROR)
+               {
+                       log     << tcu::TestLog::Message
+                               << "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getGraphicsResetStatusStr(status) << ", expected " << glu::getGraphicsResetStatusStr(GL_GUILTY_CONTEXT_RESET) << "]"
+                               << tcu::TestLog::EndMessage;
+
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+               }
+               else
+               {
+                       if (contextReset->getError() != GL_NO_ERROR)
+                               m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Error flag not reset after calling getGraphicsResetStatus()");
+                       else
+                               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               }
+       }
+};
+
+class SyncObjectResetCase : public ContextResetCase
+{
+public:
+       SyncObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
+               : ContextResetCase (eglTestCtx, name, description, params) {}
+
+       virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->setup();
+               contextReset->draw();
+       }
+
+       virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->createSyncObject();
+               contextReset->teardown();
+               contextReset->finish();
+       }
+
+       virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
+       {
+               TestLog& log = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "Check the status of a sync object after a context reset returned by glGetSynciv() equals GL_SIGNALED\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const glw::GLint status = contextReset->getSyncStatus();
+               if (status != GL_SIGNALED)
+               {
+                       log     << tcu::TestLog::Message
+                               << "Test failed! glGetSynciv() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_SIGNALED) << "]"
+                               << tcu::TestLog::EndMessage;
+
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+               }
+               else
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+       }
+};
+
+class QueryObjectResetCase : public ContextResetCase
+{
+public:
+       QueryObjectResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
+               : ContextResetCase (eglTestCtx, name, description, params) {}
+
+       virtual void provokeReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->setup();
+               contextReset->beginQuery();
+               contextReset->draw();
+       }
+
+       virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->endQuery();
+               contextReset->teardown();
+               contextReset->finish();
+       }
+
+       virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
+       {
+               TestLog& log = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "Check the status of a query object after a context reset returned by glGetQueryObjectuiv() equals GL_TRUE\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const glw::GLuint queryReady = contextReset->getQueryAvailability();
+               if (queryReady != GL_TRUE)
+               {
+                       log << tcu::TestLog::Message
+                               << "Test failed! glGetQueryObjectuiv() returned wrong value [" << glu::getErrorStr(queryReady) << ", expected " << glu::getErrorStr(GL_TRUE) << "]"
+                               << tcu::TestLog::EndMessage;
+
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+               }
+               else
+               {
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               }
+       }
+};
+
+class InvalidShareContextCase : public RobustnessTestCase
+{
+public:
+       InvalidShareContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
+               : RobustnessTestCase (eglTestCtx, name, description) {}
+
+       TestCase::IterateResult iterate (void)
+       {
+               TestLog&                log             =       m_testCtx.getLog();
+               const Library&  egl             =       m_eglTestCtx.getLibrary();
+               bool                    isOk    =       true;
+
+               log << tcu::TestLog::Message
+                       << "EGL_BAD_MATCH is generated if reset notification strategies do not match when creating shared contexts\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const EGLint attribListA[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
+                       EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_NO_RESET_NOTIFICATION,
+                       EGL_NONE
+               };
+
+               const EGLint attribListB[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
+                       EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
+                       EGL_NONE
+               };
+
+               checkRequiredEGLExtensions(attribListA);
+
+               log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
+               RenderingContext contextA(m_eglTestCtx, attribListA, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+
+               log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
+               logAttribList(m_eglTestCtx, attribListB);
+
+               EGLContext contextB = egl.createContext(m_eglDisplay, m_eglConfig, contextA.getContext(), attribListB);
+
+               const EGLenum error = egl.getError();
+               if (error != EGL_BAD_MATCH)
+               {
+                       log << TestLog::Message
+                               << "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_MATCH) << "]"
+                               << TestLog::EndMessage;
+
+                       isOk = false;
+               }
+
+               if (contextB != EGL_NO_CONTEXT)
+                       egl.destroyContext(m_eglDisplay, contextB);
+
+               if (isOk)
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               else
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+               return STOP;
+       }
+};
+
+class SharedContextResetCase : public RobustnessTestCase
+{
+public:
+       SharedContextResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
+               : RobustnessTestCase (eglTestCtx, name, description, params) {}
+
+       TestCase::IterateResult iterate (void)
+       {
+               TestLog&        log             = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "A reset in one context will result in a reset in all other contexts in its share group\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               // Create two share contexts with the same reset notification strategies
+               const EGLint attribListShared[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
+                       EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
+                       EGL_NONE
+               };
+
+               checkRequiredEGLExtensions(attribListShared);
+
+               log << tcu::TestLog::Message << "Create context A (share_context = EGL_NO_CONTEXT)" << tcu::TestLog::EndMessage;
+               RenderingContext contextA(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+
+               log << tcu::TestLog::Message << "Create context B (share_context = context A)" << tcu::TestLog::EndMessage;
+               RenderingContext contextB(m_eglTestCtx, attribListShared, m_eglConfig, m_eglDisplay, contextA.getContext());
+
+               contextA.makeCurrent(m_eglSurface);
+
+               glw::Functions gl;
+               contextA.initGLFunctions(&gl);
+               checkRequiredGLRobustnessExtension(attribListShared, gl);
+
+               DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP);
+               de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType()));
+
+               contextReset->setup();
+               contextReset->draw();
+
+               try
+               {
+                       contextReset->teardown();
+                       contextReset->finish();
+               }
+               catch (const glu::Error& error)
+               {
+                       if (error.getError() == GL_CONTEXT_LOST)
+                       {
+                               contextB.makeCurrent(m_eglSurface);
+
+                               contextB.initGLFunctions(&gl);
+                               gl.getString(GL_VERSION); // arbitrary gl call
+
+                               if (gl.getError() != GL_CONTEXT_LOST)
+                               {
+                                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context B");
+                                       return STOP;
+                               }
+                       }
+                       else
+                       {
+                               m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A");
+                               return STOP;
+                       }
+               }
+
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               return STOP;
+       }
+};
+
+class InvalidContextCase : public RobustnessTestCase
+{
+public:
+       InvalidContextCase (EglTestContext& eglTestCtx, const char* name, const char* description)
+               : RobustnessTestCase (eglTestCtx, name, description) {}
+
+       TestCase::IterateResult iterate (void)
+       {
+               const Library&  egl             = m_eglTestCtx.getLibrary();
+               TestLog&                log             = m_testCtx.getLog();
+               bool                    isOk    = true;
+
+               log << tcu::TestLog::Message
+                       << "EGL_BAD_ATTRIBUTE is generated if EXT_create_context_robustness is NOT supported but EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT is specified\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const EGLint attribList[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
+                       EGL_NONE
+               };
+
+               if (eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_create_context_robustness"))
+               {
+                       m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "Test requires EGL_EXT_create_context_robustness to be unsupported");
+                       return STOP;
+               }
+
+               logAttribList(m_eglTestCtx, attribList);
+               EGLContext context = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
+
+               const EGLenum error = egl.getError();
+               if (error != EGL_BAD_ATTRIBUTE)
+               {
+                       log << TestLog::Message
+                               << "Test failed! eglCreateContext() returned with error [" << eglu::getErrorStr(error) << ", expected " << eglu::getErrorStr(EGL_BAD_ATTRIBUTE) << "]"
+                               << TestLog::EndMessage;
+
+                       isOk = false;
+               }
+
+               if (context != EGL_NO_CONTEXT)
+                       egl.destroyContext(m_eglDisplay, context);
+
+               if (isOk)
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               else
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+
+               return STOP;
+       }
+};
+
+class RecoverFromResetCase : public RobustnessTestCase
+{
+public:
+       RecoverFromResetCase (EglTestContext& eglTestCtx, const char* name, const char* description, Params params)
+               : RobustnessTestCase (eglTestCtx, name, description,  params) {}
+
+       TestCase::IterateResult iterate (void)
+       {
+               TestLog&        log             = m_testCtx.getLog();
+
+               log << tcu::TestLog::Message
+                       << "Provoke a context reset and wait for glGetGraphicsResetStatus() to return NO_ERROR_KHR.\n"
+                       << "Destroy the old context and successfully create a new context.\n\n"
+                       << tcu::TestLog::EndMessage;
+
+               const EGLint attribList[] =
+               {
+                       EGL_CONTEXT_CLIENT_VERSION, 3,
+                       EGL_CONTEXT_MINOR_VERSION_KHR, 1,
+                       EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT, EGL_TRUE,
+                       EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, EGL_LOSE_CONTEXT_ON_RESET,
+                       EGL_NONE
+               };
+
+               checkRequiredEGLExtensions(attribList);
+
+               log << tcu::TestLog::Message << "Create context A" << tcu::TestLog::EndMessage;
+               RenderingContext contextA(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+               contextA.makeCurrent(m_eglSurface);
+
+               glw::Functions gl;
+               contextA.initGLFunctions(&gl);
+               checkRequiredGLRobustnessExtension(attribList, gl);
+
+               DE_ASSERT(m_params.getContextResetType() == CONTEXTRESETTYPE_INFINITE_LOOP);
+               de::UniquePtr<ContextReset> contextReset(new InfiniteLoop(gl, log, m_params.getShaderType()));
+
+               contextReset->setup();
+               contextReset->draw();
+
+               try
+               {
+                       contextReset->teardown();
+                       contextReset->finish();
+               }
+               catch (const glu::Error& error)
+               {
+                       if (error.getError() == GL_CONTEXT_LOST)
+                       {
+                               const glw::GLint status = gl.getGraphicsResetStatus();
+                               if (status == GL_NO_ERROR)
+                               {
+                                       log << tcu::TestLog::Message
+                                               << "Test failed! glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(status) << ", expected " << glu::getErrorStr(GL_GUILTY_CONTEXT_RESET) << "]"
+                                               << tcu::TestLog::EndMessage;
+
+                                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+                                       return STOP;
+                               }
+
+                               const int       sleepTimeMs             = 1000;                         // (1 second)
+                               int                     timeout                 = sleepTimeMs * 10; // (10 seconds)
+                               int                     reset_status    = -1;
+
+                               // wait for context to reset
+                               while ((reset_status = gl.getGraphicsResetStatus() != GL_NO_ERROR) && timeout > 0)
+                               {
+                                       deSleep(sleepTimeMs);
+                                       timeout -= sleepTimeMs;
+                               }
+
+                               if (reset_status != GL_NO_ERROR)
+                               {
+                                       log     << tcu::TestLog::Message
+                                               << "Test failed! Context did not reset. glGetGraphicsResetStatus() returned wrong value [" << glu::getErrorStr(reset_status) << ", expected " << glu::getErrorStr(GL_NO_ERROR) << "]"
+                                               << tcu::TestLog::EndMessage;
+
+                                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
+                                       return STOP;
+                               }
+                       }
+                       else
+                       {
+                               m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! glGetError() returned wrong value. Expected GL_CONTEXT_LOST in context A");
+                               return STOP;
+                       }
+               }
+
+               try
+               {
+                       log << tcu::TestLog::Message << "Create context B" << tcu::TestLog::EndMessage;
+                       RenderingContext contextB(m_eglTestCtx, attribList, m_eglConfig, m_eglDisplay, EGL_NO_CONTEXT);
+               }
+               catch (const glu::Error& error)
+               {
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Test failed! Could not create new context. glGetError() returned wrong value. Expected GL_NO_ERROR");
+                       return STOP;
+               }
+
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               return STOP;
+       }
+};
+
+} // anonymous
+
+// Note: Tests limited to openGLES 3.1 contexts only
+TestCaseGroup* createRobustnessTests (EglTestContext& eglTestCtx)
+{
+       de::MovePtr<TestCaseGroup> group (new TestCaseGroup(eglTestCtx, "robustness", "KHR_robustness tests"));
+
+       tcu::TestCaseGroup* const contextCreationTestGroup                      = new TestCaseGroup(eglTestCtx, "create_context",                                               "Test valid context_creation attributes");
+       tcu::TestCaseGroup* const contextResetTestGroup                         = new TestCaseGroup(eglTestCtx, "reset_context",                                                "Test context resets scenarios");
+       tcu::TestCaseGroup* const negativeContextTestGroup                      = new TestCaseGroup(eglTestCtx, "negative_context",                                             "Test invalid context creation attributes");
+
+       tcu::TestCaseGroup* const shadersTestGroup                                      = new TestCaseGroup(eglTestCtx, "shaders",                                                              "Shader specific context reset tests");
+       tcu::TestCaseGroup* const fixedFunctionTestGroup                        = new TestCaseGroup(eglTestCtx, "fixed_function_pipeline",                              "Fixed function pipeline context reset tests with robust context");
+       tcu::TestCaseGroup* const fixedFunctionNonRobustTestGroup       = new TestCaseGroup(eglTestCtx, "fixed_function_pipeline_non_robust",   "Fixed function pipeline context reset tests with non-robust context");
+
+       tcu::TestCaseGroup* const infiniteLoopTestGroup                         = new TestCaseGroup(eglTestCtx, "infinite_loop",                                                "Infinite loop scenarios");
+       tcu::TestCaseGroup* const outOfBoundsTestGroup                          = new TestCaseGroup(eglTestCtx, "out_of_bounds",                                                "Out of bounds access scenarios with robust context");
+
+       tcu::TestCaseGroup* const outOfBoundsNonRobustTestGroup         = new TestCaseGroup(eglTestCtx, "out_of_bounds_non_robust",                             "Out of bounds access scenarios with non-robust context");
+
+       const string resetScenarioDescription   = "query error states and reset notifications";
+       const string syncScenarioDescription    = "query sync status with getSynciv()";
+       const string queryScenarioDescription   = "check availability of query result with getQueryObjectiv()";
+       const string sharedScenarioDescription  = "check reset notification is propagated to shared context";
+       const string recoverScenarioDescription = "delete the old context and create a new one";
+
+       // infinite loop test cases
+       {
+               tcu::TestCaseGroup* const infiniteLoopResetTestGroup    = new TestCaseGroup(eglTestCtx, "reset_status",                         "Tests that query the reset status after a context reset has occurred");
+               tcu::TestCaseGroup* const infiniteLoopSyncTestGroup             = new TestCaseGroup(eglTestCtx, "sync_status",                          "Tests that query the sync status after a context reset has occurred");
+               tcu::TestCaseGroup* const infiniteLoopQueryTestGroup    = new TestCaseGroup(eglTestCtx, "query_status",                         "Tests that query the state of a query object after a context reset has occurred");
+               tcu::TestCaseGroup* const infiniteLoopSharedTestGroup   = new TestCaseGroup(eglTestCtx, "shared_context_status",        "Tests that query the state of a shared context after a reset has occurred");
+               tcu::TestCaseGroup* const infiniteLoopRecoverTestGroup  = new TestCaseGroup(eglTestCtx, "recover_from_reset",           "Tests that attempt to create a new context after a context has occurred");
+
+               static const RobustnessTestCase::Params s_infiniteLoopCases[] =
+               {
+                       RobustnessTestCase::Params("vertex",                            "Provoke a context reset in vertex shader and ",                                CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_VERT),
+                       RobustnessTestCase::Params("fragment",                          "Provoke a context reset in fragment shader and ",                              CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_FRAG),
+                       RobustnessTestCase::Params("vertex_and_fragment",       "Provoke a context reset in vertex and fragment shader and ",   CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_VERT_AND_FRAG),
+                       RobustnessTestCase::Params("compute",                           "Provoke a context reset in compute shader and ",                               CONTEXTRESETTYPE_INFINITE_LOOP, SHADERTYPE_COMPUTE),
+               };
+
+               for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_infiniteLoopCases); ++testNdx)
+               {
+                       const RobustnessTestCase::Params& test = s_infiniteLoopCases[testNdx];
+                       infiniteLoopResetTestGroup->addChild    (new BasicResetCase                             (eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+                       infiniteLoopSyncTestGroup->addChild             (new SyncObjectResetCase                (eglTestCtx, test.getName().c_str(), (test.getDescription() + syncScenarioDescription).c_str(), test));
+                       infiniteLoopQueryTestGroup->addChild    (new QueryObjectResetCase               (eglTestCtx, test.getName().c_str(), (test.getDescription() + queryScenarioDescription).c_str(), test));
+                       infiniteLoopSharedTestGroup->addChild   (new SharedContextResetCase             (eglTestCtx, test.getName().c_str(), (test.getDescription() + sharedScenarioDescription).c_str(), test));
+                       infiniteLoopRecoverTestGroup->addChild  (new RecoverFromResetCase               (eglTestCtx, test.getName().c_str(), (test.getDescription() + recoverScenarioDescription).c_str(), test));
+               }
+
+               infiniteLoopTestGroup->addChild(infiniteLoopResetTestGroup);
+               infiniteLoopTestGroup->addChild(infiniteLoopSyncTestGroup);
+               infiniteLoopTestGroup->addChild(infiniteLoopQueryTestGroup);
+               infiniteLoopTestGroup->addChild(infiniteLoopSharedTestGroup);
+               infiniteLoopTestGroup->addChild(infiniteLoopRecoverTestGroup);
+       }
+
+       // out-of-bounds test cases
+       {
+               // robust context
+               tcu::TestCaseGroup* const uboReadArrayResetTestGroup    = new TestCaseGroup(eglTestCtx, "uniform_block",                "Uniform Block Accesses");
+               tcu::TestCaseGroup* const uboWriteArrayResetTestGroup   = new TestCaseGroup(eglTestCtx, "uniform_block",                "Uniform Block Accesses");
+               tcu::TestCaseGroup* const ssboWriteArrayResetTestGroup  = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
+               tcu::TestCaseGroup* const ssboReadArrayResetTestGroup   = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
+               tcu::TestCaseGroup* const localWriteArrayResetTestGroup = new TestCaseGroup(eglTestCtx, "local_array",                  "Local array accesses");
+               tcu::TestCaseGroup* const localReadArrayResetTestGroup  = new TestCaseGroup(eglTestCtx, "local_array",                  "Local array accesses");
+
+               // non-robust context (internal use only)
+               tcu::TestCaseGroup* const uboReadArrayResetNonRobustTestGroup           = new TestCaseGroup(eglTestCtx, "uniform_block",                "Uniform Block Accesses");
+               tcu::TestCaseGroup* const uboWriteArrayResetNonRobustTestGroup          = new TestCaseGroup(eglTestCtx, "uniform_block",                "Uniform Block Accesses");
+               tcu::TestCaseGroup* const ssboWriteArrayResetNonRobustTestGroup         = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
+               tcu::TestCaseGroup* const ssboReadArrayResetNonRobustTestGroup          = new TestCaseGroup(eglTestCtx, "shader_storage_block", "Shader Storage Block accesses");
+               tcu::TestCaseGroup* const localWriteArrayResetNonRobustTestGroup        = new TestCaseGroup(eglTestCtx, "local_array",                  "Local array accesses");
+               tcu::TestCaseGroup* const localReadArrayResetNonRobustTestGroup         = new TestCaseGroup(eglTestCtx, "local_array",                  "Local array accesses");
+
+               static const RobustnessTestCase::Params s_outOfBoundReadCases[] =
+               {
+                       // ubo read only
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                        RESOURCETYPE_UBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                        RESOURCETYPE_UBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,       RESOURCETYPE_UBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,                     RESOURCETYPE_UBO, READWRITETYPE_READ),
+
+                       // ssbo read only
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                        RESOURCETYPE_SSBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                        RESOURCETYPE_SSBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,       RESOURCETYPE_SSBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,                     RESOURCETYPE_SSBO, READWRITETYPE_READ),
+
+                       // local array read only
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                        RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                        RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,       RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,                     RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+
+                       // ubo read only (non-robust)
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                       RESOURCETYPE_UBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                       RESOURCETYPE_UBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,      RESOURCETYPE_UBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,            RESOURCETYPE_UBO, READWRITETYPE_READ),
+
+                       // ssbo read only (non-robust)
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                       RESOURCETYPE_SSBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                       RESOURCETYPE_SSBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,      RESOURCETYPE_SSBO, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,            RESOURCETYPE_SSBO, READWRITETYPE_READ),
+
+                       // local array read only (non-robust)
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                       RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                       RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,      RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,            RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_READ),
+               };
+
+               for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundReadCases); ++testNdx)
+               {
+                       const RobustnessTestCase::Params& test = s_outOfBoundReadCases[testNdx];
+
+                       if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
+                               uboReadArrayResetTestGroup->addChild                            (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                       if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
+                               uboReadArrayResetNonRobustTestGroup->addChild           (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                       if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
+                               ssboReadArrayResetTestGroup->addChild                           (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                       if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
+                               ssboReadArrayResetNonRobustTestGroup->addChild          (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                       if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
+                               localReadArrayResetTestGroup->addChild                          (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                       if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
+                               localReadArrayResetNonRobustTestGroup->addChild         (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+               }
+
+               static const RobustnessTestCase::Params s_outOfBoundWriteCases[] =
+               {
+                       // ubo write only
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                        RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                        RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,       RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,                     RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+
+                       // ssbo write only
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                        RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                        RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,       RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,                     RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+
+                       // local array write only
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                        RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                        RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,       RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,                     RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+
+                       // ubo write only (non-robust)
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                       RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                       RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,      RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,            RESOURCETYPE_UBO, READWRITETYPE_WRITE),
+
+                       // ssbo write only (non-robust)
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                       RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                       RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,      RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,            RESOURCETYPE_SSBO, READWRITETYPE_WRITE),
+
+                       // local array write only (non-robust)
+                       RobustnessTestCase::Params ("vertex",                           "Provoke a context reset in vertex shader and ",                                ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT,                       RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("fragment",                         "Provoke a context reset in fragment shader and ",                              ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_FRAG,                       RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("vertex_and_fragment",      "Provoke a context reset in vertex and fragment shader and ",   ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_VERT_AND_FRAG,      RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+                       RobustnessTestCase::Params ("compute",                          "Provoke a context reset in compute shader and ",                               ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_SHADER_OOB, SHADERTYPE_COMPUTE,            RESOURCETYPE_LOCAL_ARRAY, READWRITETYPE_WRITE),
+               };
+
+               for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_outOfBoundWriteCases); ++testNdx)
+               {
+                       const RobustnessTestCase::Params& test = s_outOfBoundWriteCases[testNdx];
+
+                               if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
+                                       uboWriteArrayResetTestGroup->addChild                           (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                               if (test.getResourceType() == RESOURCETYPE_UBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
+                                       uboWriteArrayResetNonRobustTestGroup->addChild          (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                               if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
+                                       ssboWriteArrayResetTestGroup->addChild                          (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                               if (test.getResourceType() == RESOURCETYPE_SSBO && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
+                                       ssboWriteArrayResetNonRobustTestGroup->addChild         (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                               if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_TRUE)
+                                       localWriteArrayResetTestGroup->addChild                         (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+
+                               if (test.getResourceType() == RESOURCETYPE_LOCAL_ARRAY && test.getRobustAccessType() == ROBUSTACCESS_FALSE)
+                                       localWriteArrayResetNonRobustTestGroup->addChild        (new BasicResetCase(eglTestCtx, test.getName().c_str(), (test.getDescription() + resetScenarioDescription).c_str(), test));
+               }
+
+               // robust Context
+               tcu::TestCaseGroup* const outOfBoundsResetReadAccessTestGroup   = new TestCaseGroup(eglTestCtx, "reads",        "Out of bounds read accesses");
+               tcu::TestCaseGroup* const outOfBoundsResetWriteAccessTestGroup  = new TestCaseGroup(eglTestCtx, "writes",       "Out of bounds write accesses");
+
+               outOfBoundsResetReadAccessTestGroup->addChild(uboReadArrayResetTestGroup);
+               outOfBoundsResetReadAccessTestGroup->addChild(ssboReadArrayResetTestGroup);
+               outOfBoundsResetReadAccessTestGroup->addChild(localReadArrayResetTestGroup);
+
+               outOfBoundsResetWriteAccessTestGroup->addChild(uboWriteArrayResetTestGroup);
+               outOfBoundsResetWriteAccessTestGroup->addChild(ssboWriteArrayResetTestGroup);
+               outOfBoundsResetWriteAccessTestGroup->addChild(localWriteArrayResetTestGroup);
+
+               tcu::TestCaseGroup* const outOfBoundsResetTestGroup             = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
+
+               outOfBoundsResetTestGroup->addChild(outOfBoundsResetReadAccessTestGroup);
+               outOfBoundsResetTestGroup->addChild(outOfBoundsResetWriteAccessTestGroup);
+
+               outOfBoundsTestGroup->addChild(outOfBoundsResetTestGroup);
+
+               // non-robust Context (internal use only)
+               tcu::TestCaseGroup* const outOfBoundsResetReadAccessNonRobustTestGroup  = new TestCaseGroup(eglTestCtx, "reads",        "Out of bounds read accesses");
+               tcu::TestCaseGroup* const outOfBoundsResetWriteAccessNonRobustTestGroup = new TestCaseGroup(eglTestCtx, "writes",       "Out of bounds write accesses");
+
+               outOfBoundsResetReadAccessNonRobustTestGroup->addChild(uboReadArrayResetNonRobustTestGroup);
+               outOfBoundsResetReadAccessNonRobustTestGroup->addChild(ssboReadArrayResetNonRobustTestGroup);
+               outOfBoundsResetReadAccessNonRobustTestGroup->addChild(localReadArrayResetNonRobustTestGroup);
+
+               outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(uboWriteArrayResetNonRobustTestGroup);
+               outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(ssboWriteArrayResetNonRobustTestGroup);
+               outOfBoundsResetWriteAccessNonRobustTestGroup->addChild(localWriteArrayResetNonRobustTestGroup);
+
+               tcu::TestCaseGroup* const outOfBoundsResetNonRobustTestGroup            = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
+
+               outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetReadAccessNonRobustTestGroup);
+               outOfBoundsResetNonRobustTestGroup->addChild(outOfBoundsResetWriteAccessNonRobustTestGroup);
+
+               outOfBoundsNonRobustTestGroup->addChild(outOfBoundsResetNonRobustTestGroup);
+       }
+
+       // fixed function test cases
+       {
+               // robust context
+               tcu::TestCaseGroup* const fixedFunctionResetStatusTestGroup                             = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
+
+               // non-robust context (internal use only)
+               tcu::TestCaseGroup* const fixedFunctionResetStatusNonRobustTestGroup    = new TestCaseGroup(eglTestCtx, "reset_status", "Tests that query the reset status after a context reset has occurred");
+
+               static const RobustnessTestCase::Params s_fixedFunctionPipelineCases[] =
+               {
+                       RobustnessTestCase::Params( "index_buffer_out_of_bounds",       "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES),
+                       RobustnessTestCase::Params( "vertex_buffer_out_of_bounds",      "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_TRUE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES),
+
+                       RobustnessTestCase::Params( "index_buffer_out_of_bounds",       "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_INDICES),
+                       RobustnessTestCase::Params( "vertex_buffer_out_of_bounds",      "Provoke context reset and query error states and reset notifications", ROBUSTACCESS_FALSE, CONTEXTRESETTYPE_FIXED_FUNC_OOB, FIXEDFUNCTIONTYPE_VERTICES),
+               };
+
+               for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(s_fixedFunctionPipelineCases); ++testNdx)
+               {
+                       const RobustnessTestCase::Params& test = s_fixedFunctionPipelineCases[testNdx];
+                       if (test.getRobustAccessType() == ROBUSTACCESS_TRUE)
+                               fixedFunctionResetStatusTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
+                       else
+                               fixedFunctionResetStatusNonRobustTestGroup->addChild(new BasicResetCase(eglTestCtx, test.getName().c_str(), test.getDescription().c_str(), test));
+               }
+
+               fixedFunctionTestGroup->addChild(fixedFunctionResetStatusTestGroup);
+               fixedFunctionNonRobustTestGroup->addChild(fixedFunctionResetStatusNonRobustTestGroup);
+       }
+
+       // context creation query cases
+       {
+               contextCreationTestGroup->addChild(new QueryRobustAccessCase    (eglTestCtx, "query_robust_access",             "Query robust access after successfully creating a robust context"));
+               contextCreationTestGroup->addChild(new NoResetNotificationCase  (eglTestCtx, "no_reset_notification",   "Query reset notification strategy after specifying GL_NO_RESET_NOTIFICATION"));
+               contextCreationTestGroup->addChild(new LoseContextOnResetCase   (eglTestCtx, "lose_context_on_reset",   "Query reset notification strategy after specifying GL_LOSE_CONTEXT_ON_RESET"));
+       }
+
+       // invalid context creation cases
+       {
+               negativeContextTestGroup->addChild(new InvalidContextCase               (eglTestCtx, "invalid_robust_context_creation",                 "Create a non-robust context but specify a reset notification strategy"));
+               negativeContextTestGroup->addChild(new InvalidShareContextCase  (eglTestCtx, "invalid_robust_shared_context_creation",  "Create a context share group with conflicting reset notification strategies"));
+       }
+
+       shadersTestGroup->addChild(infiniteLoopTestGroup);
+       shadersTestGroup->addChild(outOfBoundsTestGroup);
+       shadersTestGroup->addChild(outOfBoundsNonRobustTestGroup);
+
+       contextResetTestGroup->addChild(shadersTestGroup);
+       contextResetTestGroup->addChild(fixedFunctionTestGroup);
+       contextResetTestGroup->addChild(fixedFunctionNonRobustTestGroup);
+
+       group->addChild(contextCreationTestGroup);
+       group->addChild(contextResetTestGroup);
+       group->addChild(negativeContextTestGroup);
+
+       return group.release();
+}
+
+} // egl
+} // deqp
diff --git a/modules/egl/teglRobustnessTests.hpp b/modules/egl/teglRobustnessTests.hpp
new file mode 100644 (file)
index 0000000..e670b5c
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _TEGLROBUSTNESSTESTS_HPP
+#define _TEGLROBUSTNESSTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program EGL Module
+ * ---------------------------------------
+ *
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Robustness tests for KHR_robustness
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "teglTestCase.hpp"
+
+namespace deqp
+{
+namespace egl
+{
+
+TestCaseGroup* createRobustnessTests (EglTestContext& eglTestCtx);
+
+} // egl
+} // deqp
+
+#endif // _TEGLROBUSTNESSTESTS_HPP
index 0c4ee77..91a374b 100644 (file)
@@ -64,6 +64,7 @@
 #include "teglThreadCleanUpTests.hpp"
 #include "teglMutableRenderBufferTests.hpp"
 #include "teglGetFrameTimestampsTests.hpp"
+#include "teglRobustnessTests.hpp"
 
 namespace deqp
 {
@@ -140,6 +141,7 @@ public:
                addChild(createThreadCleanUpTest                (m_eglTestCtx));
                addChild(new MutableRenderBufferTests   (m_eglTestCtx));
                addChild(createGetFrameTimestampsTests  (m_eglTestCtx));
+               addChild(createRobustnessTests                  (m_eglTestCtx));
        }
 };
 
index de28b32..52ffd1e 100644 (file)
@@ -345,7 +345,8 @@ NYC_VULKAN_PKG                                      = Package(module = VULKAN_MODULE, configurations = [
 
 MASTER_EGL_COMMON_FILTERS              = [include("egl-master.txt"),
                                                                   exclude("egl-test-issues.txt"),
-                                                                  exclude("egl-internal-api-tests.txt")]
+                                                                  exclude("egl-internal-api-tests.txt"),
+                                                                  exclude("egl-manual-robustness.txt")]
 MASTER_EGL_PKG                                 = Package(module = EGL_MODULE, configurations = [
                # Master
                Configuration(name                      = "master",
index 7b62083..45a17cd 100644 (file)
@@ -75,7 +75,7 @@ ENUM_GROUPS = [
 
        # ErrorCode
        ("Error",                               ["NO_ERROR", "INVALID_ENUM", "INVALID_VALUE", "INVALID_OPERATION", "OUT_OF_MEMORY",
-                                                        "INVALID_FRAMEBUFFER_OPERATION"]),
+                                                        "INVALID_FRAMEBUFFER_OPERATION", "CONTEXT_LOST"]),
        # PixelType, partially
        ("Type", [
                # GLES2 types
@@ -938,6 +938,14 @@ ENUM_GROUPS = [
        ("TextureFormat", [
                # generated: UncompressedTextureFormat + CompressedTextureFormat
        ]),
+
+       # GraphicsResetStatus
+       ("GraphicsResetStatus", [
+               "NO_ERROR",
+               "GUILTY_CONTEXT_RESET",
+               "INNOCENT_CONTEXT_RESET",
+               "UNKNOWN_CONTEXT_RESET",
+       ]),
 ]
 
 def getEnumGroupByName (name):