Merge Vulkan CTS 1.0.2.2 into aosp/master
authorPyry Haulos <phaulos@google.com>
Fri, 31 Mar 2017 21:12:43 +0000 (14:12 -0700)
committerPyry Haulos <phaulos@google.com>
Fri, 31 Mar 2017 23:14:09 +0000 (16:14 -0700)
Bug: 36780905

New tests:

 * Add tests for VK_KHR_incremental_present
 * Add tests for VK_GOOGLE_display_timing
 * Handle VK_EXT_swapchain_colorspace in swapchain tests

Fixes:

 * Imgtec Waiver for SNORM linear filtering
 * Check DynamicIndexing in pipeline.image count tests
 * Add missing barrier in synchronization tests
 * Fix invalid SPIR-V in dEQP-VK.sparse_resources
 * Add missing flushes for basic draws
 * Add missing flushes for indirect draws
 * Fix precision mismatch issues in dEQP-VK.glsl
 * Fix validation errors in dEQP-VK.tessellation
 * Fix precision mismatch in dEQP-VK.binding_model
 * Fix depth stencil aspect flag in render pass input tests
 * Fix image layout in dEQP-VK.image
 * Fix validation errors in dEQP-VK.geometry
 * Fix issues in pipeline.timestamp.transfer_tests
 * Refactor vktShaderExecutor
 * Improve precision handling in texture.explicit_lod
 * Fix a compilation error on GCC 5.4
 * Fix a compilation error on MSVC12
 * Fix bug in reallocation callback validation
 * Fix input attachment layout in renderpass tests

Change-Id: I76a768de047020d4624afa0aee2232e9e022f8d2

101 files changed:
Android.mk
android/cts/AndroidTest.xml
android/cts/lmp-mr1/gles31-master.txt
android/cts/lmp-mr1/src/es31-lmp-mr1.txt
android/cts/lmp/gles31-master.txt
android/cts/lmp/src/es31-lmp.txt
android/cts/master/egl-master.txt
android/cts/master/gles31-master.txt
android/cts/master/gles31-multisample.txt
android/cts/master/gles31-rotate-landscape.txt
android/cts/master/gles31-rotate-portrait.txt
android/cts/master/gles31-rotate-reverse-landscape.txt
android/cts/master/gles31-rotate-reverse-portrait.txt
android/cts/master/src/egl-manual-robustness.txt [new file with mode: 0644]
android/cts/master/src/gles31-hw-issues.txt
android/cts/mnc/gles31-master.txt
android/cts/mnc/src/gles31-master.txt
android/cts/nyc/gles31-master.txt
android/cts/nyc/src/gles31-master.txt
android/cts/runner/src/com/drawelements/deqp/runner/DeqpTestRunner.java
android/scripts/build.py
android/scripts/common.py
android/scripts/install.py
data/gles31/shaders/linkage_tessellation.test
data/gles31/shaders/separate_shader_validation.test
framework/egl/egluCallLogWrapper.inl
framework/egl/egluCallLogWrapperApi.inl
framework/egl/egluConfigFilter.cpp
framework/egl/egluConfigFilter.hpp
framework/egl/egluConfigInfo.cpp
framework/egl/egluConfigInfo.hpp
framework/egl/egluStrUtil.inl
framework/egl/egluStrUtilPrototypes.inl
framework/egl/wrapper/eglwEnums.inl
framework/egl/wrapper/eglwFuncPtrLibraryDecl.inl
framework/egl/wrapper/eglwFuncPtrLibraryImpl.inl
framework/egl/wrapper/eglwFunctionTypes.inl
framework/egl/wrapper/eglwFunctions.inl
framework/egl/wrapper/eglwInitCore.inl
framework/egl/wrapper/eglwInitExtensions.inl
framework/egl/wrapper/eglwLibrary.inl
framework/egl/wrapper/eglwStaticLibrary14.inl
framework/egl/wrapper/eglwStaticLibrary15.inl
framework/opengl/gluStrUtil.inl
framework/opengl/gluStrUtilPrototypes.inl
framework/opengl/wrapper/glwInitExtES.inl
framework/platform/X11/tcuX11.cpp
framework/platform/X11/tcuX11.hpp
framework/platform/X11/tcuX11Platform.cpp
modules/egl/CMakeLists.txt
modules/egl/teglChooseConfigReference.cpp
modules/egl/teglChooseConfigTests.cpp
modules/egl/teglCreateContextTests.cpp
modules/egl/teglGetFrameTimestampsTests.cpp [new file with mode: 0644]
modules/egl/teglGetFrameTimestampsTests.hpp [new file with mode: 0644]
modules/egl/teglGetProcAddressTests.inl
modules/egl/teglNegativeApiTests.cpp
modules/egl/teglRenderCase.cpp
modules/egl/teglRobustnessTests.cpp [new file with mode: 0644]
modules/egl/teglRobustnessTests.hpp [new file with mode: 0644]
modules/egl/teglSimpleConfigCase.cpp
modules/egl/teglTestPackage.cpp
modules/gles2/functional/es2fDepthStencilTests.cpp
modules/gles2/functional/es2fIntegerStateQueryTests.cpp
modules/gles2/functional/es2fPolygonOffsetTests.cpp
modules/gles3/functional/es3fASTCDecompressionCases.cpp
modules/gles3/functional/es3fDepthStencilTests.cpp
modules/gles3/functional/es3fIntegerStateQueryTests.cpp
modules/gles3/functional/es3fNegativeTextureApiTests.cpp
modules/gles3/functional/es3fPolygonOffsetTests.cpp
modules/gles3/functional/es3fShaderPrecisionTests.cpp
modules/gles3/functional/es3fTextureSpecificationTests.cpp
modules/gles3/performance/es3pBufferDataUploadTests.cpp
modules/gles31/functional/CMakeLists.txt
modules/gles31/functional/es31fCopyImageTests.cpp
modules/gles31/functional/es31fDebugTests.cpp
modules/gles31/functional/es31fFunctionalTests.cpp
modules/gles31/functional/es31fIntegerStateQueryTests.cpp
modules/gles31/functional/es31fLayoutBindingTests.cpp
modules/gles31/functional/es31fNegativeBufferApiTests.cpp
modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeSSBOBlockTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeShaderApiTests.cpp
modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp
modules/gles31/functional/es31fNegativeShaderStorageTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeShaderStorageTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeStateApiTests.cpp
modules/gles31/functional/es31fNegativeTessellationTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeTessellationTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeTextureApiTests.cpp
modules/gles31/functional/es31fPrimitiveBoundingBoxTests.cpp
modules/gles31/functional/es31fSRGBDecodeTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fSRGBDecodeTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fSynchronizationTests.cpp
modules/gles31/functional/es31fTessellationTests.cpp
modules/glshared/glsFboCompletenessTests.cpp
scripts/build_android_mustpass.py
scripts/egl/common.py
scripts/egl/str_util.py
scripts/opengl/gen_str_util.py
scripts/opengl/src_util.py

index 70666cc..4e7bbcf 100644 (file)
@@ -270,6 +270,7 @@ LOCAL_SRC_FILES := \
        modules/egl/teglCreateContextExtTests.cpp \
        modules/egl/teglCreateContextTests.cpp \
        modules/egl/teglCreateSurfaceTests.cpp \
+       modules/egl/teglGetFrameTimestampsTests.cpp \
        modules/egl/teglGetProcAddressTests.cpp \
        modules/egl/teglGLES1RenderUtil.cpp \
        modules/egl/teglGLES2RenderUtil.cpp \
@@ -295,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 \
@@ -589,7 +591,10 @@ LOCAL_SRC_FILES := \
        modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp \
        modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp \
        modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.cpp \
+       modules/gles31/functional/es31fNegativeShaderStorageTests.cpp \
        modules/gles31/functional/es31fNegativeStateApiTests.cpp \
+       modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp \
+       modules/gles31/functional/es31fNegativeTessellationTests.cpp \
        modules/gles31/functional/es31fNegativeTestShared.cpp \
        modules/gles31/functional/es31fNegativeTextureApiTests.cpp \
        modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp \
@@ -637,6 +642,7 @@ LOCAL_SRC_FILES := \
        modules/gles31/functional/es31fVertexAttributeBindingTests.cpp \
        modules/gles31/functional/es31fCopyImageTests.cpp \
        modules/gles31/functional/es31fDrawBuffersIndexedTests.cpp \
+       modules/gles31/functional/es31fSRGBDecodeTests.cpp \
        modules/gles31/stress/es31sDrawTests.cpp \
        modules/gles31/stress/es31sStressTests.cpp \
        modules/gles31/stress/es31sTessellationGeometryInteractionTests.cpp \
@@ -904,6 +910,7 @@ LOCAL_SRC_FILES := \
        external/vulkancts/modules/vulkan/vktTestPackage.cpp \
        external/vulkancts/modules/vulkan/vktTestPackageEntry.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiDisplayTimingTests.cpp \
+       external/vulkancts/modules/vulkan/wsi/vktWsiIncrementalPresentTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiSurfaceTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiSwapchainTests.cpp \
        external/vulkancts/modules/vulkan/wsi/vktWsiTests.cpp
@@ -981,6 +988,7 @@ deqp_compile_flags := \
        -DDEQP_GLES2_RUNTIME_LOAD=1 \
        -DQP_SUPPORT_PNG=1 \
        -Wconversion \
+       -fwrapv \
        -Wno-sign-conversion
 
 LOCAL_SHARED_LIBRARIES := \
@@ -1000,7 +1008,7 @@ LOCAL_CFLAGS += \
        $(deqp_compile_flags)
 
 LOCAL_SDK_VERSION := 22
-LOCAL_CPPFLAGS += -Wno-non-virtual-dtor -fwrapv
+LOCAL_CPPFLAGS += -Wno-non-virtual-dtor -Wno-delete-non-virtual-dtor
 LOCAL_NDK_STL_VARIANT := gnustl_static
 LOCAL_RTTI_FLAG := -frtti -fexceptions
 LOCAL_MULTILIB := both
index 0484be6..5838cfd 100644 (file)
@@ -24,7 +24,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="unspecified"/>
-               <option name="runtime-hint" value="24m"/>
+               <option name="runtime-hint" value="23m"/>
                <option name="deqp-config-required" value="true"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
@@ -33,7 +33,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="unspecified"/>
-               <option name="runtime-hint" value="40m"/>
+               <option name="runtime-hint" value="46m"/>
                <option name="deqp-config-required" value="true"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
@@ -42,7 +42,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="unspecified"/>
-               <option name="runtime-hint" value="1h15m"/>
+               <option name="runtime-hint" value="1h50m"/>
                <option name="deqp-config-required" value="true"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
@@ -51,7 +51,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="0"/>
-               <option name="runtime-hint" value="7m"/>
+               <option name="runtime-hint" value="1m"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
                <option name="deqp-package" value="dEQP-GLES3"/>
@@ -59,7 +59,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="90"/>
-               <option name="runtime-hint" value="7m"/>
+               <option name="runtime-hint" value="1m"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
                <option name="deqp-package" value="dEQP-GLES3"/>
@@ -67,7 +67,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="180"/>
-               <option name="runtime-hint" value="7m"/>
+               <option name="runtime-hint" value="1m"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
                <option name="deqp-package" value="dEQP-GLES3"/>
@@ -75,7 +75,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="270"/>
-               <option name="runtime-hint" value="7m"/>
+               <option name="runtime-hint" value="1m"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
                <option name="deqp-package" value="dEQP-GLES3"/>
@@ -83,7 +83,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms4"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="unspecified"/>
-               <option name="runtime-hint" value="10m"/>
+               <option name="runtime-hint" value="1m"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
                <option name="deqp-package" value="dEQP-GLES3"/>
@@ -91,7 +91,7 @@
                <option name="deqp-gl-config-name" value="rgb565d0s0ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="unspecified"/>
-               <option name="runtime-hint" value="10m"/>
+               <option name="runtime-hint" value="1m"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
                <option name="deqp-package" value="dEQP-GLES31"/>
@@ -99,7 +99,7 @@
                <option name="deqp-gl-config-name" value="rgba8888d24s8ms0"/>
                <option name="deqp-surface-type" value="window"/>
                <option name="deqp-screen-rotation" value="unspecified"/>
-               <option name="runtime-hint" value="7h30m"/>
+               <option name="runtime-hint" value="1h40m"/>
                <option name="deqp-config-required" value="true"/>
        </test>
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
        <test class="com.drawelements.deqp.runner.DeqpTestRunner">
                <option name="deqp-package" value="dEQP-VK"/>
                <option name="deqp-caselist-file" value="vk-master.txt"/>
-               <option name="runtime-hint" value="3h45m"/>
+               <option name="runtime-hint" value="2h29m"/>
        </test>
 </configuration>
index 2baaad3..596e3d6 100644 (file)
@@ -13000,7 +13000,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
@@ -13016,7 +13015,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index 96833a1..632afa9 100644 (file)
@@ -13000,7 +13000,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
@@ -13016,7 +13015,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index d79324b..87fd6bc 100644 (file)
@@ -12589,7 +12589,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_location
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_array_element_type
@@ -12603,7 +12602,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index 05e7d95..afe5c02 100644 (file)
@@ -12589,7 +12589,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_location
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_array_element_type
@@ -12603,7 +12602,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index 74f28a9..d3b76c1 100644 (file)
@@ -24,6 +24,7 @@ dEQP-EGL.functional.create_context.rgba8888_no_depth_stencil
 dEQP-EGL.functional.create_context.rgba8888_depth_no_stencil
 dEQP-EGL.functional.create_context.rgba8888_depth_stencil
 dEQP-EGL.functional.create_context.other
+dEQP-EGL.functional.create_context.no_config
 dEQP-EGL.functional.query_context.simple.query_api
 dEQP-EGL.functional.query_context.get_current_context.rgb565_window
 dEQP-EGL.functional.query_context.get_current_context.rgb565_pixmap
@@ -413,6 +414,9 @@ dEQP-EGL.functional.choose_config.random.buffer_sizes
 dEQP-EGL.functional.choose_config.random.surface_type
 dEQP-EGL.functional.choose_config.random.sample_buffers
 dEQP-EGL.functional.choose_config.random.all
+dEQP-EGL.functional.choose_config.color_component_type_ext.dont_care
+dEQP-EGL.functional.choose_config.color_component_type_ext.fixed
+dEQP-EGL.functional.choose_config.color_component_type_ext.float
 dEQP-EGL.functional.color_clears.single_context.gles1.rgb565_window
 dEQP-EGL.functional.color_clears.single_context.gles1.rgb565_pixmap
 dEQP-EGL.functional.color_clears.single_context.gles1.rgb565_pbuffer
@@ -2364,11 +2368,14 @@ dEQP-EGL.functional.multithread.pbuffer_context
 dEQP-EGL.functional.multithread.single_window_context
 dEQP-EGL.functional.multithread.pbuffer_single_window_context
 dEQP-EGL.functional.get_proc_address.extension.egl_android_blob_cache
+dEQP-EGL.functional.get_proc_address.extension.egl_android_create_native_client_buffer
 dEQP-EGL.functional.get_proc_address.extension.egl_android_native_fence_sync
+dEQP-EGL.functional.get_proc_address.extension.egl_android_presentation_time
 dEQP-EGL.functional.get_proc_address.extension.egl_angle_query_surface_pointer
 dEQP-EGL.functional.get_proc_address.extension.egl_ext_device_base
 dEQP-EGL.functional.get_proc_address.extension.egl_ext_device_enumeration
 dEQP-EGL.functional.get_proc_address.extension.egl_ext_device_query
+dEQP-EGL.functional.get_proc_address.extension.egl_ext_image_dma_buf_import_modifiers
 dEQP-EGL.functional.get_proc_address.extension.egl_ext_output_base
 dEQP-EGL.functional.get_proc_address.extension.egl_ext_platform_base
 dEQP-EGL.functional.get_proc_address.extension.egl_ext_stream_consumer_egloutput
@@ -2384,6 +2391,7 @@ dEQP-EGL.functional.get_proc_address.extension.egl_khr_lock_surface3
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_partial_update
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_reusable_sync
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_stream
+dEQP-EGL.functional.get_proc_address.extension.egl_khr_stream_attrib
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_stream_consumer_gltexture
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_stream_cross_process_fd
 dEQP-EGL.functional.get_proc_address.extension.egl_khr_stream_fifo
@@ -2398,6 +2406,7 @@ dEQP-EGL.functional.get_proc_address.extension.egl_nv_native_query
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_post_sub_buffer
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_stream_consumer_gltexture_yuv
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_stream_metadata
+dEQP-EGL.functional.get_proc_address.extension.egl_nv_stream_reset
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_stream_sync
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_sync
 dEQP-EGL.functional.get_proc_address.extension.egl_nv_system_time
@@ -3540,3 +3549,75 @@ dEQP-EGL.functional.thread_cleanup.multi_context_multi_surface
 dEQP-EGL.functional.mutable_render_buffer.querySurface
 dEQP-EGL.functional.mutable_render_buffer.negativeConfigBit
 dEQP-EGL.functional.mutable_render_buffer.basic
+dEQP-EGL.functional.get_frame_timestamps.rgb565_no_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgb565_no_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgb565_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgb565_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgb888_no_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgb888_no_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgb888_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgb888_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba4444_no_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba4444_no_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba4444_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba4444_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba5551_no_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba5551_no_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba5551_depth_no_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba5551_depth_stencil
+dEQP-EGL.functional.get_frame_timestamps.rgba8888_no_depth_no_stencil
+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
index 8204cb8..b4f78d9 100644 (file)
@@ -4089,12 +4089,17 @@ dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.vertex_fragmen
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.vertex_fragment_same_varying_name_2
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_vertex_index
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_non_array
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_non_array
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_array_size_mismatch
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.internal_array_size_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_patch_in_usage
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_patch_out_usage
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_per_patch_qualifier_usage
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.per_patch_qualifier_mismatch_1
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.per_patch_qualifier_mismatch_2
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_block
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_block_non_array
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_block_non_array
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_block_array_size_mismatch
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_block
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_block_array
@@ -4158,6 +4163,12 @@ dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.uvec2
 dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.uvec3
 dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.uvec4
 dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.float_struct
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.primitive_mode_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.spacing_mode_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.vertex_order_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.vertex_count_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.barriers.rules.invalid_barrier_usage_within_control_flow
+dEQP-GLES31.functional.shaders.linkage.tessellation.barriers.rules.invalid_barrier_usage_after_return
 dEQP-GLES31.functional.shaders.linkage.tessellation_geometry.varying.rules.type_mismatch
 dEQP-GLES31.functional.shaders.linkage.tessellation_geometry.varying.rules.different_precision
 dEQP-GLES31.functional.shaders.linkage.tessellation_geometry.varying.rules.no_output_declaration
@@ -15875,7 +15886,7 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
+dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
@@ -15897,7 +15908,7 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_different_member_interpolation
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
+dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
@@ -16758,11 +16769,23 @@ dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.shader
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.tessellation_shader
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.texture_buffer
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.texture_cube_map_array
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_directive.accessing_bounding_box_type
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.ssbo_block.ssbo_block_interface_matching_tests
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.ssbo_block.ssbo_using_shared_qualifier_tests
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_variable_name
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_function_name
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.precise.precise_as_function_argument
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.attachment_advanced_equation
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_storage.block_number_limits
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_storage.max_combined_block_number_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.single_tessellation_stage
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.invalid_primitive_mode
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.tessellation_not_active
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.invalid_program_state
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.get_programiv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.invalid_program_queries
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.tessellation_control_invalid_vertex_count
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.gen_buffers
@@ -17204,11 +17227,23 @@ dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.shader_io_bl
 dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.tessellation_shader
 dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.texture_buffer
 dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.texture_cube_map_array
+dEQP-GLES31.functional.debug.negative_coverage.log.shader_directive.accessing_bounding_box_type
+dEQP-GLES31.functional.debug.negative_coverage.log.ssbo_block.ssbo_block_interface_matching_tests
+dEQP-GLES31.functional.debug.negative_coverage.log.ssbo_block.ssbo_using_shared_qualifier_tests
 dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_variable_name
 dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_name
 dEQP-GLES31.functional.debug.negative_coverage.log.precise.precise_as_function_argument
 dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.attachment_advanced_equation
+dEQP-GLES31.functional.debug.negative_coverage.log.shader_storage.block_number_limits
+dEQP-GLES31.functional.debug.negative_coverage.log.shader_storage.max_combined_block_number_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.single_tessellation_stage
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.invalid_primitive_mode
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.tessellation_not_active
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.invalid_program_state
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.get_programiv
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.invalid_program_queries
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.tessellation_control_invalid_vertex_count
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.gen_buffers
@@ -17648,11 +17683,23 @@ dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.shader
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.tessellation_shader
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.texture_buffer
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.texture_cube_map_array
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_directive.accessing_bounding_box_type
+dEQP-GLES31.functional.debug.negative_coverage.get_error.ssbo_block.ssbo_block_interface_matching_tests
+dEQP-GLES31.functional.debug.negative_coverage.get_error.ssbo_block.ssbo_using_shared_qualifier_tests
 dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_variable_name
 dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_function_name
 dEQP-GLES31.functional.debug.negative_coverage.get_error.precise.precise_as_function_argument
 dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.blend_qualifier_mismatch
 dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.attachment_advanced_equation
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_storage.block_number_limits
+dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_storage.max_combined_block_number_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.single_tessellation_stage
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.invalid_primitive_mode
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.tessellation_not_active
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.invalid_program_state
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.get_programiv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.invalid_program_queries
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.tessellation_control_invalid_vertex_count
 dEQP-GLES31.functional.debug.externally_generated.application_messages
 dEQP-GLES31.functional.debug.externally_generated.third_party_messages
 dEQP-GLES31.functional.debug.externally_generated.push_pop_stack
@@ -22658,62 +22705,110 @@ dEQP-GLES31.functional.layout_binding.image.image3d.fragment_binding_array
 dEQP-GLES31.functional.layout_binding.image.image3d.fragment_binding_max_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.vertex_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.fragment_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_control_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_evaluation_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.vertex_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.fragment_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_control_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_evaluation_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.vertex_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.fragment_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_control_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_evaluation_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.vertex_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.fragment_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_control_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.tess_evaluation_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.binding_contradictory
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler2d.binding_contradictory_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.vertex_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.fragment_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_control_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_evaluation_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.vertex_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.fragment_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_control_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_evaluation_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.vertex_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.fragment_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_control_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_evaluation_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.vertex_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.fragment_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_control_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.tess_evaluation_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.binding_contradictory
 dEQP-GLES31.functional.layout_binding.negative.sampler.sampler3d.binding_contradictory_array
 dEQP-GLES31.functional.layout_binding.negative.ubo.vertex_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.ubo.fragment_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_control_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_evaluation_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.ubo.vertex_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.ubo.fragment_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_control_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_evaluation_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.ubo.vertex_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.ubo.fragment_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_control_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_evaluation_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.ubo.vertex_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.ubo.fragment_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_control_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.ubo.tess_evaluation_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.ubo.binding_contradictory
 dEQP-GLES31.functional.layout_binding.negative.ubo.binding_contradictory_array
 dEQP-GLES31.functional.layout_binding.negative.ssbo.vertex_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.ssbo.fragment_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_control_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_evaluation_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.ssbo.vertex_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.ssbo.fragment_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_control_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_evaluation_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.ssbo.vertex_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.ssbo.fragment_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_control_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_evaluation_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.ssbo.vertex_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.ssbo.fragment_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_control_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.ssbo.tess_evaluation_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.ssbo.binding_contradictory
 dEQP-GLES31.functional.layout_binding.negative.ssbo.binding_contradictory_array
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.vertex_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.fragment_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_control_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_evaluation_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.vertex_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.fragment_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_control_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_evaluation_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.vertex_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.fragment_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_control_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_evaluation_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.vertex_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.fragment_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_control_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.image.image2d.tess_evaluation_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.binding_contradictory
 dEQP-GLES31.functional.layout_binding.negative.image.image2d.binding_contradictory_array
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.vertex_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.fragment_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_control_binding_over_max
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_evaluation_binding_over_max
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.vertex_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.fragment_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_control_binding_neg
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_evaluation_binding_neg
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.vertex_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.fragment_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_control_binding_over_max_array
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_evaluation_binding_over_max_array
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.vertex_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.fragment_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_control_binding_neg_array
+dEQP-GLES31.functional.layout_binding.negative.image.image3d.tess_evaluation_binding_neg_array
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.binding_contradictory
 dEQP-GLES31.functional.layout_binding.negative.image.image3d.binding_contradictory_array
 dEQP-GLES31.functional.primitive_bounding_box.state_query.initial_value
@@ -22761,18 +22856,39 @@ dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_pri
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_primitive.vertex_tessellation_fragment.fbo
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_primitive.vertex_tessellation_geometry_fragment.default_framebuffer
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_primitive.vertex_tessellation_geometry_fragment.fbo
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.fbo_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.fbo_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.fbo_bbox_smaller
@@ -22820,18 +22936,39 @@ dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_primit
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_primitive.vertex_tessellation_fragment.fbo
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_primitive.vertex_tessellation_geometry_fragment.default_framebuffer
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_primitive.vertex_tessellation_geometry_fragment.fbo
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.fbo_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.fbo_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.fbo_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.fbo_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.fbo_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.fbo_bbox_smaller
@@ -35413,3 +35550,17 @@ dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffe
 dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.18
 dEQP-GLES31.functional.draw_buffers_indexed.random.max_implementation_draw_buffers.19
 dEQP-GLES31.functional.default_vertex_array_object.vertex_attrib_divisor
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.skipped
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.enabled
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.texel_fetch
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.conversion_gpu
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.toggled
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.multiple_textures
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.srgba8.using_sampler
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.skipped
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.enabled
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.texel_fetch
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.conversion_gpu
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.toggled
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.multiple_textures
+dEQP-GLES31.functional.srgb_texture_decode.skip_decode.sr8.using_sampler
index d78f3f6..721e97b 100644 (file)
@@ -134,6 +134,24 @@ dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_dra
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
@@ -152,6 +170,24 @@ dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.v
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
index 42f000f..c98268f 100644 (file)
@@ -47,6 +47,24 @@ dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_dra
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
@@ -65,6 +83,24 @@ dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.v
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
index 42f000f..c98268f 100644 (file)
@@ -47,6 +47,24 @@ dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_dra
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
@@ -65,6 +83,24 @@ dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.v
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
index 42f000f..c98268f 100644 (file)
@@ -47,6 +47,24 @@ dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_dra
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
@@ -65,6 +83,24 @@ dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.v
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
index 42f000f..c98268f 100644 (file)
@@ -47,6 +47,24 @@ dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_dra
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.triangles.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
@@ -65,6 +83,24 @@ dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.v
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.points.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_fragment.default_framebuffer_bbox_smaller
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_equal
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_larger
+dEQP-GLES31.functional.primitive_bounding_box.wide_lines.tessellation_set_per_draw.vertex_tessellation_geometry_fragment.default_framebuffer_bbox_smaller
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_equal
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_larger
 dEQP-GLES31.functional.primitive_bounding_box.wide_points.global_state.vertex_fragment.default_framebuffer_bbox_smaller
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 9473ba4..5d24d03 100644 (file)
@@ -66,15 +66,6 @@ dEQP-GLES31.functional.shaders.builtin_functions.precision.sin.mediump_*
 dEQP-GLES31.functional.shaders.builtin_functions.precision.cos.mediump_*
 dEQP-GLES31.functional.shaders.builtin_functions.precision.tan.mediump_*
 
-# Bug 22713865
-dEQP-GLES31.functional.primitive_bounding_box.*lines*default_framebuffer_bbox*
-dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.fbo_bbox_equal
-dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.fbo_bbox_larger
-dEQP-GLES31.functional.primitive_bounding_box.lines.global_state.vertex_geometry_fragment.fbo_bbox_smaller
-dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.fbo_bbox_equal
-dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.fbo_bbox_larger
-dEQP-GLES31.functional.primitive_bounding_box.wide_lines.global_state.vertex_geometry_fragment.fbo_bbox_smaller
-
 # Bug 23288315
 dEQP-GLES31.functional.draw_indirect.compute_interop.large.drawelements_separate_grid_1000x1000_drawcount_1
 dEQP-GLES31.functional.draw_indirect.compute_interop.large.drawelements_separate_grid_1200x1200_drawcount_1
index b2602dc..904caca 100644 (file)
@@ -15174,7 +15174,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
@@ -15196,7 +15195,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_different_member_interpolation
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index b2602dc..904caca 100644 (file)
@@ -15174,7 +15174,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
@@ -15196,7 +15195,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_different_member_interpolation
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index 4e6fdba..6b1aef0 100644 (file)
@@ -15875,7 +15875,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
@@ -15897,7 +15896,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_different_member_interpolation
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index 4e6fdba..6b1aef0 100644 (file)
@@ -15875,7 +15875,6 @@ dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_explicit_loca
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_1
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_2
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_implicit_explicit_location_3
-dEQP-GLES31.functional.separate_shader.validation.varying.match_different_struct_names
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.varying.mismatch_struct_member_precision
@@ -15897,7 +15896,6 @@ dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_precision
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_different_member_interpolation
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_array_size
-dEQP-GLES31.functional.separate_shader.validation.io_blocks.match_different_member_struct_names
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_name
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_type
 dEQP-GLES31.functional.separate_shader.validation.io_blocks.mismatch_member_struct_member_precision
index cbcec16..465d2da 100644 (file)
@@ -2116,6 +2116,7 @@ public class DeqpTestRunner implements IBuildReceiver, IDeviceTest,
         destination.mExcludeFilters = new ArrayList<>(source.mExcludeFilters);
         destination.mAbi = source.mAbi;
         destination.mLogData = source.mLogData;
+        destination.mCollectTestsOnly = source.mCollectTestsOnly;
     }
 
     /**
index cfee003..a1cc086 100644 (file)
@@ -24,7 +24,9 @@ import os
 import re
 import sys
 import shutil
+import string
 import argparse
+import time
 
 import common
 
@@ -188,6 +190,51 @@ def dumpConfig ():
                print "%-30s : %s" % (entry[0], entry[1])
        print " "
 
+# Return NDK version as [<major>,<minor>] or None if cannot be figured out.
+def getNdkVersion (path):
+       if path == None:
+               return None
+
+       propFilePath = os.path.join(path, "source.properties")
+       try:
+               with open(propFilePath) as propFile:
+                       for line in propFile:
+                               keyValue = map(lambda x: string.strip(x), line.split("="))
+                               if keyValue[0] == "Pkg.Revision":
+                                       versionParts = keyValue[1].split(".")
+                                       return tuple(map(int, versionParts[0:2]))
+       except:
+               print("Could not read source prop file '%s'" % propFilePath)
+
+       return None
+
+def checkConfig ():
+       HOST_OS_TO_DOWNLOAD_STRING = {
+                       "linux-x86_64"          : "linux-x86_64",
+                       "windows"                       : "windows-x86",
+                       "windows-x86_64"        : "windows-x86_64"
+               }
+
+       version = getNdkVersion(common.ANDROID_NDK_PATH)
+       # Note: NDK currently maintains compatibility between minor
+       # versions. Error out only on major version mismatch.
+       if version == None or version[0] != common.ANDROID_NDK_VERSION[0]:
+               print("**** WARNING! Deqp requires NDK version %s" % common.ANDROID_NDK_VERSION_STRING)
+               print("**** NDK Path %s does not appear to have that version." % common.ANDROID_NDK_PATH)
+
+               # Download hint will use the version encored in common.py, not
+               # the latest minor version available
+               versionString = common.ANDROID_NDK_VERSION_STRING
+               if common.ANDROID_NDK_HOST_OS in HOST_OS_TO_DOWNLOAD_STRING:
+                       osString = HOST_OS_TO_DOWNLOAD_STRING[common.ANDROID_NDK_HOST_OS]
+                       print("**** Please install from https://dl.google.com/android/repository/android-ndk-%s-%s.zip" % (versionString, osString))
+               else:
+                       print("**** Please download version", versionString, "from https://developer.android.com/ndk/downloads/index.html")
+
+               return False
+
+       return True
+
 if __name__ == "__main__":
        nativeBuildTypes = ['Release', 'Debug', 'MinSizeRel', 'RelWithAsserts', 'RelWithDebInfo']
        androidBuildTypes = ['debug', 'release']
@@ -199,10 +246,15 @@ if __name__ == "__main__":
        parser.add_argument('--dump-config', dest='dumpConfig', action='store_true', help="Print out all configurations variables")
        parser.add_argument('--java-api', dest='javaApi', default=common.ANDROID_JAVA_API, help="Set the API signature for the java build.")
        parser.add_argument('-p', '--parallel-build', dest='parallelBuild', action="store_true", help="Build native libraries in parallel.")
+       parser.add_argument('--skip-config-check', dest='skipConfigCheck', action="store_true", default=False, help="Skips config check. Warranty void.")
 
        args = parser.parse_args()
 
        if args.dumpConfig:
                dumpConfig()
 
+       if not args.skipConfigCheck and not checkConfig():
+               print "Config check failed, exit"
+               exit(-1)
+
        build(buildRoot=os.path.abspath(args.buildRoot), androidBuildType=args.androidBuildType, nativeBuildType=args.nativeBuildType, javaApi=args.javaApi, doParallelBuild=args.parallelBuild)
index 16b5276..a158367 100644 (file)
@@ -110,7 +110,7 @@ def execArgs (args):
        if retcode != 0:
                raise Exception("Failed to execute '%s', got %d" % (str(args), retcode))
 
-def execArgsInDirectory (args, cwd, linePrefix=""):
+def execArgsInDirectory (args, cwd, linePrefix="", failOnNonZeroExit=True):
 
        def readApplyPrefixAndPrint (source, prefix, sink):
                while True:
@@ -125,7 +125,7 @@ def execArgsInDirectory (args, cwd, linePrefix=""):
        stdoutJob.start()
        stderrJob.start()
        retcode = process.wait()
-       if retcode != 0:
+       if failOnNonZeroExit and retcode != 0:
                raise Exception("Failed to execute '%s', got %d" % (str(args), retcode))
 
 def serialApply(f, argsList):
@@ -173,7 +173,7 @@ def getDevices (adb):
        if proc.returncode != 0:
                raise Exception("adb devices -l failed, got %d" % proc.returncode)
 
-       ptrn = re.compile(r'^([a-zA-Z0-9:]+)\s+.*product:([^\s]+)\s+model:([^\s]+)\s+device:([^\s]+)')
+       ptrn = re.compile(r'^([a-zA-Z0-9\.:]+)\s+.*product:([^\s]+)\s+model:([^\s]+)\s+device:([^\s]+)')
        devices = []
        for line in stdout.splitlines()[1:]:
                if len(line.strip()) == 0:
@@ -240,10 +240,16 @@ NATIVE_LIBS                               = [
 ANDROID_JAVA_API               = "android-22"
 NATIVE_LIB_NAME                        = "libdeqp.so"
 
+def makeNdkVersionString (version):
+       minorVersionString = (chr(ord('a') + version[1]) if version[1] > 0 else "")
+       return "r%d%s" % (version[0], minorVersionString)
+
+ANDROID_NDK_VERSION                    = (11,0)
+ANDROID_NDK_VERSION_STRING     = makeNdkVersionString(ANDROID_NDK_VERSION)
 def selectNDKPath ():
        candidates =  [
-               os.path.expanduser("~/android-ndk-r11"),
-               "C:/android/android-ndk-r11",
+               os.path.expanduser("~/android-ndk-" + ANDROID_NDK_VERSION_STRING),
+               "C:/android/android-ndk-" + ANDROID_NDK_VERSION_STRING,
                os.environ.get("ANDROID_NDK_PATH", None), # If not defined, return None
        ]
 
index 6c9ff0f..5545cbb 100644 (file)
@@ -33,7 +33,7 @@ def install (buildRoot, extraArgs = [], printPrefix=""):
        common.execArgsInDirectory([common.ADB_BIN] + extraArgs + [
                        'uninstall',
                        'com.drawelements.deqp'
-               ], buildRoot, printPrefix)
+               ], buildRoot, printPrefix, failOnNonZeroExit=False)
        print printPrefix + "Remove complete\n",
 
        print printPrefix + "Installing dEQP Package from %s...\n" %(buildRoot),
index b26dd82..bdb3dc8 100644 (file)
@@ -854,6 +854,61 @@ group varying "Varying linkage"
                        ""
                end
 
+               case output_non_array
+                       version 310 es
+                       desc "Tessellation control output out not an array"
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       expect compile_or_link_fail
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out; // not an array
+                               void main()
+                               {
+                                       tc_out = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
                case input_array_size_mismatch
                        version 310 es
                        desc "Tessellation control input array size is not gl_MaxPatchVertices"
@@ -964,6 +1019,133 @@ group varying "Varying linkage"
                        ""
                end
 
+               case invalid_patch_in_usage
+                       version 310 es
+                       desc "Invalid use of the patch_in qualifier in a non-tessellation shader"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float frag_in;
+                               out mediump float var;
+                               void main()
+                               {
+                                       frag_in = in0;
+                                       var = 2.0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               patch in mediump float var; // invalid use of patch_in
+                               in mediump float frag_in;
+                               void main()
+                               {
+                                       out0 = frag_in * var;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case invalid_patch_out_usage
+                       version 310 es
+                       desc "Invalid use of the patch_out qualifier in a non-tessellation shader"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float frag_in;
+                               patch out mediump float var;
+                               void main()
+                               {
+                                       frag_in = in0;
+                                       var = 2.0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float var; // invalid use of patch_out
+                               in mediump float frag_in;
+                               void main()
+                               {
+                                       out0 = frag_in * var;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case invalid_per_patch_qualifier_usage
+                       version 310 es
+                       desc "Invalid use of per-patch qualifier on input variable in tessellation control shader"
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       expect compile_or_link_fail
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               patch in mediump float tc_in; // patch in not allowed in TCS
+                               patch out mediump float tc_out;
+                               void main()
+                               {
+                                       tc_out = tc_in;
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               patch in mediump float tc_out;
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out;
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
                case per_patch_qualifier_mismatch_1
                        version 310 es
                        desc "Tessellation control output is per-patch qualified, evaluation input is not"
@@ -1133,7 +1315,7 @@ group varying "Varying linkage"
 
                case input_block_non_array
                        version 310 es
-                       desc "Tessellation control shader input block with explicit array"
+                       desc "Tessellation control shader input block without explicit array"
                        require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
                        require extension { "GL_OES_shader_io_blocks" | "GL_EXT_shader_io_blocks" } in { vertex }
                        expect compile_or_link_fail
@@ -1189,6 +1371,64 @@ group varying "Varying linkage"
                        ""
                end
 
+               case output_block_non_array
+                       version 310 es
+                       desc "Tessellation control shader output block without explicit array"
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       require extension { "GL_OES_shader_io_blocks" | "GL_EXT_shader_io_blocks" } in { vertex }
+                       expect compile_or_link_fail
+                       values { output float out0 = 1.0; }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = 1.0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out IOBlockName
+                               {
+                                       mediump float var;
+                               } outputInstanceName; // not an array
+                               void main()
+                               {
+                                       outputInstanceName.var = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in IOBlockName
+                               {
+                                       mediump float var;
+                               } outputInstanceName[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = outputInstanceName[2].var;
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
                case input_block_array_size_mismatch
                        version 310 es
                        desc "Tessellation control shader input block array, size not gl_MaxPatchVertices"
@@ -2151,3 +2391,355 @@ group uniform "Uniform"
 
        import "linkage_tessellation_uniform_types.test"
 end
+
+group layout_declarations "Layout linkage"
+       group rules "Rules"
+
+               case primitive_mode_mismatch
+                       version 310 es
+                       desc "Tessellation evaluation shader primitive mode mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               layout (triangles) in;
+                               layout (isolines) in;
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case spacing_mode_mismatch
+                       version 310 es
+                       desc "Tessellation evaluation shader spacing mode mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               layout (triangles, equal_spacing) in;
+                               layout (triangles, fractional_odd_spacing) in;
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case vertex_order_mismatch
+                       version 310 es
+                       desc "Tessellation evaluation shader vertex order mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               layout (triangles, cw) in;
+                               layout (triangles, ccw) in;
+                                   in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case vertex_count_mismatch
+                       version 310 es
+                       desc "Tessellation control shader vertex count mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               layout (vertices=3) out;
+                               layout (vertices=4) out;
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+       end
+end
+
+group barriers "Barriers"
+       group rules "Rules"
+
+               case invalid_barrier_usage_within_control_flow
+                       version 310 es
+                       desc "Tessellation control shader invalid barrier usage within control flow statement"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+
+                               void main()
+                               {
+                                       if (gl_InvocationID == 0)
+                                               barrier(); // error: within control flow
+
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case invalid_barrier_usage_after_return
+                       version 310 es
+                       desc "Tessellation control shader invalid barrier usage after main() returns"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+
+                                       return;
+                                       barrier(); // error: barrier() after return
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+       end
+end
index b868d9d..d16d6ee 100644 (file)
@@ -327,10 +327,10 @@ group varying "Default block varying matching"
                end
        end
 
-       case match_different_struct_names
+       case mismatch_different_struct_names
                version 310 es
                desc "Variable struct names different but otherwise identical"
-               expect pass
+               expect validation_fail
 
                pipeline_program
                        active_stages {vertex}
@@ -1150,10 +1150,10 @@ group io_blocks "shader io blocks"
                end
        end
 
-       case match_different_member_struct_names
+       case mismatch_different_member_struct_names
                version 310 es
                desc "IO-blocks match with structs with different names"
-               expect pass
+               expect validation_fail
 
                pipeline_program
                        active_stages {vertex}
index 57041bd..ee49459 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 
 eglw::EGLBoolean CallLogWrapper::eglBindAPI (eglw::EGLenum api)
index 69be6e9..99df24b 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 eglw::EGLBoolean                                                               eglBindAPI                                                      (eglw::EGLenum api);
 eglw::EGLBoolean                                                               eglBindTexImage                                         (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint buffer);
index c6d06ad..bd1a5c7 100644 (file)
@@ -25,6 +25,7 @@
 #include "egluUtil.hpp"
 #include "egluConfigInfo.hpp"
 #include "eglwEnums.hpp"
+#include "deSTLUtil.hpp"
 
 #include <algorithm>
 
@@ -55,19 +56,32 @@ int CandidateConfig::get (deUint32 attrib) const
        if (m_type == TYPE_CONFIG_INFO)
                return m_cfg.configInfo->getAttribute(attrib);
        else
-               return getConfigAttribInt(*m_cfg.object.egl, m_cfg.object.display, m_cfg.object.config, attrib);
+       {
+               if (attrib == EGL_COLOR_COMPONENT_TYPE_EXT)
+               {
+                       const std::vector<std::string>  extensions      = getDisplayExtensions(*m_cfg.object.egl, m_cfg.object.display);
+
+                       if (de::contains(extensions.begin(), extensions.end(), "EGL_EXT_pixel_format_float"))
+                               return getConfigAttribInt(*m_cfg.object.egl, m_cfg.object.display, m_cfg.object.config, attrib);
+                       else
+                               return EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
+               }
+               else
+                       return getConfigAttribInt(*m_cfg.object.egl, m_cfg.object.display, m_cfg.object.config, attrib);
+       }
 }
 
-int                    CandidateConfig::id                             (void) const { return get(EGL_CONFIG_ID);                                       }
-int                    CandidateConfig::redSize                (void) const { return get(EGL_RED_SIZE);                                        }
-int                    CandidateConfig::greenSize              (void) const { return get(EGL_GREEN_SIZE);                                      }
-int                    CandidateConfig::blueSize               (void) const { return get(EGL_BLUE_SIZE);                                       }
-int                    CandidateConfig::alphaSize              (void) const { return get(EGL_ALPHA_SIZE);                                      }
-int                    CandidateConfig::depthSize              (void) const { return get(EGL_DEPTH_SIZE);                                      }
-int                    CandidateConfig::stencilSize    (void) const { return get(EGL_STENCIL_SIZE);                            }
-int                    CandidateConfig::samples                (void) const { return get(EGL_SAMPLES);                                         }
-deUint32       CandidateConfig::renderableType (void) const { return (deUint32)get(EGL_RENDERABLE_TYPE);       }
-deUint32       CandidateConfig::surfaceType    (void) const { return (deUint32)get(EGL_SURFACE_TYPE);          }
+int                    CandidateConfig::id                                     (void) const { return get(EGL_CONFIG_ID);                                                       }
+int                    CandidateConfig::redSize                        (void) const { return get(EGL_RED_SIZE);                                                        }
+int                    CandidateConfig::greenSize                      (void) const { return get(EGL_GREEN_SIZE);                                                      }
+int                    CandidateConfig::blueSize                       (void) const { return get(EGL_BLUE_SIZE);                                                       }
+int                    CandidateConfig::alphaSize                      (void) const { return get(EGL_ALPHA_SIZE);                                                      }
+int                    CandidateConfig::depthSize                      (void) const { return get(EGL_DEPTH_SIZE);                                                      }
+int                    CandidateConfig::stencilSize            (void) const { return get(EGL_STENCIL_SIZE);                                            }
+int                    CandidateConfig::samples                        (void) const { return get(EGL_SAMPLES);                                                         }
+deUint32       CandidateConfig::renderableType         (void) const { return (deUint32)get(EGL_RENDERABLE_TYPE);                       }
+deUint32       CandidateConfig::surfaceType            (void) const { return (deUint32)get(EGL_SURFACE_TYPE);                          }
+deUint32       CandidateConfig::colorComponentType     (void) const { return (deUint32)get(EGL_COLOR_COMPONENT_TYPE_EXT);      }
 
 FilterList& FilterList::operator<< (ConfigFilter filter)
 {
index 2f316fe..baddad5 100644 (file)
@@ -59,6 +59,7 @@ public:
 
        deUint32                renderableType          (void) const;
        deUint32                surfaceType                     (void) const;
+       deUint32                colorComponentType      (void) const;
 
        tcu::RGBA               colorBits                       (void) const { return tcu::RGBA(redSize(), greenSize(), blueSize(), alphaSize());       }
 
index aed08f3..ab6081c 100644 (file)
@@ -77,6 +77,9 @@ deInt32 ConfigInfo::getAttribute (deUint32 attribute) const
                case EGL_YUV_CSC_STANDARD_EXT:          return yuvCscStandard;
                case EGL_YUV_PLANE_BPP_EXT:                     return yuvPlaneBpp;
 
+               // EGL_EXT_pixel_format_float
+               case EGL_COLOR_COMPONENT_TYPE_EXT:      return colorComponentType;
+
                default:                                                        TCU_THROW(InternalError, "Unknown attribute");
        }
 }
@@ -132,6 +135,15 @@ void queryExtConfigInfo (const eglw::Library& egl, eglw::EGLDisplay display, egl
 
                EGLU_CHECK_MSG(egl, "Failed to query EGL_EXT_yuv_surface config attribs");
        }
+
+       if (de::contains(extensions.begin(), extensions.end(), "EGL_EXT_pixel_format_float"))
+       {
+               egl.getConfigAttrib(display, config, EGL_COLOR_COMPONENT_TYPE_EXT,      (EGLint*)&dst->colorComponentType);
+
+               EGLU_CHECK_MSG(egl, "Failed to query EGL_EXT_pixel_format_float config attribs");
+       }
+       else
+               dst->colorComponentType = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT;
 }
 
 } // eglu
index 356c50a..2c0ae24 100644 (file)
@@ -81,6 +81,9 @@ public:
        deUint32                yuvCscStandard;
        deInt32                 yuvPlaneBpp;
 
+       // EGL_EXT_pixel_format_float
+       deUint32                colorComponentType;
+
        ConfigInfo (void)
                : bufferSize                    (0)
                , redSize                               (0)
@@ -119,6 +122,7 @@ public:
                , yuvDepthRange                 (EGL_NONE)
                , yuvCscStandard                (EGL_NONE)
                , yuvPlaneBpp                   (EGL_YUV_PLANE_BPP_0_EXT)
+               , colorComponentType    (EGL_NONE)
        {
        }
 
index 297a00c..2c563e5 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 
 const char* getBooleanName (int value)
@@ -104,6 +104,7 @@ const char* getConfigAttribName (int value)
                case EGL_TRANSPARENT_RED_VALUE:         return "EGL_TRANSPARENT_RED_VALUE";
                case EGL_TRANSPARENT_GREEN_VALUE:       return "EGL_TRANSPARENT_GREEN_VALUE";
                case EGL_TRANSPARENT_BLUE_VALUE:        return "EGL_TRANSPARENT_BLUE_VALUE";
+               case EGL_COLOR_COMPONENT_TYPE_EXT:      return "EGL_COLOR_COMPONENT_TYPE_EXT";
                default:                                                        return DE_NULL;
        }
 }
@@ -159,6 +160,16 @@ const char* getYuvPlaneBppName (int value)
        }
 }
 
+const char* getColorComponentTypeName (int value)
+{
+       switch (value)
+       {
+               case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT:        return "EGL_COLOR_COMPONENT_TYPE_FIXED_EXT";
+               case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT:        return "EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT";
+               default:                                                                        return DE_NULL;
+       }
+}
+
 const char* getSurfaceTargetName (int value)
 {
        switch (value)
index fc2093f..839837f 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 const char*                                                    getBooleanName                          (int value);
 const char*                                                    getBoolDontCareName                     (int value);
@@ -12,6 +12,7 @@ const char*                                                   getConfigAttribName                     (int value);
 const char*                                                    getSurfaceAttribName            (int value);
 const char*                                                    getYuvOrderName                         (int value);
 const char*                                                    getYuvPlaneBppName                      (int value);
+const char*                                                    getColorComponentTypeName       (int value);
 const char*                                                    getSurfaceTargetName            (int value);
 const char*                                                    getColorBufferTypeName          (int value);
 const char*                                                    getConfigCaveatName                     (int value);
@@ -34,6 +35,7 @@ inline tcu::Format::Enum<int, 2>      getConfigAttribStr                      (int value)             { return tcu:
 inline tcu::Format::Enum<int, 2>       getSurfaceAttribStr                     (int value)             { return tcu::Format::Enum<int, 2>(getSurfaceAttribName, value); }
 inline tcu::Format::Enum<int, 2>       getYuvOrderStr                          (int value)             { return tcu::Format::Enum<int, 2>(getYuvOrderName, value); }
 inline tcu::Format::Enum<int, 2>       getYuvPlaneBppStr                       (int value)             { return tcu::Format::Enum<int, 2>(getYuvPlaneBppName, value); }
+inline tcu::Format::Enum<int, 2>       getColorComponentTypeStr        (int value)             { return tcu::Format::Enum<int, 2>(getColorComponentTypeName, value); }
 inline tcu::Format::Enum<int, 2>       getSurfaceTargetStr                     (int value)             { return tcu::Format::Enum<int, 2>(getSurfaceTargetName, value); }
 inline tcu::Format::Enum<int, 2>       getColorBufferTypeStr           (int value)             { return tcu::Format::Enum<int, 2>(getColorBufferTypeName, value); }
 inline tcu::Format::Enum<int, 2>       getConfigCaveatStr                      (int value)             { return tcu::Format::Enum<int, 2>(getConfigCaveatName, value); }
index bfa267d..edb58c5 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 #define EGL_PBUFFER_BIT                                                                                0x0001
 #define EGL_PIXMAP_BIT                                                                         0x0002
 #define EGL_YUV_PLANE_BPP_0_EXT                                                                0x331B
 #define EGL_YUV_PLANE_BPP_8_EXT                                                                0x331C
 #define EGL_YUV_PLANE_BPP_10_EXT                                                       0x331D
+#define EGL_COLOR_COMPONENT_TYPE_EXT                                           0x3339
+#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT                                     0x333A
+#define EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT                                     0x333B
index 353b6b2..e7d1327 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 EGLBoolean                                                                     bindAPI                                                 (EGLenum api) const;
 EGLBoolean                                                                     bindTexImage                                    (EGLDisplay dpy, EGLSurface surface, EGLint buffer) const;
index c1140a7..1678c71 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 
 EGLBoolean FuncPtrLibrary::bindAPI (EGLenum api) const
index b66bdfd..d57105e 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 typedef EGLW_APICALL EGLBoolean                                                                        (EGLW_APIENTRY* eglBindAPIFunc)                                                 (EGLenum api);
 typedef EGLW_APICALL EGLBoolean                                                                        (EGLW_APIENTRY* eglBindTexImageFunc)                                    (EGLDisplay dpy, EGLSurface surface, EGLint buffer);
index 3f0ce29..af0d1b2 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 eglBindAPIFunc                                                 bindAPI;
 eglBindTexImageFunc                                            bindTexImage;
index b09f990..15f941d 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 dst->bindAPI                                           = (eglBindAPIFunc)                                                      loader->get("eglBindAPI");
 dst->bindTexImage                                      = (eglBindTexImageFunc)                                         loader->get("eglBindTexImage");
index 7ea82e4..90d00a1 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 dst->clientWaitSyncKHR                         = (eglClientWaitSyncKHRFunc)                            loader->get("eglClientWaitSyncKHR");
 dst->createImageKHR                                    = (eglCreateImageKHRFunc)                                       loader->get("eglCreateImageKHR");
index a9a42c8..a3d617d 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 virtual EGLBoolean                                                                     bindAPI                                                 (EGLenum api) const                                                                                                                                                                                             = 0;
 virtual EGLBoolean                                                                     bindTexImage                                    (EGLDisplay dpy, EGLSurface surface, EGLint buffer) const                                                                                                               = 0;
index d2d5ca0..22a2c5c 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
        { "eglBindAPI",                                                 (deFunctionPtr)eglBindAPI },
        { "eglBindTexImage",                                    (deFunctionPtr)eglBindTexImage },
index c9fafeb..a44c589 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
        { "eglBindAPI",                                                 (deFunctionPtr)eglBindAPI },
        { "eglBindTexImage",                                    (deFunctionPtr)eglBindTexImage },
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 75a3385..5e8005b 100644 (file)
@@ -34,6 +34,14 @@ if (de::contains(extSet, "GL_EXT_geometry_shader"))
        gl->framebufferTexture  = (glFramebufferTextureFunc)    loader->get("glFramebufferTextureEXT");
 }
 
+if (de::contains(extSet, "GL_EXT_robustness"))
+{
+       gl->getGraphicsResetStatus      = (glGetGraphicsResetStatusFunc)        loader->get("glGetGraphicsResetStatusEXT");
+       gl->getnUniformfv                       = (glGetnUniformfvFunc)                         loader->get("glGetnUniformfvEXT");
+       gl->getnUniformiv                       = (glGetnUniformivFunc)                         loader->get("glGetnUniformivEXT");
+       gl->readnPixels                         = (glReadnPixelsFunc)                           loader->get("glReadnPixelsEXT");
+}
+
 if (de::contains(extSet, "GL_EXT_texture_buffer"))
 {
        gl->texBuffer           = (glTexBufferFunc)                     loader->get("glTexBufferEXT");
index ee24d13..75f55c7 100644 (file)
@@ -86,6 +86,20 @@ XlibDisplay::~XlibDisplay (void)
        XCloseDisplay(m_display);
 }
 
+void XlibDisplay::processEvent (XEvent& event)
+{
+       switch (event.type)
+       {
+               case ClientMessage:
+                       if ((unsigned)event.xclient.data.l[0] == m_deleteAtom)
+                               m_eventState.setQuitFlag(true);
+                       break;
+               // note: ConfigureNotify for window is handled in setDimensions()
+               default:
+                       break;
+       }
+}
+
 void XlibDisplay::processEvents (void)
 {
        XEvent  event;
@@ -93,10 +107,7 @@ void XlibDisplay::processEvents (void)
        while (XPending(m_display))
        {
                XNextEvent(m_display, &event);
-
-               // \todo [2010-10-27 pyry] Handle ConfigureNotify?
-               if (event.type == ClientMessage && (unsigned)event.xclient.data.l[0] == m_deleteAtom)
-                       m_eventState.setQuitFlag(true);
+               processEvent(event);
        }
 }
 
@@ -211,7 +222,7 @@ void XlibWindow::setVisibility (bool visible)
 
        do
        {
-               XNextEvent(dpy, &event);
+               XWindowEvent(dpy, m_window, ExposureMask | StructureNotifyMask, &event);
        } while (event.type != eventType);
 
        m_visible = visible;
@@ -244,8 +255,13 @@ void XlibWindow::setDimensions (int width, int height)
        for(;;)
        {
                XNextEvent(dpy, &myevent);
-               if (myevent.type == ConfigureNotify)
-                       break;
+               if (myevent.type == ConfigureNotify) {
+                       XConfigureEvent e = myevent.xconfigure;
+                       if (e.width == width && e.height == height)
+                               break;
+               }
+               else
+                       m_display.processEvent(myevent);
        }
 }
 
index 02a731b..ac2fd02 100644 (file)
@@ -109,6 +109,7 @@ public:
        ::Visual*               getVisual               (VisualID visualID);
        bool                    getVisualInfo   (VisualID visualID, XVisualInfo& dst);
        void                    processEvents   (void);
+       void                    processEvent    (XEvent& event);
 
 protected:
        ::Display*              m_display;
index 830a463..74c161c 100644 (file)
@@ -89,5 +89,13 @@ X11Platform::X11Platform (void)
 
 tcu::Platform* createPlatform (void)
 {
+       // From man:XinitThreads(3):
+       //
+       //     The XInitThreads function initializes Xlib support for concurrent
+       //     threads.  This function must be the first Xlib function
+       //     a multi-threaded program calls, and it must complete before any other
+       //     Xlib call is made.
+       DE_CHECK_RUNTIME_ERR(XInitThreads() != 0);
+
        return new tcu::x11::X11Platform();
 }
index a191391..6772b48 100644 (file)
@@ -21,6 +21,8 @@ set(DEQP_EGL_SRCS
        teglConfigList.hpp
        teglCreateContextTests.cpp
        teglCreateContextTests.hpp
+       teglGetFrameTimestampsTests.cpp
+       teglGetFrameTimestampsTests.hpp
        teglQueryContextTests.cpp
        teglQueryContextTests.hpp
        teglCreateSurfaceTests.cpp
@@ -97,6 +99,8 @@ set(DEQP_EGL_SRCS
        teglMultiContextTests.cpp
        teglThreadCleanUpTests.hpp
        teglThreadCleanUpTests.cpp
+       teglRobustnessTests.hpp
+       teglRobustnessTests.cpp
        )
 
 set(DEQP_EGL_LIBS
index 50a2769..aab0156 100644 (file)
@@ -142,6 +142,17 @@ private:
                }
        }
 
+       static int getColorComponentTypeRank (EGLenum compType)
+       {
+               switch (compType)
+               {
+                       case EGL_COLOR_COMPONENT_TYPE_FIXED_EXT:        return 0;
+                       case EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT:        return 1;
+                       default:
+                               TCU_THROW(TestError, (std::string("Unknown color component type: ") + eglu::getColorComponentTypeStr(compType).toString()).c_str());
+               }
+       }
+
        typedef bool (*CompareFunc) (const SurfaceConfig& a, const SurfaceConfig& b);
 
        static bool compareCaveat (const SurfaceConfig& a, const SurfaceConfig& b)
@@ -159,6 +170,11 @@ private:
                return getYuvOrderRank((EGLenum)a.m_info.yuvOrder) < getYuvOrderRank((EGLenum)b.m_info.yuvOrder);
        }
 
+       static bool compareColorComponentType (const SurfaceConfig& a, const SurfaceConfig& b)
+       {
+               return getColorComponentTypeRank((EGLenum)a.m_info.colorComponentType) < getColorComponentTypeRank((EGLenum)b.m_info.colorComponentType);
+       }
+
        static bool compareColorBufferBits (const SurfaceConfig& a, const SurfaceConfig& b, const tcu::BVec4& specifiedRGBColors, const tcu::BVec2& specifiedLuminanceColors, bool yuvPlaneBppSpecified)
        {
                DE_ASSERT(a.m_info.colorBufferType == b.m_info.colorBufferType);
@@ -229,6 +245,7 @@ public:
                {
                        SurfaceConfig::compareCaveat,
                        SurfaceConfig::compareColorBufferType,
+                       SurfaceConfig::compareColorComponentType,
                        DE_NULL, // SurfaceConfig::compareColorBufferBits,
                        SurfaceConfig::compareAttributeSmaller<EGL_BUFFER_SIZE>,
                        SurfaceConfig::compareAttributeSmaller<EGL_SAMPLE_BUFFERS>,
@@ -307,6 +324,9 @@ public:
                rules[EGL_YUV_CSC_STANDARD_EXT]         = AttribRule(EGL_YUV_CSC_STANDARD_EXT,          EGL_DONT_CARE,          CRITERIA_EXACT,         SORTORDER_NONE);
                rules[EGL_YUV_PLANE_BPP_EXT]            = AttribRule(EGL_YUV_PLANE_BPP_EXT,                     EGL_DONT_CARE,          CRITERIA_AT_LEAST,      SORTORDER_SPECIAL);     //      3
 
+               // EGL_EXT_pixel_format_float
+               rules[EGL_COLOR_COMPONENT_TYPE_EXT]     = AttribRule(EGL_COLOR_COMPONENT_TYPE_EXT,      EGL_COLOR_COMPONENT_TYPE_FIXED_EXT,             CRITERIA_EXACT,         SORTORDER_SPECIAL);     //      2
+
                return rules;
        }
 private:
index 69fc87c..b42b333 100644 (file)
@@ -30,6 +30,8 @@
 #include "eglwEnums.hpp"
 #include "deRandom.hpp"
 #include "deStringUtil.hpp"
+#include "deUniquePtr.hpp"
+#include "deSTLUtil.hpp"
 
 #include <vector>
 #include <algorithm>
@@ -469,6 +471,42 @@ private:
        int                                     m_iterNdx;
 };
 
+class ColorComponentTypeCase : public ChooseConfigCase
+{
+
+public:
+       ColorComponentTypeCase (EglTestContext& eglTestCtx, const char* name, EGLenum value)
+               : ChooseConfigCase      (eglTestCtx, name, "", true /* sorting order is validated */)
+               , m_value                       (value)
+       {
+       }
+
+       TestCase::IterateResult iterate (void)
+       {
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+
+               {
+                       const std::vector<std::string>  extensions      = eglu::getDisplayExtensions(m_eglTestCtx.getLibrary(), m_display);
+
+                       if (!de::contains(extensions.begin(), extensions.end(), "EGL_EXT_pixel_format_float"))
+                               TCU_THROW(NotSupportedError, "EGL_EXT_pixel_format_float is not supported");
+               }
+
+               {
+                       std::vector<std::pair<EGLenum, EGLint> > attributes;
+
+                       attributes.push_back(std::pair<EGLenum, EGLint>(EGL_COLOR_COMPONENT_TYPE_EXT, m_value));
+                       fillDontCare(attributes);
+
+                       executeTest(attributes, m_checkOrder);
+               }
+
+               return STOP;
+       }
+private:
+       const EGLenum   m_value;
+};
+
 ChooseConfigTests::ChooseConfigTests (EglTestContext& eglTestCtx)
        : TestCaseGroup(eglTestCtx, "choose_config", "eglChooseConfig() tests")
 {
@@ -631,6 +669,17 @@ void ChooseConfigTests::init (void)
                };
                randomGroup->addChild(new ChooseConfigRandomCase(m_eglTestCtx, "all", "All attributes", toSet(allAttribs)));
        }
+
+       // EGL_EXT_pixel_format_float
+       {
+               de::MovePtr<tcu::TestCaseGroup> colorComponentTypeGroup (new tcu::TestCaseGroup(m_testCtx, "color_component_type_ext", "EGL_EXT_pixel_format_float tests"));
+
+               colorComponentTypeGroup->addChild(new ColorComponentTypeCase(m_eglTestCtx, "dont_care", EGL_DONT_CARE));
+               colorComponentTypeGroup->addChild(new ColorComponentTypeCase(m_eglTestCtx, "fixed",             EGL_COLOR_COMPONENT_TYPE_FIXED_EXT));
+               colorComponentTypeGroup->addChild(new ColorComponentTypeCase(m_eglTestCtx, "float",             EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT));
+
+               addChild(colorComponentTypeGroup.release());
+       }
 }
 
 } // egl
index 81e0c38..b107d67 100644 (file)
 #include "teglSimpleConfigCase.hpp"
 #include "egluStrUtil.hpp"
 #include "egluUtil.hpp"
+#include "egluUnique.hpp"
 #include "eglwLibrary.hpp"
 #include "eglwEnums.hpp"
 #include "tcuTestLog.hpp"
+#include "deSTLUtil.hpp"
 
 namespace deqp
 {
@@ -38,6 +40,25 @@ using std::vector;
 using tcu::TestLog;
 using namespace eglw;
 
+static const EGLint s_es1Attrs[] = { EGL_CONTEXT_CLIENT_VERSION,       1, EGL_NONE };
+static const EGLint s_es2Attrs[] = { EGL_CONTEXT_CLIENT_VERSION,       2, EGL_NONE };
+static const EGLint s_es3Attrs[] = { EGL_CONTEXT_MAJOR_VERSION_KHR,    3, EGL_NONE };
+
+static const struct
+{
+       const char*             name;
+       EGLenum                 api;
+       EGLint                  apiBit;
+       const EGLint*   ctxAttrs;
+} s_apis[] =
+{
+       { "OpenGL",                     EGL_OPENGL_API,         EGL_OPENGL_BIT,                 DE_NULL         },
+       { "OpenGL ES 1",        EGL_OPENGL_ES_API,      EGL_OPENGL_ES_BIT,              s_es1Attrs      },
+       { "OpenGL ES 2",        EGL_OPENGL_ES_API,      EGL_OPENGL_ES2_BIT,             s_es2Attrs      },
+       { "OpenGL ES 3",        EGL_OPENGL_ES_API,      EGL_OPENGL_ES3_BIT_KHR, s_es3Attrs      },
+       { "OpenVG",                     EGL_OPENVG_API,         EGL_OPENVG_BIT,                 DE_NULL         }
+};
+
 class CreateContextCase : public SimpleConfigCase
 {
 public:
@@ -63,36 +84,17 @@ void CreateContextCase::executeForConfig (EGLDisplay display, EGLConfig config)
        EGLint                  id              = eglu::getConfigAttribInt(egl, display, config, EGL_CONFIG_ID);
        EGLint                  apiBits = eglu::getConfigAttribInt(egl, display, config, EGL_RENDERABLE_TYPE);
 
-       static const EGLint es1Attrs[] = { EGL_CONTEXT_CLIENT_VERSION,          1, EGL_NONE };
-       static const EGLint es2Attrs[] = { EGL_CONTEXT_CLIENT_VERSION,          2, EGL_NONE };
-       static const EGLint es3Attrs[] = { EGL_CONTEXT_MAJOR_VERSION_KHR,       3, EGL_NONE };
-
-       static const struct
+       for (int apiNdx = 0; apiNdx < (int)DE_LENGTH_OF_ARRAY(s_apis); apiNdx++)
        {
-               const char*             name;
-               EGLenum                 api;
-               EGLint                  apiBit;
-               const EGLint*   ctxAttrs;
-       } apis[] =
-       {
-               { "OpenGL",                     EGL_OPENGL_API,         EGL_OPENGL_BIT,                 DE_NULL         },
-               { "OpenGL ES 1",        EGL_OPENGL_ES_API,      EGL_OPENGL_ES_BIT,              es1Attrs        },
-               { "OpenGL ES 2",        EGL_OPENGL_ES_API,      EGL_OPENGL_ES2_BIT,             es2Attrs        },
-               { "OpenGL ES 3",        EGL_OPENGL_ES_API,      EGL_OPENGL_ES3_BIT_KHR, es3Attrs        },
-               { "OpenVG",                     EGL_OPENVG_API,         EGL_OPENVG_BIT,                 DE_NULL         }
-       };
-
-       for (int apiNdx = 0; apiNdx < (int)DE_LENGTH_OF_ARRAY(apis); apiNdx++)
-       {
-               if ((apiBits & apis[apiNdx].apiBit) == 0)
+               if ((apiBits & s_apis[apiNdx].apiBit) == 0)
                        continue; // Not supported API
 
-               log << TestLog::Message << "Creating " << apis[apiNdx].name << " context with config ID " << id << TestLog::EndMessage;
+               log << TestLog::Message << "Creating " << s_apis[apiNdx].name << " context with config ID " << id << TestLog::EndMessage;
                EGLU_CHECK_MSG(egl, "init");
 
-               EGLU_CHECK_CALL(egl, bindAPI(apis[apiNdx].api));
+               EGLU_CHECK_CALL(egl, bindAPI(s_apis[apiNdx].api));
 
-               EGLContext      context = egl.createContext(display, config, EGL_NO_CONTEXT, apis[apiNdx].ctxAttrs);
+               EGLContext      context = egl.createContext(display, config, EGL_NO_CONTEXT, s_apis[apiNdx].ctxAttrs);
                EGLenum         err             = egl.getError();
 
                if (context == EGL_NO_CONTEXT || err != EGL_SUCCESS)
@@ -109,6 +111,57 @@ void CreateContextCase::executeForConfig (EGLDisplay display, EGLConfig config)
        }
 }
 
+class CreateContextNoConfigCase : public TestCase
+{
+public:
+       CreateContextNoConfigCase (EglTestContext& eglTestCtx)
+               : TestCase(eglTestCtx, "no_config", "EGL_KHR_no_config_context")
+       {
+       }
+
+       IterateResult iterate (void)
+       {
+               const eglw::Library&            egl             = m_eglTestCtx.getLibrary();
+               const eglu::UniqueDisplay       display (egl, eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay(), DE_NULL));
+               tcu::TestLog&                           log             = m_testCtx.getLog();
+
+               if (!eglu::hasExtension(egl, *display, "EGL_KHR_no_config_context"))
+                       TCU_THROW(NotSupportedError, "EGL_KHR_no_config_context is not supported");
+
+               m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "pass");
+
+               for (int apiNdx = 0; apiNdx < (int)DE_LENGTH_OF_ARRAY(s_apis); apiNdx++)
+               {
+                       const EGLenum   api             = s_apis[apiNdx].api;
+
+                       if (egl.bindAPI(api) == EGL_FALSE)
+                       {
+                               TCU_CHECK(egl.getError() == EGL_BAD_PARAMETER);
+                               log << TestLog::Message << "eglBindAPI(" << eglu::getAPIStr(api) << ") failed, skipping" << TestLog::EndMessage;
+                               continue;
+                       }
+
+                       log << TestLog::Message << "Creating " << s_apis[apiNdx].name << " context" << TestLog::EndMessage;
+
+                       const EGLContext        context = egl.createContext(*display, (EGLConfig)0, EGL_NO_CONTEXT, s_apis[apiNdx].ctxAttrs);
+                       const EGLenum           err             = egl.getError();
+
+                       if (context == EGL_NO_CONTEXT || err != EGL_SUCCESS)
+                       {
+                               log << TestLog::Message << "  Fail, context: " << tcu::toHex(context) << ", error: " << eglu::getErrorName(err) << TestLog::EndMessage;
+                               m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to create context");
+                       }
+                       else
+                       {
+                               // Destroy
+                               EGLU_CHECK_CALL(egl, destroyContext(*display, context));
+                               log << TestLog::Message << "  Pass" << TestLog::EndMessage;
+                       }
+               }
+
+               return STOP;
+       }
+};
 
 CreateContextTests::CreateContextTests (EglTestContext& eglTestCtx)
        : TestCaseGroup(eglTestCtx, "create_context", "Basic eglCreateContext() tests")
@@ -126,6 +179,8 @@ void CreateContextTests::init (void)
 
        for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
                addChild(new CreateContextCase(m_eglTestCtx, i->getName(), i->getDescription(), *i));
+
+       addChild(new CreateContextNoConfigCase(m_eglTestCtx));
 }
 
 } // egl
diff --git a/modules/egl/teglGetFrameTimestampsTests.cpp b/modules/egl/teglGetFrameTimestampsTests.cpp
new file mode 100644 (file)
index 0000000..7c70fdc
--- /dev/null
@@ -0,0 +1,717 @@
+/*-------------------------------------------------------------------------
+ * 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 Test the EGL_ANDROID_get_frame_timestamps extension.
+ *//*--------------------------------------------------------------------*/
+
+#include "teglGetFrameTimestampsTests.hpp"
+
+#include "teglSimpleConfigCase.hpp"
+
+#include "egluNativeWindow.hpp"
+#include "egluUtil.hpp"
+#include "egluUnique.hpp"
+#include "eglwLibrary.hpp"
+#include "eglwEnums.hpp"
+
+#include "gluDefs.hpp"
+#include "glwEnums.hpp"
+#include "glwFunctions.hpp"
+
+#include "tcuResultCollector.hpp"
+#include "tcuTestLog.hpp"
+#include "tcuSurface.hpp"
+#include "tcuTexture.hpp"
+#include "tcuTextureUtil.hpp"
+#include "tcuImageCompare.hpp"
+#include "tcuVector.hpp"
+#include "tcuVectorUtil.hpp"
+
+#include "deClock.h"
+#include "deMath.h"
+#include "deUniquePtr.hpp"
+#include "deThread.hpp"
+
+#include <algorithm>
+#include <string>
+#include <vector>
+#include <sstream>
+
+// Tentative EGL header definitions for EGL_ANDROID_get_Frame_timestamps.
+// \todo [2017-01-25 brianderson] Remove once defined in the official headers.
+#define EGL_TIMESTAMPS_ANDROID 0x314D
+#define EGL_COMPOSITE_DEADLINE_ANDROID 0x314E
+#define EGL_COMPOSITE_INTERVAL_ANDROID 0x314F
+#define EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID 0x3150
+#define EGL_REQUESTED_PRESENT_TIME_ANDROID 0x3151
+#define EGL_RENDERING_COMPLETE_TIME_ANDROID 0x3152
+#define EGL_COMPOSITION_LATCH_TIME_ANDROID 0x3153
+#define EGL_FIRST_COMPOSITION_START_TIME_ANDROID 0x3154
+#define EGL_LAST_COMPOSITION_START_TIME_ANDROID 0x3155
+#define EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID 0x3156
+#define EGL_DISPLAY_PRESENT_TIME_ANDROID 0x3157
+#define EGL_DEQUEUE_READY_TIME_ANDROID 0x3158
+#define EGL_READS_DONE_TIME_ANDROID 0x3159
+typedef deInt64 EGLnsecsANDROID;
+typedef deUint64 EGLuint64KHR;
+typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetNextFrameIdANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, EGLuint64KHR *frameId);
+typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetCompositorTimingANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint numTimestamps, const eglw::EGLint *names, EGLnsecsANDROID *values);
+typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetCompositorTimingSupportedANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint name);
+typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetFrameTimestampsANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, EGLuint64KHR frameId, eglw::EGLint numTimestamps, const eglw::EGLint *timestamps, EGLnsecsANDROID *values);
+typedef EGLW_APICALL eglw::EGLBoolean (EGLW_APIENTRY* eglGetFrameTimestampSupportedANDROIDFunc) (eglw::EGLDisplay dpy, eglw::EGLSurface surface, eglw::EGLint timestamp);
+
+#define CHECK_NAKED_EGL_CALL(EGLW, CALL)       do { CALL; eglu::checkError((EGLW).getError(), #CALL, __FILE__, __LINE__); } while (deGetFalse())
+
+namespace deqp
+{
+namespace egl
+{
+
+using tcu::TestLog;
+using std::string;
+using std::vector;
+using namespace eglw;
+
+namespace
+{
+
+// Careful: This has microsecond precision, which can cause timestamps to
+// appear non monotonic when compared to the nanosecond precision timestamps
+// we get from the eglGetFrameTimestamps extension.
+// Current test expectations only make sure microsecond precision timestamps
+// are less than the nanosecond precision timestamps, so this is okay.
+EGLnsecsANDROID getNanoseconds (void)
+{
+       return deGetMicroseconds() * 1000;
+}
+
+struct FrameTimes
+{
+       FrameTimes (void)
+               : frameId                                               (-1)
+               , swapBufferBeginNs                             (-1)
+               , compositeDeadline                             (-1)
+               , compositeInterval                             (-1)
+               , compositeToPresentLatency             (-1)
+               , requestedPresent                              (-1)
+               , latch                                                 (-1)
+               , firstCompositionStart                 (-1)
+               , lastCompositionStart                  (-1)
+               , dequeueReady                                  (-1)
+               , renderingComplete                             (-1)
+               , firstCompositionGpuFinished   (-1)
+               , displayPresent                                (-1)
+               , readsDone                                             (-1)
+       {
+       }
+
+       EGLuint64KHR    frameId;
+
+       // Timestamps sampled by the test.
+       EGLnsecsANDROID swapBufferBeginNs;
+
+       // Compositor info.
+       EGLnsecsANDROID compositeDeadline;
+       EGLnsecsANDROID compositeInterval;
+       EGLnsecsANDROID compositeToPresentLatency;
+
+       // CPU Timeline.
+       EGLnsecsANDROID requestedPresent;
+       EGLnsecsANDROID latch;
+       EGLnsecsANDROID firstCompositionStart;
+       EGLnsecsANDROID lastCompositionStart;
+       EGLnsecsANDROID dequeueReady;
+
+       // GPU Timeline.
+       EGLnsecsANDROID renderingComplete;
+       EGLnsecsANDROID firstCompositionGpuFinished;
+       EGLnsecsANDROID displayPresent;
+       EGLnsecsANDROID readsDone;
+};
+
+bool timestampExists (EGLnsecsANDROID timestamp)
+{
+       return timestamp > 0;
+}
+
+void verifySingleFrame (const FrameTimes& frameTimes, tcu::ResultCollector& result, bool verifyReadsDone)
+{
+       // Verify CPU timeline is monotonic.
+       result.check(frameTimes.swapBufferBeginNs < frameTimes.latch, "Buffer latched before it was swapped.");
+       result.check(frameTimes.latch < frameTimes.firstCompositionStart, "Buffer composited before it was latched.");
+       result.check(frameTimes.firstCompositionStart <= frameTimes.lastCompositionStart, "First composition start after last composition start.");
+       result.check(frameTimes.lastCompositionStart < frameTimes.dequeueReady, "Buffer composited after it was ready to be dequeued.");
+
+       // Verify GPU timeline is monotonic.
+       if (timestampExists(frameTimes.firstCompositionGpuFinished))
+               result.check(frameTimes.renderingComplete < frameTimes.firstCompositionGpuFinished, "Buffer rendering completed after compositor GPU work finished.");
+
+       if (timestampExists(frameTimes.displayPresent))
+               result.check(frameTimes.renderingComplete < frameTimes.displayPresent, "Buffer displayed before rendering completed.");
+
+       if (timestampExists(frameTimes.firstCompositionGpuFinished) && timestampExists(frameTimes.displayPresent))
+               result.check(frameTimes.firstCompositionGpuFinished < frameTimes.displayPresent, "Buffer displayed before compositor GPU work completed");
+
+       // Drivers may maintain shadow copies of the buffer, so the readsDone time
+       // of the real buffer may be earlier than apparent dependencies. We can only
+       // be sure that the readsDone time must be after the renderingComplete time.
+       if (verifyReadsDone)
+               result.check(frameTimes.renderingComplete < frameTimes.readsDone, "Buffer rendering completed after reads completed.");
+
+       // Verify CPU/GPU dependencies
+       result.check(frameTimes.renderingComplete < frameTimes.latch, "Buffer latched before rendering completed.");
+       if (timestampExists(frameTimes.firstCompositionGpuFinished))
+               result.check(frameTimes.firstCompositionStart < frameTimes.firstCompositionGpuFinished, "Composition CPU work started after GPU work finished.");
+
+       if (timestampExists(frameTimes.displayPresent))
+               result.check(frameTimes.firstCompositionStart < frameTimes.displayPresent, "Buffer displayed before it was composited.");
+}
+
+void verifyNeighboringFrames (const FrameTimes& frame1, const FrameTimes& frame2, tcu::ResultCollector& result, bool verifyReadsDone)
+{
+       // CPU timeline.
+       result.check(frame1.swapBufferBeginNs < frame2.swapBufferBeginNs, "Swap begin times not monotonic.");
+       result.check(frame1.latch < frame2.latch, "Latch times not monotonic.");
+       result.check(frame1.lastCompositionStart < frame2.latch, "Old buffer composited after new buffer latched.");
+       result.check(frame1.lastCompositionStart < frame2.firstCompositionStart, "Composition times overlap.");
+       result.check(frame1.dequeueReady < frame2.dequeueReady, "Dequeue ready times not monotonic.");
+
+       // GPU timeline.
+       result.check(frame1.renderingComplete < frame2.renderingComplete, "Rendering complete times not monotonic.");
+
+       if (timestampExists(frame1.firstCompositionGpuFinished) && timestampExists(frame2.firstCompositionGpuFinished))
+               result.check(frame1.firstCompositionGpuFinished < frame2.firstCompositionGpuFinished, "Composition GPU work complete times not monotonic.");
+
+       if (timestampExists(frame1.displayPresent) && timestampExists(frame2.displayPresent))
+               result.check(frame1.displayPresent < frame2.displayPresent, "Display present times not monotonic.");
+
+       if (verifyReadsDone && timestampExists(frame1.readsDone) && timestampExists(frame2.readsDone))
+               result.check(frame1.readsDone < frame2.readsDone, "Reads done times not monotonic.");
+}
+
+EGLContext createGLES2Context (const Library& egl, EGLDisplay display, EGLConfig config)
+{
+       EGLContext              context = EGL_NO_CONTEXT;
+       const EGLint    attribList[] =
+       {
+               EGL_CONTEXT_CLIENT_VERSION, 2,
+               EGL_NONE
+       };
+
+       EGLU_CHECK_CALL(egl, bindAPI(EGL_OPENGL_ES_API));
+
+       context = egl.createContext(display, config, EGL_NO_CONTEXT, attribList);
+       EGLU_CHECK_MSG(egl, "eglCreateContext() failed");
+       TCU_CHECK(context);
+
+       return context;
+}
+
+class GetFrameTimestampTest : public SimpleConfigCase
+{
+public:
+                                                       GetFrameTimestampTest   (EglTestContext& eglTestCtx, const NamedFilterList& filters);
+                                                       ~GetFrameTimestampTest  (void);
+
+private:
+       void                                    executeForConfig                (EGLDisplay display, EGLConfig config);
+       void                                    initializeExtension             (const Library& egl);
+
+       // Not allowed
+                                                       GetFrameTimestampTest   (const GetFrameTimestampTest&);
+       GetFrameTimestampTest&  operator=                               (const GetFrameTimestampTest&);
+
+       // TODO: Move these to eglw::Library.
+       eglGetNextFrameIdANDROIDFunc                            m_eglGetNextFrameIdANDROID;
+       eglGetCompositorTimingANDROIDFunc                       m_eglGetCompositorTimingANDROID;
+       eglGetCompositorTimingSupportedANDROIDFunc      m_eglGetCompositorTimingSupportedANDROID;
+       eglGetFrameTimestampsANDROIDFunc                        m_eglGetFrameTimestampsANDROID;
+       eglGetFrameTimestampSupportedANDROIDFunc        m_eglGetFrameTimestampSupportedANDROID;
+
+       tcu::ResultCollector                                            m_result;
+};
+
+GetFrameTimestampTest::GetFrameTimestampTest (EglTestContext& eglTestCtx, const NamedFilterList& filters)
+       : SimpleConfigCase                                                      (eglTestCtx, filters.getName(), filters.getDescription(), filters)
+       , m_eglGetNextFrameIdANDROID                            (DE_NULL)
+       , m_eglGetCompositorTimingANDROID                       (DE_NULL)
+       , m_eglGetCompositorTimingSupportedANDROID      (DE_NULL)
+       , m_eglGetFrameTimestampsANDROID                        (DE_NULL)
+       , m_eglGetFrameTimestampSupportedANDROID        (DE_NULL)
+       , m_result                                                                      (m_testCtx.getLog())
+{
+}
+
+GetFrameTimestampTest::~GetFrameTimestampTest (void)
+{
+}
+
+void GetFrameTimestampTest::initializeExtension (const Library& egl)
+{
+       m_eglGetNextFrameIdANDROID = reinterpret_cast<eglGetNextFrameIdANDROIDFunc>(egl.getProcAddress("eglGetNextFrameIdANDROID"));
+       EGLU_CHECK_MSG(egl, "getProcAddress of eglGetNextFrameIdANDROID failed.");
+       m_eglGetCompositorTimingANDROID = reinterpret_cast<eglGetCompositorTimingANDROIDFunc>(egl.getProcAddress("eglGetCompositorTimingANDROID"));
+       EGLU_CHECK_MSG(egl, "getProcAddress of eglGetCompositorTimingANDROID failed.");
+       m_eglGetCompositorTimingSupportedANDROID = reinterpret_cast<eglGetCompositorTimingSupportedANDROIDFunc>(egl.getProcAddress("eglGetCompositorTimingSupportedANDROID"));
+       EGLU_CHECK_MSG(egl, "getProcAddress of eglGetCompositorTimingSupportedANDROID failed.");
+       m_eglGetFrameTimestampsANDROID = reinterpret_cast<eglGetFrameTimestampsANDROIDFunc>(egl.getProcAddress("eglGetFrameTimestampsANDROID"));
+       EGLU_CHECK_MSG(egl, "getProcAddress of eglGetFrameTimestampsANDROID failed.");
+       m_eglGetFrameTimestampSupportedANDROID = reinterpret_cast<eglGetFrameTimestampSupportedANDROIDFunc>(egl.getProcAddress("eglGetFrameTimestampSupportedANDROID"));
+       EGLU_CHECK_MSG(egl, "getProcAddress of eglGetFrameTimestampSupportedANDROID failed.");
+}
+
+
+string getConfigIdString (const Library& egl, EGLDisplay display, EGLConfig config)
+{
+       std::ostringstream      stream;
+       EGLint                          id;
+
+       EGLU_CHECK_CALL(egl, getConfigAttrib(display, config , EGL_CONFIG_ID, &id));
+
+       stream << id;
+
+       return stream.str();
+}
+
+deUint32 createGLES2Program (const glw::Functions& gl, TestLog& log)
+{
+       const char* const vertexShaderSource =
+       "attribute highp vec2 a_pos;\n"
+       "void main (void)\n"
+       "{\n"
+       "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
+       "}";
+
+       const char* const fragmentShaderSource =
+       "void main (void)\n"
+       "{\n"
+       "\tgl_FragColor = vec4(0.9, 0.1, 0.4, 1.0);\n"
+       "}";
+
+       deUint32        program                 = 0;
+       deUint32        vertexShader    = 0;
+       deUint32        fragmentShader  = 0;
+
+       deInt32         vertexCompileStatus;
+       string          vertexInfoLog;
+       deInt32         fragmentCompileStatus;
+       string          fragmentInfoLog;
+       deInt32         linkStatus;
+       string          programInfoLog;
+
+       try
+       {
+               program                 = gl.createProgram();
+               vertexShader    = gl.createShader(GL_VERTEX_SHADER);
+               fragmentShader  = gl.createShader(GL_FRAGMENT_SHADER);
+
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to create shaders and program");
+
+               gl.shaderSource(vertexShader, 1, &vertexShaderSource, DE_NULL);
+               gl.compileShader(vertexShader);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup vertex shader");
+
+               gl.shaderSource(fragmentShader, 1, &fragmentShaderSource, DE_NULL);
+               gl.compileShader(fragmentShader);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup fragment shader");
+
+               {
+                       deInt32         infoLogLength = 0;
+
+                       gl.getShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexCompileStatus);
+                       gl.getShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+                       vertexInfoLog.resize(infoLogLength, '\0');
+
+                       gl.getShaderInfoLog(vertexShader, (glw::GLsizei)vertexInfoLog.length(), &infoLogLength, &(vertexInfoLog[0]));
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get vertex shader compile info");
+
+                       vertexInfoLog.resize(infoLogLength);
+               }
+
+               {
+                       deInt32         infoLogLength = 0;
+
+                       gl.getShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentCompileStatus);
+                       gl.getShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+                       fragmentInfoLog.resize(infoLogLength, '\0');
+
+                       gl.getShaderInfoLog(fragmentShader, (glw::GLsizei)fragmentInfoLog.length(), &infoLogLength, &(fragmentInfoLog[0]));
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get fragment shader compile info");
+
+                       fragmentInfoLog.resize(infoLogLength);
+               }
+
+               gl.attachShader(program, vertexShader);
+               gl.attachShader(program, fragmentShader);
+               gl.linkProgram(program);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup program");
+
+               {
+                       deInt32         infoLogLength = 0;
+
+                       gl.getProgramiv(program, GL_LINK_STATUS, &linkStatus);
+                       gl.getProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+
+                       programInfoLog.resize(infoLogLength, '\0');
+
+                       gl.getProgramInfoLog(program, (glw::GLsizei)programInfoLog.length(), &infoLogLength, &(programInfoLog[0]));
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to get program link info");
+
+                       programInfoLog.resize(infoLogLength);
+               }
+
+               if (linkStatus == 0 || vertexCompileStatus == 0 || fragmentCompileStatus == 0)
+               {
+
+                       log.startShaderProgram(linkStatus != 0, programInfoLog.c_str());
+
+                       log << TestLog::Shader(QP_SHADER_TYPE_VERTEX, vertexShaderSource, vertexCompileStatus != 0, vertexInfoLog);
+                       log << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, fragmentShaderSource, fragmentCompileStatus != 0, fragmentInfoLog);
+
+                       log.endShaderProgram();
+               }
+
+               gl.deleteShader(vertexShader);
+               gl.deleteShader(fragmentShader);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to delete shaders");
+
+               TCU_CHECK(linkStatus != 0 && vertexCompileStatus != 0 && fragmentCompileStatus != 0);
+       }
+       catch (...)
+       {
+               if (program)
+                       gl.deleteProgram(program);
+
+               if (vertexShader)
+                       gl.deleteShader(vertexShader);
+
+               if (fragmentShader)
+                       gl.deleteShader(fragmentShader);
+
+               throw;
+       }
+
+       return program;
+}
+
+void GetFrameTimestampTest::executeForConfig (EGLDisplay display, EGLConfig config)
+{
+       const Library&                                          egl                     = m_eglTestCtx.getLibrary();
+
+       if (!eglu::hasExtension(egl, display, "EGL_ANDROID_get_frame_timestamps"))
+               TCU_THROW(NotSupportedError, "EGL_ANDROID_get_frame_timestamps is not supported");
+
+       initializeExtension(egl);
+
+       const string                                            configIdStr     (getConfigIdString(egl, display, config));
+       tcu::ScopedLogSection                           logSection      (m_testCtx.getLog(), ("Config ID " + configIdStr).c_str(), ("Config ID " + configIdStr).c_str());
+       const eglu::NativeWindowFactory&        factory         = eglu::selectNativeWindowFactory(m_eglTestCtx.getNativeDisplayFactory(), m_testCtx.getCommandLine());
+
+       {
+               TestLog& log = m_testCtx.getLog();
+
+               log << TestLog::Message << "EGL_RED_SIZE: "             << eglu::getConfigAttribInt(egl, display, config, EGL_RED_SIZE)         << TestLog::EndMessage;
+               log << TestLog::Message << "EGL_GREEN_SIZE: "   << eglu::getConfigAttribInt(egl, display, config, EGL_GREEN_SIZE)       << TestLog::EndMessage;
+               log << TestLog::Message << "EGL_BLUE_SIZE: "    << eglu::getConfigAttribInt(egl, display, config, EGL_BLUE_SIZE)        << TestLog::EndMessage;
+               log << TestLog::Message << "EGL_ALPHA_SIZE: "   << eglu::getConfigAttribInt(egl, display, config, EGL_ALPHA_SIZE)       << TestLog::EndMessage;
+               log << TestLog::Message << "EGL_DEPTH_SIZE: "   << eglu::getConfigAttribInt(egl, display, config, EGL_DEPTH_SIZE)       << TestLog::EndMessage;
+               log << TestLog::Message << "EGL_STENCIL_SIZE: " << eglu::getConfigAttribInt(egl, display, config, EGL_STENCIL_SIZE)     << TestLog::EndMessage;
+               log << TestLog::Message << "EGL_SAMPLES: "              << eglu::getConfigAttribInt(egl, display, config, EGL_SAMPLES)          << TestLog::EndMessage;
+       }
+
+       de::UniquePtr<eglu::NativeWindow>       window  (factory.createWindow(&m_eglTestCtx.getNativeDisplay(), display, config, DE_NULL, eglu::WindowParams(128, 128, eglu::WindowParams::VISIBILITY_VISIBLE)));
+
+       eglu::UniqueSurface                                     surface (egl, display, eglu::createWindowSurface(m_eglTestCtx.getNativeDisplay(), *window, display, config, DE_NULL));
+       eglu::UniqueContext                                     context (egl, display, createGLES2Context(egl, display, config));
+       glw::Functions                                          gl;
+       deUint32                                                        program = 0;
+
+       EGLU_CHECK_CALL(egl, surfaceAttrib(display, *surface, EGL_TIMESTAMPS_ANDROID, EGL_TRUE));
+
+       m_eglTestCtx.initGLFunctions(&gl, glu::ApiType::es(2,0));
+
+       EGLU_CHECK_CALL(egl, makeCurrent(display, *surface, *surface, *context));
+
+       try
+       {
+               const eglw::EGLint frameTimestampNames[] =
+               {
+                       EGL_REQUESTED_PRESENT_TIME_ANDROID,
+                       EGL_RENDERING_COMPLETE_TIME_ANDROID,
+                       EGL_COMPOSITION_LATCH_TIME_ANDROID,
+                       EGL_FIRST_COMPOSITION_START_TIME_ANDROID,
+                       EGL_LAST_COMPOSITION_START_TIME_ANDROID,
+                       EGL_FIRST_COMPOSITION_GPU_FINISHED_TIME_ANDROID,
+                       EGL_DISPLAY_PRESENT_TIME_ANDROID,
+                       EGL_DEQUEUE_READY_TIME_ANDROID,
+                       EGL_READS_DONE_TIME_ANDROID,
+               };
+               const size_t frameTimestampCount = DE_LENGTH_OF_ARRAY(frameTimestampNames);
+
+               const eglw::EGLint invalidTimestampName = EGL_READS_DONE_TIME_ANDROID + 1;
+
+               // Verify required timestamps are supported.
+               for (size_t i = 0; i < frameTimestampCount; i++)
+               {
+                       const bool supported = m_eglGetFrameTimestampSupportedANDROID(display, *surface, frameTimestampNames[i]) != EGL_FALSE;
+                       EGLU_CHECK_MSG(egl, "eglGetFrameTimestampSupportedANDROID failed.");
+                       TCU_CHECK_MSG(supported, "Required timestamp not supported.");
+               }
+
+               // Verify unsupported timestamps are reported properly.
+               const bool invalidSupported = m_eglGetFrameTimestampSupportedANDROID(display, *surface, invalidTimestampName) != EGL_FALSE;
+               EGLU_CHECK_MSG(egl, "eglGetFrameTimestampSupportedANDROID failed.");
+               TCU_CHECK_MSG(!invalidSupported, "Non existant timestamp reports that it is supported.");
+
+               // Verify compositor timings are supported.
+               const bool deadlineSupported = m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_DEADLINE_ANDROID) != EGL_FALSE;
+               EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
+               TCU_CHECK_MSG(deadlineSupported, "EGL_COMPOSITE_DEADLINE_ANDROID not supported.");
+               const bool intervalSupported = m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_INTERVAL_ANDROID) != EGL_FALSE;
+               EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
+               TCU_CHECK_MSG(intervalSupported, "EGL_COMPOSITE_INTERVAL_ANDROID not supported.");
+               const bool latencySupported = m_eglGetCompositorTimingSupportedANDROID(display, *surface, EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID) != EGL_FALSE;
+               EGLU_CHECK_MSG(egl, "eglGetCompositorTimingSupportedANDROID failed.");
+               TCU_CHECK_MSG(latencySupported, "EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID not supported.");
+
+               const float positions1[] =
+               {
+                        0.00f,  0.00f,
+                        0.75f,  0.00f,
+                        0.75f,  0.75f,
+
+                        0.75f,  0.75f,
+                        0.00f,  0.75f,
+                        0.00f,  0.00f
+               };
+
+               const float positions2[] =
+               {
+                       -0.75f, -0.75f,
+                        0.00f, -0.75f,
+                        0.00f,  0.00f,
+
+                        0.00f,  0.00f,
+                       -0.75f,  0.00f,
+                       -0.75f, -0.75f
+               };
+
+               deUint32 posLocation;
+
+               program = createGLES2Program(gl, m_testCtx.getLog());
+
+               gl.useProgram(program);
+               posLocation     = gl.getAttribLocation(program, "a_pos");
+               gl.enableVertexAttribArray(posLocation);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup shader program for rendering");
+
+               const size_t frameCount = 120;
+               std::vector<FrameTimes> frameTimes(frameCount);
+               for (size_t i = 0; i < frameCount; i++)
+               {
+                       FrameTimes& frame = frameTimes[i];
+
+                       const eglw::EGLint compositorTimingNames[] =
+                       {
+                               EGL_COMPOSITE_DEADLINE_ANDROID,
+                               EGL_COMPOSITE_INTERVAL_ANDROID,
+                               EGL_COMPOSITE_TO_PRESENT_LATENCY_ANDROID,
+                       };
+                       const EGLint compositorTimingCount = DE_LENGTH_OF_ARRAY(compositorTimingNames);
+                       EGLnsecsANDROID compositorTimingValues[compositorTimingCount] = { -2 };
+
+                       // Get the current time before making any API calls in case "now"
+                       // just happens to get sampled near one of the composite deadlines.
+                       EGLnsecsANDROID now = getNanoseconds();
+
+                       // Get the frame id.
+                       EGLuint64KHR nextFrameId = 0;
+                       CHECK_NAKED_EGL_CALL(egl, m_eglGetNextFrameIdANDROID(display, *surface, &nextFrameId));
+                       frame.frameId                           =       nextFrameId;
+
+                       // Get the compositor timing.
+                       CHECK_NAKED_EGL_CALL(egl, m_eglGetCompositorTimingANDROID(
+                               display, *surface, compositorTimingCount,
+                               compositorTimingNames, compositorTimingValues));
+                       frame.compositeDeadline                 =       compositorTimingValues[0];
+                       frame.compositeInterval                 =       compositorTimingValues[1];
+                       frame.compositeToPresentLatency =       compositorTimingValues[2];
+
+                       // Verify compositor timing is sane.
+                       m_result.check(1000000 < frame.compositeInterval, "Reported refresh rate greater than 1kHz.");
+                       m_result.check(frame.compositeInterval < 1000000000, "Reported refresh rate less than 1Hz.");
+                       m_result.check(0 < frame.compositeToPresentLatency, "Composite to present latency must be greater than 0.");
+                       m_result.check(frame.compositeToPresentLatency < frame.compositeInterval * 3, "Composite to present latency is more than 3 vsyncs.");
+                       const EGLnsecsANDROID minDeadline = now;
+                       m_result.check(minDeadline < frame.compositeDeadline, "Next composite deadline is in the past.");
+                       const EGLnsecsANDROID maxDeadline = now + frame.compositeInterval * 2;
+                       m_result.check(frame.compositeDeadline < maxDeadline, "Next composite deadline over two intervals away.");
+
+                       const float colorAngle = (static_cast<float>(i) / static_cast<float>(frameCount)) * 6.28318f;
+                       gl.clearColor((1.0f + deFloatSin(colorAngle)) / 2.0f, 0.7f, (1.0f + deFloatCos(colorAngle)) / 2.0f, 1.0f);
+                       gl.clear(GL_COLOR_BUFFER_BIT);
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to clear surface");
+
+                       const bool posSelect  = ((i % 2) == 0);
+                       gl.vertexAttribPointer(posLocation, 2, GL_FLOAT, GL_FALSE, 0, posSelect ? positions1 : positions2);
+                       gl.drawArrays(GL_TRIANGLES, 0, 6);
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render");
+
+                       frame.swapBufferBeginNs = getNanoseconds();
+                       EGLU_CHECK_CALL(egl, swapBuffers(display, *surface));
+
+                       // All timestamps from 5 frames ago should definitely be available.
+                       const size_t frameDelay = 5;
+                       if (i >= frameDelay)
+                       {
+                               FrameTimes&             frame5ago                                                                       =       frameTimes[i-frameDelay];
+                               EGLnsecsANDROID frameTimestampValues[frameTimestampCount]       =       { 0 };
+                               // \todo [2017-01-25 brianderson] Remove this work around once reads done is fixed.
+                               const bool verifyReadsDone                                                                      =       i > (frameDelay + 3);
+
+                               CHECK_NAKED_EGL_CALL(egl, m_eglGetFrameTimestampsANDROID(
+                                       display, *surface, frame5ago.frameId, frameTimestampCount,
+                                       frameTimestampNames, frameTimestampValues));
+
+                               frame5ago.requestedPresent                              =       frameTimestampValues[0];
+                               frame5ago.renderingComplete                             =       frameTimestampValues[1];
+                               frame5ago.latch                                                 =       frameTimestampValues[2];
+                               frame5ago.firstCompositionStart                 =       frameTimestampValues[3];
+                               frame5ago.lastCompositionStart                  =       frameTimestampValues[4];
+                               frame5ago.firstCompositionGpuFinished   =       frameTimestampValues[5];
+                               frame5ago.displayPresent                                =       frameTimestampValues[6];
+                               frame5ago.dequeueReady                                  =       frameTimestampValues[7];
+                               frame5ago.readsDone                                             =       frameTimestampValues[8];
+
+                               verifySingleFrame(frame5ago, m_result, verifyReadsDone);
+                               if (i >= frameDelay + 1)
+                               {
+                                       FrameTimes& frame6ago = frameTimes[i-frameDelay-1];
+                                       verifyNeighboringFrames(frame6ago, frame5ago, m_result, verifyReadsDone);
+                               }
+                       }
+               }
+
+               // All timestamps for the most recently swapped frame should
+               // become available by only polling eglGetFrametimestamps.
+               // No additional swaps should be necessary.
+               FrameTimes&                             lastFrame                               =       frameTimes.back();
+               const EGLnsecsANDROID   pollingDeadline                 =       lastFrame.swapBufferBeginNs + 1000000000;
+               bool                                    finalTimestampAvaiable  =       false;
+
+               do
+               {
+                       EGLnsecsANDROID frameTimestampValues[frameTimestampCount] = { 0 };
+                       CHECK_NAKED_EGL_CALL(egl, m_eglGetFrameTimestampsANDROID(
+                               display, *surface, lastFrame.frameId, frameTimestampCount,
+                               frameTimestampNames, frameTimestampValues));
+
+                       lastFrame.requestedPresent                              =       frameTimestampValues[0];
+                       lastFrame.renderingComplete                             =       frameTimestampValues[1];
+                       lastFrame.latch                                                 =       frameTimestampValues[2];
+                       lastFrame.firstCompositionStart                 =       frameTimestampValues[3];
+                       lastFrame.lastCompositionStart                  =       frameTimestampValues[4];
+                       lastFrame.firstCompositionGpuFinished   =       frameTimestampValues[5];
+                       lastFrame.displayPresent                                =       frameTimestampValues[6];
+                       lastFrame.dequeueReady                                  =       frameTimestampValues[7];
+                       lastFrame.readsDone                                             =       frameTimestampValues[8];
+
+                       if (timestampExists(lastFrame.displayPresent))
+                               finalTimestampAvaiable = true;
+
+                       if (getNanoseconds() > pollingDeadline)
+                               break;
+               } while (!finalTimestampAvaiable);
+
+               m_result.check(finalTimestampAvaiable, "Timed out polling for timestamps of last swap.");
+               m_result.check(timestampExists(lastFrame.requestedPresent), "Rendering complete of last swap not avaiable.");
+               m_result.check(timestampExists(lastFrame.renderingComplete), "Rendering complete of last swap not avaiable.");
+               m_result.check(timestampExists(lastFrame.latch), "Latch of last swap not avaiable.");
+               m_result.check(timestampExists(lastFrame.firstCompositionStart), "First composite time of last swap not avaiable.");
+               m_result.check(timestampExists(lastFrame.lastCompositionStart), "Last composite time of last swap not avaiable.");
+
+               window->processEvents();
+               gl.disableVertexAttribArray(posLocation);
+               gl.useProgram(0);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to release program state");
+
+               gl.deleteProgram(program);
+               program = 0;
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteProgram()");
+
+               m_result.setTestContextResult(m_testCtx);
+       }
+       catch (...)
+       {
+               if (program != 0)
+                       gl.deleteProgram(program);
+
+               EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+               throw;
+       }
+
+       EGLU_CHECK_CALL(egl, makeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
+}
+
+class GetFrameTimestampsTests : public TestCaseGroup
+{
+public:
+                                                               GetFrameTimestampsTests (EglTestContext& eglTestCtx);
+       void                                            init                                    (void);
+
+private:
+                                                               GetFrameTimestampsTests (const GetFrameTimestampsTests&);
+       GetFrameTimestampsTests&        operator=                               (const GetFrameTimestampsTests&);
+};
+
+
+GetFrameTimestampsTests::GetFrameTimestampsTests (EglTestContext& eglTestCtx)
+       : TestCaseGroup(eglTestCtx, "get_frame_timestamps", "Get frame timestamp tests")
+{
+}
+
+bool isWindow (const eglu::CandidateConfig& c)
+{
+       return (c.surfaceType() & EGL_WINDOW_BIT) != 0;
+}
+
+void GetFrameTimestampsTests::init (void)
+{
+       eglu::FilterList baseFilters;
+       baseFilters << isWindow;
+
+       vector<NamedFilterList> filterLists;
+       getDefaultFilterLists(filterLists, baseFilters);
+
+       for (vector<NamedFilterList>::iterator i = filterLists.begin(); i != filterLists.end(); i++)
+               addChild(new GetFrameTimestampTest(m_eglTestCtx, *i));
+}
+
+} // anonymous
+
+TestCaseGroup* createGetFrameTimestampsTests (EglTestContext& eglTestCtx)
+{
+       return new GetFrameTimestampsTests(eglTestCtx);
+}
+
+} // egl
+} // deqp
diff --git a/modules/egl/teglGetFrameTimestampsTests.hpp b/modules/egl/teglGetFrameTimestampsTests.hpp
new file mode 100644 (file)
index 0000000..d55d6a4
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _TEGLGETFRAMETIMESTAMPSTESTS_HPP
+#define _TEGLGETFRAMETIMESTAMPSTESTS_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 Test the EGL_ANDROID_get_frame_timestamps extension.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "teglTestCase.hpp"
+
+namespace deqp
+{
+namespace egl
+{
+
+TestCaseGroup* createGetFrameTimestampsTests (EglTestContext& eglTestCtx);
+
+} // egl
+} // deqp
+
+#endif // _TEGLGETFRAMETIMESTAMPSTESTS_HPP
index 087ec0e..33fde9b 100644 (file)
@@ -1,7 +1,7 @@
 /* WARNING: This is auto-generated file. Do not modify, since changes will
  * be lost! Modify the generating script instead.
  *
- * Generated from Khronos EGL API description (egl.xml) revision 32725.
+ * Generated from Khronos EGL API description (egl.xml) revision 33315.
  */
 
 static const char* s_EGL14[] =
@@ -449,11 +449,21 @@ static const char* s_EGL_ANDROID_blob_cache[] =
        "eglSetBlobCacheFuncsANDROID",
 };
 
+static const char* s_EGL_ANDROID_create_native_client_buffer[] =
+{
+       "eglCreateNativeClientBufferANDROID",
+};
+
 static const char* s_EGL_ANDROID_native_fence_sync[] =
 {
        "eglDupNativeFenceFDANDROID",
 };
 
+static const char* s_EGL_ANDROID_presentation_time[] =
+{
+       "eglPresentationTimeANDROID",
+};
+
 static const char* s_EGL_ANGLE_query_surface_pointer[] =
 {
        "eglQuerySurfacePointerANGLE",
@@ -479,6 +489,12 @@ static const char* s_EGL_EXT_device_query[] =
        "eglQueryDisplayAttribEXT",
 };
 
+static const char* s_EGL_EXT_image_dma_buf_import_modifiers[] =
+{
+       "eglQueryDmaBufFormatsEXT",
+       "eglQueryDmaBufModifiersEXT",
+};
+
 static const char* s_EGL_EXT_output_base[] =
 {
        "eglGetOutputLayersEXT",
@@ -581,6 +597,15 @@ static const char* s_EGL_KHR_stream[] =
        "eglStreamAttribKHR",
 };
 
+static const char* s_EGL_KHR_stream_attrib[] =
+{
+       "eglCreateStreamAttribKHR",
+       "eglQueryStreamAttribKHR",
+       "eglSetStreamAttribKHR",
+       "eglStreamConsumerAcquireAttribKHR",
+       "eglStreamConsumerReleaseAttribKHR",
+};
+
 static const char* s_EGL_KHR_stream_consumer_gltexture[] =
 {
        "eglStreamConsumerAcquireKHR",
@@ -660,6 +685,11 @@ static const char* s_EGL_NV_stream_metadata[] =
        "eglSetStreamMetadataNV",
 };
 
+static const char* s_EGL_NV_stream_reset[] =
+{
+       "eglResetStreamNV",
+};
+
 static const char* s_EGL_NV_stream_sync[] =
 {
        "eglCreateStreamSyncNV",
@@ -1553,11 +1583,14 @@ static const struct
 } s_extensions[] =
 {
        { "EGL_ANDROID_blob_cache",                                                     DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_blob_cache),                                           s_EGL_ANDROID_blob_cache                                                },
+       { "EGL_ANDROID_create_native_client_buffer",            DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_create_native_client_buffer),          s_EGL_ANDROID_create_native_client_buffer               },
        { "EGL_ANDROID_native_fence_sync",                                      DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_native_fence_sync),                            s_EGL_ANDROID_native_fence_sync                                 },
+       { "EGL_ANDROID_presentation_time",                                      DE_LENGTH_OF_ARRAY(s_EGL_ANDROID_presentation_time),                            s_EGL_ANDROID_presentation_time                                 },
        { "EGL_ANGLE_query_surface_pointer",                            DE_LENGTH_OF_ARRAY(s_EGL_ANGLE_query_surface_pointer),                          s_EGL_ANGLE_query_surface_pointer                               },
        { "EGL_EXT_device_base",                                                        DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_base),                                                      s_EGL_EXT_device_base                                                   },
        { "EGL_EXT_device_enumeration",                                         DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_enumeration),                                       s_EGL_EXT_device_enumeration                                    },
        { "EGL_EXT_device_query",                                                       DE_LENGTH_OF_ARRAY(s_EGL_EXT_device_query),                                                     s_EGL_EXT_device_query                                                  },
+       { "EGL_EXT_image_dma_buf_import_modifiers",                     DE_LENGTH_OF_ARRAY(s_EGL_EXT_image_dma_buf_import_modifiers),           s_EGL_EXT_image_dma_buf_import_modifiers                },
        { "EGL_EXT_output_base",                                                        DE_LENGTH_OF_ARRAY(s_EGL_EXT_output_base),                                                      s_EGL_EXT_output_base                                                   },
        { "EGL_EXT_platform_base",                                                      DE_LENGTH_OF_ARRAY(s_EGL_EXT_platform_base),                                            s_EGL_EXT_platform_base                                                 },
        { "EGL_EXT_stream_consumer_egloutput",                          DE_LENGTH_OF_ARRAY(s_EGL_EXT_stream_consumer_egloutput),                        s_EGL_EXT_stream_consumer_egloutput                             },
@@ -1573,6 +1606,7 @@ static const struct
        { "EGL_KHR_partial_update",                                                     DE_LENGTH_OF_ARRAY(s_EGL_KHR_partial_update),                                           s_EGL_KHR_partial_update                                                },
        { "EGL_KHR_reusable_sync",                                                      DE_LENGTH_OF_ARRAY(s_EGL_KHR_reusable_sync),                                            s_EGL_KHR_reusable_sync                                                 },
        { "EGL_KHR_stream",                                                                     DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream),                                                           s_EGL_KHR_stream                                                                },
+       { "EGL_KHR_stream_attrib",                                                      DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_attrib),                                            s_EGL_KHR_stream_attrib                                                 },
        { "EGL_KHR_stream_consumer_gltexture",                          DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_consumer_gltexture),                        s_EGL_KHR_stream_consumer_gltexture                             },
        { "EGL_KHR_stream_cross_process_fd",                            DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_cross_process_fd),                          s_EGL_KHR_stream_cross_process_fd                               },
        { "EGL_KHR_stream_fifo",                                                        DE_LENGTH_OF_ARRAY(s_EGL_KHR_stream_fifo),                                                      s_EGL_KHR_stream_fifo                                                   },
@@ -1587,6 +1621,7 @@ static const struct
        { "EGL_NV_post_sub_buffer",                                                     DE_LENGTH_OF_ARRAY(s_EGL_NV_post_sub_buffer),                                           s_EGL_NV_post_sub_buffer                                                },
        { "EGL_NV_stream_consumer_gltexture_yuv",                       DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_consumer_gltexture_yuv),                     s_EGL_NV_stream_consumer_gltexture_yuv                  },
        { "EGL_NV_stream_metadata",                                                     DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_metadata),                                           s_EGL_NV_stream_metadata                                                },
+       { "EGL_NV_stream_reset",                                                        DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_reset),                                                      s_EGL_NV_stream_reset                                                   },
        { "EGL_NV_stream_sync",                                                         DE_LENGTH_OF_ARRAY(s_EGL_NV_stream_sync),                                                       s_EGL_NV_stream_sync                                                    },
        { "EGL_NV_sync",                                                                        DE_LENGTH_OF_ARRAY(s_EGL_NV_sync),                                                                      s_EGL_NV_sync                                                                   },
        { "EGL_NV_system_time",                                                         DE_LENGTH_OF_ARRAY(s_EGL_NV_system_time),                                                       s_EGL_NV_system_time                                                    },
index 8295f74..a33da58 100644 (file)
@@ -122,11 +122,12 @@ void NegativeApiTests::init (void)
        using namespace eglw;
        using namespace eglu;
 
-       static const EGLint s_emptyAttribList[]                 = { EGL_NONE };
-       static const EGLint s_es1ContextAttribList[]    = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE };
-       static const EGLint s_es2ContextAttribList[]    = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+       static const EGLint                             s_emptyAttribList[]                     = { EGL_NONE };
+       static const EGLint                             s_es1ContextAttribList[]        = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE };
+       static const EGLint                             s_es2ContextAttribList[]        = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
 
-       static const EGLenum s_renderAPIs[]                             = { EGL_OPENGL_API, EGL_OPENGL_ES_API, EGL_OPENVG_API };
+       static const EGLenum                    s_renderAPIs[]                          = { EGL_OPENGL_API, EGL_OPENGL_ES_API, EGL_OPENVG_API };
+       static const eglu::ConfigFilter s_renderAPIFilters[]            = { renderable<EGL_OPENGL_BIT>, renderable<EGL_OPENGL_ES_BIT>, renderable<EGL_OPENVG_BIT> };
 
        TEGL_ADD_API_CASE(bind_api, "eglBindAPI() negative tests",
                {
@@ -144,14 +145,19 @@ void NegativeApiTests::init (void)
 
                        log << TestLog::EndSection;
 
-                       log << TestLog::Section("Test2", "EGL_BAD_PARAMETER is generated if the specified client API is not supported by the EGL implementation");
+                       log << TestLog::Section("Test2", "EGL_BAD_PARAMETER is generated if the specified client API is not supported by the EGL display, or no configuration is provided for the specified API.");
 
                        for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_renderAPIs); ndx++)
                        {
                                if (!isAPISupported(s_renderAPIs[ndx]))
                                {
-                                       expectFalse(eglBindAPI(s_renderAPIs[ndx]));
-                                       expectError(EGL_BAD_PARAMETER);
+                                       if (!eglBindAPI(s_renderAPIs[ndx]))
+                                               expectError(EGL_BAD_PARAMETER);
+                                       else
+                                       {
+                                               EGLConfig eglConfig;
+                                               expectFalse(getConfig(&eglConfig, FilterList() << s_renderAPIFilters[ndx]));
+                                       }
                                }
                        }
 
index fc30091..a0ff8ae 100644 (file)
@@ -397,6 +397,11 @@ static bool isConformant (const eglu::CandidateConfig& c)
        return c.get(EGL_CONFIG_CAVEAT) != EGL_NON_CONFORMANT_CONFIG;
 }
 
+static bool notFloat (const eglu::CandidateConfig& c)
+{
+       return c.colorComponentType() != EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
+}
+
 void getDefaultRenderFilterLists (vector<RenderFilterList>& filterLists, const eglu::FilterList& baseFilters)
 {
        static const struct
@@ -450,7 +455,8 @@ void getDefaultRenderFilterLists (vector<RenderFilterList>& filterLists, const e
                                << notColorBits<4, 4, 4, 4>
                                << notColorBits<5, 5, 5, 1>
                                << notColorBits<8, 8, 8, 8>
-                               << isConformant;
+                               << isConformant
+                               << notFloat;
 
                filterLists.push_back(filters);
        }
diff --git a/modules/egl/teglRobustnessTests.cpp b/modules/egl/teglRobustnessTests.cpp
new file mode 100644 (file)
index 0000000..269b866
--- /dev/null
@@ -0,0 +1,2430 @@
+/*-------------------------------------------------------------------------
+ * 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)
+{
+       // \todo [2017-03-23 pyry] Current version has 2 somewhat ugly hacks:
+       //
+       // 1) Core functions are loaded twice. We need glGetString(i) to query supported
+       //    extensions to determine if we need to load EXT or KHR-suffixed robustness
+       //    functions. This could be fixed by exposing glw::FunctionLoader in EglTestContext
+       //    for example.
+       //
+       // 2) We assume that calling code will check for KHR_robustness or EXT_robustness
+       //    support after calling initGLFunctions(). We could move the check here.
+
+       const glu::ApiType      apiType = attribListToContextType(m_attribList).getAPI();
+
+       m_eglTestCtx.initGLFunctions(gl, apiType);
+
+       {
+               const char* const       robustnessExt   = glu::hasExtension(*gl, apiType, "GL_KHR_robustness") ? "GL_KHR_robustness" : "GL_EXT_robustness";
+               const char* const       extensions[]    = { robustnessExt };
+
+               m_eglTestCtx.initGLFunctions(gl, apiType, 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::GLuint                     m_outputBuffer;
+       glw::GLuint                     m_coordinatesBuffer;
+       glw::GLint                      m_coordLocation;
+};
+
+InfiniteLoop::InfiniteLoop (glw::Functions& gl, tcu::TestLog& log, ShaderType shaderType)
+       : ContextReset(gl, log, shaderType)
+       , m_outputBuffer                (0)
+       , m_coordinatesBuffer   (0)
+       , m_coordLocation               (0)
+{
+}
+
+InfiniteLoop::~InfiniteLoop (void)
+{
+       try
+       {
+               // Reset GL_CONTEXT_LOST error before destroying resources
+               m_gl.getGraphicsResetStatus();
+               teardown();
+       }
+       catch (...)
+       {
+               // Ignore GL errors from teardown()
+       }
+}
+
+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
+               m_outputBuffer = 0;
+               GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_outputBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_SHADER_STORAGE_BUFFER, m_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, bindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_outputBuffer));
+       }
+       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
+               m_coordinatesBuffer = 0;
+               GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
+               GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
+               GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
+       }
+
+       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)
+       {
+               if (m_coordLocation)
+               {
+                       GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
+                       m_coordLocation = 0;
+               }
+       }
+
+       if (m_outputBuffer)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_outputBuffer));
+               m_outputBuffer = 0;
+       }
+
+       if (m_coordinatesBuffer)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
+               m_coordinatesBuffer = 0;
+       }
+
+       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::GLuint                             m_coordinatesBuffer;
+       glw::GLint                              m_coordLocation;
+};
+
+FixedFunctionOOB::FixedFunctionOOB (glw::Functions& gl, tcu::TestLog& log, FixedFunctionType fixedFunctionType)
+       : ContextReset(gl, log, fixedFunctionType)
+       , m_coordinatesBuffer   (0)
+       , m_coordLocation               (0)
+{
+}
+
+FixedFunctionOOB::~FixedFunctionOOB (void)
+{
+       try
+       {
+               // Reset GL_CONTEXT_LOST error before destroying resources
+               m_gl.getGraphicsResetStatus();
+               teardown();
+       }
+       catch (...)
+       {
+               // Ignore GL errors from teardown()
+       }
+}
+
+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);
+
+       // Load the vertex data
+       m_coordinatesBuffer = 0;
+       GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
+       GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
+       GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
+       GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
+       GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
+}
+
+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)
+{
+       if (m_coordLocation)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
+               m_coordLocation = 0;
+       }
+
+       if (m_coordinatesBuffer)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
+               m_coordinatesBuffer = 0;
+       }
+
+       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::GLuint                                     m_coordinatesBuffer;
+       glw::GLint                                      m_coordLocation;
+
+       bool                                            m_isUBO;
+       bool                                            m_isRead;
+       bool                                            m_isLocalArray;
+       std::vector<glw::GLuint>        m_buffers;
+
+       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_coordinatesBuffer   (0)
+       , m_coordLocation               (0)
+       , m_buffers                             (s_numBindings, 0)
+{
+       m_isUBO                 = (m_resourceType == RESOURCETYPE_UBO);
+       m_isLocalArray  = (m_resourceType == RESOURCETYPE_LOCAL_ARRAY);
+       m_isRead                = (m_readWriteType == READWRITETYPE_READ);
+}
+
+ShadersOOB::~ShadersOOB (void)
+{
+       try
+       {
+               // Reset GL_CONTEXT_LOST error before destroying resources
+               m_gl.getGraphicsResetStatus();
+               teardown();
+       }
+       catch (...)
+       {
+               // Ignore GL errors from teardown()
+       }
+}
+
+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);
+
+               // Load the vertex data
+               m_coordinatesBuffer = 0;
+               GLU_CHECK_GLW_CALL(m_gl, genBuffers(1, &m_coordinatesBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bindBuffer(GL_ARRAY_BUFFER, m_coordinatesBuffer));
+               GLU_CHECK_GLW_CALL(m_gl, bufferData(GL_ARRAY_BUFFER, (glw::GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW));
+               GLU_CHECK_GLW_CALL(m_gl, enableVertexAttribArray(m_coordLocation));
+               GLU_CHECK_GLW_CALL(m_gl, vertexAttribPointer(m_coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL));
+       }
+
+       // 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
+               GLU_CHECK_GLW_CALL(m_gl, genBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
+
+               for (int bufNdx = 0; bufNdx < (int)m_buffers.size(); ++bufNdx)
+               {
+                       GLU_CHECK_GLW_CALL(m_gl, bindBuffer(resType, m_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, m_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)
+       {
+               if (m_coordLocation)
+               {
+                       GLU_CHECK_GLW_CALL(m_gl, disableVertexAttribArray(m_coordLocation));
+                       m_coordLocation = 0;
+               }
+       }
+
+       if (m_coordinatesBuffer)
+       {
+               GLU_CHECK_GLW_CALL(m_gl, deleteBuffers(1, &m_coordinatesBuffer));
+               m_coordinatesBuffer = 0;
+       }
+
+       if (!m_isLocalArray)
+       {
+               if (!m_buffers.empty())
+               {
+                       GLU_CHECK_GLW_CALL(m_gl, deleteBuffers((glw::GLsizei)m_buffers.size(), &m_buffers[0]));
+                       m_buffers.clear();
+               }
+       }
+
+       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)
+       {
+               m_testCtx.getLog()      << 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;
+
+               contextReset->setup();
+               contextReset->draw();
+       }
+
+       virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->teardown();
+               contextReset->finish();
+       }
+
+       virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
+       {
+               const glw::GLint status = contextReset->getGraphicsResetStatus();
+
+               if (status == GL_NO_ERROR)
+               {
+                       m_testCtx.getLog()      << 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)
+       {
+               m_testCtx.getLog()      << 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;
+
+               contextReset->setup();
+               contextReset->draw();
+       }
+
+       virtual void waitForReset (de::SharedPtr<ContextReset>& contextReset)
+       {
+               contextReset->createSyncObject();
+               contextReset->teardown();
+               contextReset->finish();
+       }
+
+       virtual void passAndLog (de::SharedPtr<ContextReset>& contextReset)
+       {
+               const glw::GLint status = contextReset->getSyncStatus();
+               if (status != GL_SIGNALED)
+               {
+                       m_testCtx.getLog()      << 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)
+       {
+               m_testCtx.getLog()      << 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;
+
+               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)
+       {
+               const glw::GLuint queryReady = contextReset->getQueryAvailability();
+               if (queryReady != GL_TRUE)
+               {
+                       m_testCtx.getLog()      << 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&)
+               {
+                       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 c528178..fc02455 100644 (file)
@@ -143,6 +143,11 @@ static bool isConformant (const eglu::CandidateConfig& c)
        return c.get(EGL_CONFIG_CAVEAT) != EGL_NON_CONFORMANT_CONFIG;
 }
 
+static bool notFloat (const eglu::CandidateConfig& c)
+{
+       return c.colorComponentType() != EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT;
+}
+
 void getDefaultFilterLists (vector<NamedFilterList>& lists, const FilterList& baseFilters)
 {
        static const struct
@@ -209,7 +214,8 @@ void getDefaultFilterLists (vector<NamedFilterList>& lists, const FilterList& ba
                                << notColorBits<4, 4, 4, 4>
                                << notColorBits<5, 5, 5, 1>
                                << notColorBits<8, 8, 8, 8>
-                               << isConformant;
+                               << isConformant
+                               << notFloat;
 
                lists.push_back(filters);
        }
index 443fad6..91a374b 100644 (file)
@@ -63,6 +63,8 @@
 #include "teglMultiContextTests.hpp"
 #include "teglThreadCleanUpTests.hpp"
 #include "teglMutableRenderBufferTests.hpp"
+#include "teglGetFrameTimestampsTests.hpp"
+#include "teglRobustnessTests.hpp"
 
 namespace deqp
 {
@@ -138,6 +140,8 @@ public:
                addChild(createMultiContextTests                (m_eglTestCtx));
                addChild(createThreadCleanUpTest                (m_eglTestCtx));
                addChild(new MutableRenderBufferTests   (m_eglTestCtx));
+               addChild(createGetFrameTimestampsTests  (m_eglTestCtx));
+               addChild(createRobustnessTests                  (m_eglTestCtx));
        }
 };
 
index 793c7a3..eacda9e 100644 (file)
@@ -669,7 +669,7 @@ DepthStencilCase::IterateResult DepthStencilCase::iterate (void)
                translateCommand(testCmd, refTestCmd, m_renderTarget);
 
                // Base clears.
-               renderReference(m_baseClears, m_refColorBuffer->getAccess(), m_refStencilBuffer->getAccess(), m_renderTarget.depthBits);
+               renderReference(m_baseClears, m_refColorBuffer->getAccess(), m_refStencilBuffer->getAccess(), m_renderTarget.stencilBits);
 
                // Base depths.
                for (vector<RefRenderCommand>::const_iterator cmd = m_refBaseDepthRenders.begin(); cmd != m_refBaseDepthRenders.end(); ++cmd)
index 245cf21..2b736d7 100644 (file)
@@ -869,7 +869,15 @@ public:
                de::Random rnd(0xabcdef);
 
                GLint maxViewportDimensions[2] = {0};
+               GLfloat viewportBoundsRange[2] = {0.0f};
+               GLboolean hasViewportArray = false;
                glGetIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDimensions);
+               hasViewportArray = m_context.getContextInfo().isExtensionSupported("GL_OES_viewport_array") ||
+                                                  m_context.getContextInfo().isExtensionSupported("GL_NV_viewport_array");
+               if (hasViewportArray)
+               {
+                       glGetFloatv(GL_VIEWPORT_BOUNDS_RANGE, viewportBoundsRange);
+               }
 
                // verify initial value of first two values
                m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, 0, 0, m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
@@ -884,7 +892,19 @@ public:
                        GLsizei height  = rnd.getInt(0, maxViewportDimensions[1]);
 
                        glViewport(x, y, width, height);
-                       m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, x, y, width, height);
+
+                       if (hasViewportArray)
+                       {
+                               m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT,
+                                                                                  de::clamp(x, deFloorFloatToInt32(viewportBoundsRange[0]), deFloorFloatToInt32(viewportBoundsRange[1])),
+                                                                                  de::clamp(y, deFloorFloatToInt32(viewportBoundsRange[0]), deFloorFloatToInt32(viewportBoundsRange[1])),
+                                                                                  width, height);
+                       }
+                       else
+                       {
+                               m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, x, y, width, height);
+                       }
+
                        expectError(GL_NO_ERROR);
                }
        }
index 4a933d8..7ec850f 100644 (file)
@@ -475,7 +475,7 @@ tcu::Vec4 UsageDisplacementTestCase::genRandomVec4 (de::Random& rnd) const
 
        retVal.x() = rnd.getFloat(-1, 1);
        retVal.y() = rnd.getFloat(-1, 1);
-       retVal.z() = rnd.getFloat(-0.9f, 0.9f);
+       retVal.z() = 0.5f;
        retVal.w() = 1.0f + rnd.getFloat();
 
        return retVal;
index ab60b1d..af32ff2 100644 (file)
@@ -445,9 +445,12 @@ ASTCBlockCase2D::IterateResult ASTCBlockCase2D::iterate (void)
 
        // Create texture and render.
 
-       glu::Texture2D  texture                 (renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams((m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR ? tcu::TexDecompressionParams::ASTCMODE_LDR : tcu::TexDecompressionParams::ASTCMODE_HDR)));
-       Surface                 renderedFrame   (imageWidth, imageHeight);
-       Surface                 referenceFrame  (imageWidth, imageHeight);
+       const tcu::TexDecompressionParams::AstcMode     decompressionMode       = (m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR || tcu::isAstcSRGBFormat(m_format))
+                                                                                                                                       ? tcu::TexDecompressionParams::ASTCMODE_LDR
+                                                                                                                                       : tcu::TexDecompressionParams::ASTCMODE_HDR;
+       glu::Texture2D                                                          texture                         (renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams(decompressionMode));
+       Surface                                                                         renderedFrame           (imageWidth, imageHeight);
+       Surface                                                                         referenceFrame          (imageWidth, imageHeight);
 
        m_renderer->render(referenceFrame, renderedFrame, texture, getUncompressedFormat(compressed.getFormat()));
 
@@ -565,9 +568,12 @@ ASTCBlockSizeRemainderCase2D::IterateResult ASTCBlockSizeRemainderCase2D::iterat
 
        // Create texture and render.
 
-       Surface                 renderedFrame   (imageWidth, imageHeight);
-       Surface                 referenceFrame  (imageWidth, imageHeight);
-       glu::Texture2D  texture                 (renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams(m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR ? tcu::TexDecompressionParams::ASTCMODE_LDR : tcu::TexDecompressionParams::ASTCMODE_HDR));
+       const tcu::TexDecompressionParams::AstcMode     decompressionMode       = (m_renderer->getASTCSupport() == ASTCSUPPORTLEVEL_LDR || tcu::isAstcSRGBFormat(m_format))
+                                                                                                                                       ? tcu::TexDecompressionParams::ASTCMODE_LDR
+                                                                                                                                       : tcu::TexDecompressionParams::ASTCMODE_HDR;
+       Surface                                                                         renderedFrame           (imageWidth, imageHeight);
+       Surface                                                                         referenceFrame          (imageWidth, imageHeight);
+       glu::Texture2D                                                          texture                         (renderCtx, m_context.getContextInfo(), 1, &compressed, tcu::TexDecompressionParams(decompressionMode));
 
        m_renderer->render(referenceFrame, renderedFrame, texture, getUncompressedFormat(compressed.getFormat()));
 
index 09958d8..be01b15 100644 (file)
@@ -669,7 +669,7 @@ DepthStencilCase::IterateResult DepthStencilCase::iterate (void)
                translateCommand(testCmd, refTestCmd, m_renderTarget);
 
                // Base clears.
-               renderReference(m_baseClears, m_refColorBuffer->getAccess(), m_refStencilBuffer->getAccess(), m_renderTarget.depthBits);
+               renderReference(m_baseClears, m_refColorBuffer->getAccess(), m_refStencilBuffer->getAccess(), m_renderTarget.stencilBits);
 
                // Base depths.
                for (vector<RefRenderCommand>::const_iterator cmd = m_refBaseDepthRenders.begin(); cmd != m_refBaseDepthRenders.end(); ++cmd)
index 518d608..4837128 100644 (file)
@@ -1148,7 +1148,15 @@ public:
                de::Random rnd(0xabcdef);
 
                GLint maxViewportDimensions[2] = {0};
+               GLfloat viewportBoundsRange[2] = {0.0f};
+               GLboolean hasViewportArray = false;
                glGetIntegerv(GL_MAX_VIEWPORT_DIMS, maxViewportDimensions);
+               hasViewportArray = m_context.getContextInfo().isExtensionSupported("GL_OES_viewport_array") ||
+                                                  m_context.getContextInfo().isExtensionSupported("GL_NV_viewport_array");
+               if (hasViewportArray)
+               {
+                       glGetFloatv(GL_VIEWPORT_BOUNDS_RANGE, viewportBoundsRange);
+               }
 
                // verify initial value of first two values
                m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, 0, 0, m_context.getRenderTarget().getWidth(), m_context.getRenderTarget().getHeight());
@@ -1163,7 +1171,19 @@ public:
                        GLsizei height  = rnd.getInt(0, maxViewportDimensions[1]);
 
                        glViewport(x, y, width, height);
-                       m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, x, y, width, height);
+
+                       if (hasViewportArray)
+                       {
+                               m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT,
+                                                                                  de::clamp(x, deFloorFloatToInt32(viewportBoundsRange[0]), deFloorFloatToInt32(viewportBoundsRange[1])),
+                                                                                  de::clamp(y, deFloorFloatToInt32(viewportBoundsRange[0]), deFloorFloatToInt32(viewportBoundsRange[1])),
+                                                                                  width, height);
+                       }
+                       else
+                       {
+                               m_verifier->verifyInteger4(m_testCtx, GL_VIEWPORT, x, y, width, height);
+                       }
+
                        expectError(GL_NO_ERROR);
                }
        }
index 93fdd5a..e14fd9d 100644 (file)
@@ -2065,9 +2065,9 @@ void NegativeTextureApiTests::init (void)
                        m_log << TestLog::EndSection;
 
                        m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if target is GL_TEXTURE_3D and format is GL_DEPTH_COMPONENT, or GL_DEPTH_STENCIL.");
-                       glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_BYTE, 0);
+                       glTexImage3D(GL_TEXTURE_3D, 0, GL_DEPTH_STENCIL, 1, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0);
                        expectError(GL_INVALID_OPERATION);
-                       glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 1, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
+                       glTexImage3D(GL_TEXTURE_3D, 0, GL_DEPTH_COMPONENT, 1, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
                        expectError(GL_INVALID_OPERATION);
                        m_log << TestLog::EndSection;
 
index 554539d..7352ee6 100644 (file)
@@ -478,7 +478,7 @@ tcu::Vec4 UsageDisplacementTestCase::genRandomVec4 (de::Random& rnd) const
 
        retVal.x() = rnd.getFloat(-1, 1);
        retVal.y() = rnd.getFloat(-1, 1);
-       retVal.z() = rnd.getFloat(-0.9f, 0.9f);
+       retVal.z() = 0.5f;
        retVal.w() = 1.0f + rnd.getFloat();
 
        return retVal;
index 2ca18da..da216fc 100644 (file)
@@ -187,28 +187,7 @@ public:
        IterateResult                           iterate                                         (void);
 
 protected:
-       bool                                            compare                                         (float in0, float in1, double reference, float result)
-#if (DE_COMPILER == DE_COMPILER_GCC) && (DE_CPU == DE_CPU_ARM_64)
-#      if (__GNUC__ == 4) && (__GNUC_MINOR__ == 9) && (__GNUC_PATCHLEVEL__ == 0)
-               // Some prerelease GCC 4.9 versions have a bug in shift right when
-               // targeting ARMv8.
-               //
-               // If compiler wants to perform logical shift by variable/register
-               // in fp/vector registers it uses USHL that selects shift direction
-               // based on shift operand value. Thus for right shifts the shift
-               // operand needs to be negated.
-               //
-               // The bug is in right shift pattern; it doesn't mark shift operand
-               // as clobbered and thus later code using that same register may
-               // see the negated value.
-               //
-               // Workaround is to disable optimization for this function.
-               //
-               // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61633
-               __attribute__((optimize(0)))
-#      endif
-#endif
-       ;
+       bool                                            compare                                         (float in0, float in1, double reference, float result);
 
 private:
                                                                ShaderFloatPrecisionCase        (const ShaderFloatPrecisionCase& other);
index 8e5b0ec..3a634a8 100644 (file)
@@ -1080,14 +1080,13 @@ protected:
                int                                             pixelSize               = m_texFormat.getPixelSize();
                int                                             rowLength               = m_rowLength > 0 ? m_rowLength : m_width;
                int                                             rowPitch                = deAlign32(rowLength*pixelSize, m_alignment);
-               int                                             height                  = m_height + m_skipRows;
                deUint32                                tex                             = 0;
                vector<deUint8>                 data;
 
                DE_ASSERT(m_numLevels == 1);
 
                // Fill data with grid.
-               data.resize(rowPitch*height);
+               data.resize(pixelSize * m_skipPixels + rowPitch * (m_height + m_skipRows));
                {
                        Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
                        Vec4    cBias           = m_texFormatInfo.valueMin;
@@ -1157,7 +1156,7 @@ protected:
                DE_ASSERT(m_numLevels == 1);
 
                // Fill data with grid.
-               data.resize(slicePitch*(m_depth+m_skipImages));
+               data.resize(pixelSize * m_skipPixels + rowPitch * m_skipRows + slicePitch * (m_skipImages + m_depth));
                {
                        Vec4    cScale          = m_texFormatInfo.valueMax-m_texFormatInfo.valueMin;
                        Vec4    cBias           = m_texFormatInfo.valueMin;
index bcd79a5..b8de44d 100644 (file)
@@ -6018,7 +6018,7 @@ static float sumOfRanks (const std::vector<deUint64>& testSamples, const std::ve
 template <typename Comparer>
 static DistributionCompareResult distributionCompare (const std::vector<deUint64>& orderedObservationsA, const std::vector<deUint64>& orderedObservationsB, const Comparer& comparer)
 {
-       // Mann\96Whitney U test
+       // Mann-Whitney U test
 
        const int                               n1                      = (int)orderedObservationsA.size();
        const int                               n2                      = (int)orderedObservationsB.size();
index 1f57b59..2f2429e 100644 (file)
@@ -43,6 +43,8 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fShaderAtomicOpTests.hpp
        es31fShaderImageLoadStoreTests.cpp
        es31fShaderImageLoadStoreTests.hpp
+       es31fSRGBDecodeTests.cpp
+       es31fSRGBDecodeTests.hpp
        es31fSSBOLayoutCase.cpp
        es31fSSBOLayoutCase.hpp
        es31fSSBOLayoutTests.cpp
@@ -157,6 +159,8 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fNegativePreciseTests.hpp
        es31fNegativeAdvancedBlendEquationTests.cpp
        es31fNegativeAdvancedBlendEquationTests.hpp
+       es31fNegativeTessellationTests.cpp
+       es31fNegativeTessellationTests.hpp
        es31fTextureGatherTests.cpp
        es31fTextureGatherTests.hpp
        es31fTextureFormatTests.cpp
@@ -173,6 +177,10 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fCopyImageTests.cpp
        es31fDrawBuffersIndexedTests.hpp
        es31fDrawBuffersIndexedTests.cpp
+       es31fNegativeShaderStorageTests.cpp
+       es31fNegativeShaderStorageTests.hpp
+       es31fNegativeSSBOBlockTests.cpp
+       es31fNegativeSSBOBlockTests.hpp
        )
 
 add_library(deqp-gles31-functional STATIC ${DEQP_GLES31_FUNCTIONAL_SRCS})
index b4e9642..4d215c2 100644 (file)
@@ -63,7 +63,9 @@ using namespace deqp::gls::TextureTestUtil;
 using namespace glu::TextureTestUtil;
 
 using tcu::Float;
+using tcu::IVec2;
 using tcu::IVec3;
+using tcu::IVec4;
 using tcu::Sampler;
 using tcu::ScopedLogSection;
 using tcu::TestLog;
@@ -118,6 +120,12 @@ enum ViewClass
        VIEWCLASS_ASTC_12x12_RGBA
 };
 
+enum Verify
+{
+       VERIFY_NONE = 0,
+       VERIFY_COMPARE_REFERENCE
+};
+
 const char* viewClassToName (ViewClass viewClass)
 {
        switch (viewClass)
@@ -249,6 +257,91 @@ int getTargetTexDims (deUint32 target)
        }
 }
 
+class RandomizedRenderGrid
+{
+public:
+                                       RandomizedRenderGrid    (const IVec2& targetSize, const IVec2& cellSize, int maxCellCount, deUint32 seed);
+       bool                    nextCell                                (void);
+       IVec2                   getOrigin                               (void) const;
+
+       const IVec2&    getCellSize                             (void) const { return m_cellSize; };
+       IVec4                   getUsedAreaBoundingBox  (void) const;
+       int                             getCellCount                    (void) const { return m_cellCount; };
+
+private:
+       static IVec2    getRandomOffset                 (deUint32 seed, IVec2 targetSize, IVec2 cellSize, IVec2 grid, int cellCount);
+
+       const IVec2             m_targetSize;
+       const IVec2             m_cellSize;
+       const IVec2             m_grid;
+       int                             m_currentCell;
+       const int               m_cellCount;
+       const IVec2             m_baseRandomOffset;
+};
+
+RandomizedRenderGrid::RandomizedRenderGrid (const IVec2& targetSize, const IVec2& cellSize, int maxCellCount, deUint32 seed)
+       : m_targetSize                  (targetSize)
+       , m_cellSize                    (cellSize)
+       , m_grid                                (targetSize / cellSize)
+       , m_currentCell                 (0)
+       // If the grid exactly fits height, take one row for randomization.
+       , m_cellCount                   (deMin32(maxCellCount, ((targetSize.y() % cellSize.y()) == 0) && m_grid.y() > 1 ? m_grid.x() * (m_grid.y() - 1) :  m_grid.x() * m_grid.y()))
+       , m_baseRandomOffset    (getRandomOffset(seed, targetSize, cellSize, m_grid, m_cellCount))
+{
+}
+
+IVec2 RandomizedRenderGrid::getRandomOffset (deUint32 seed, IVec2 targetSize, IVec2 cellSize, IVec2 grid, int cellCount)
+{
+       de::Random      rng                     (seed);
+       IVec2           result;
+       IVec2           extraSpace = targetSize - (cellSize * grid);
+
+       // If there'll be unused rows, donate them into extra space.
+       // (Round the required rows to full cell row to find out how many rows are unused, multiply by size)
+       DE_ASSERT(deDivRoundUp32(cellCount, grid.x()) <= grid.y());
+       extraSpace.y() += (grid.y() - deDivRoundUp32(cellCount, grid.x())) * cellSize.y();
+
+       DE_ASSERT(targetSize.x() > cellSize.x() && targetSize.y() > cellSize.y());
+       // If grid fits perfectly just one row of cells, just give up on randomizing.
+       DE_ASSERT(extraSpace.x() > 0 || extraSpace.y() > 0 || grid.y() == 1);
+       DE_ASSERT(extraSpace.x() + grid.x() * cellSize.x() == targetSize.x());
+
+       // \note Putting these as ctor params would make evaluation order undefined, I think <sigh>. Hence,
+       // no direct return.
+       result.x() = rng.getInt(0, extraSpace.x());
+       result.y() = rng.getInt(0, extraSpace.y());
+       return result;
+}
+
+bool RandomizedRenderGrid::nextCell (void)
+{
+       if (m_currentCell >= getCellCount())
+               return false;
+
+       m_currentCell++;
+       return true;
+}
+
+IVec2 RandomizedRenderGrid::getOrigin (void) const
+{
+       const int       gridX             = (m_currentCell - 1) % m_grid.x();
+       const int       gridY             = (m_currentCell - 1) / m_grid.x();
+       const IVec2 currentOrigin = (IVec2(gridX, gridY) * m_cellSize) + m_baseRandomOffset;
+
+       DE_ASSERT(currentOrigin.x() >= 0 && (currentOrigin.x() + m_cellSize.x()) <= m_targetSize.x());
+       DE_ASSERT(currentOrigin.y() >= 0 && (currentOrigin.y() + m_cellSize.y()) <= m_targetSize.y());
+
+       return currentOrigin;
+}
+
+IVec4 RandomizedRenderGrid::getUsedAreaBoundingBox (void) const
+{
+       const IVec2 lastCell    (de::min(m_currentCell + 1, m_grid.x()), ((m_currentCell + m_grid.x() - 1) / m_grid.x()));
+       const IVec2 size                = lastCell * m_cellSize;
+
+       return IVec4(m_baseRandomOffset.x(), m_baseRandomOffset.y(), size.x(), size.y());
+}
+
 class ImageInfo
 {
 public:
@@ -309,6 +402,182 @@ int getLevelCount (const ImageInfo& info)
        }
 }
 
+IVec3 getLevelSize (deUint32 target, const IVec3& baseSize, int level)
+{
+       IVec3 size;
+
+       if (target != GL_TEXTURE_2D_ARRAY)
+       {
+               for (int i = 0; i < 3; i++)
+                       size[i] = de::max(baseSize[i] >> level, 1);
+       }
+       else
+       {
+               for (int i = 0; i < 2; i++)
+                       size[i] = de::max(baseSize[i] >> level, 1);
+
+               size[2] = baseSize[2];
+       }
+
+       return size;
+}
+
+deUint32 mapFaceNdxToFace (int ndx)
+{
+       const deUint32 cubeFaces[] =
+       {
+               GL_TEXTURE_CUBE_MAP_POSITIVE_X,
+               GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
+
+               GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
+               GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
+
+               GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+               GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+       };
+
+       return de::getSizedArrayElement<6>(cubeFaces, ndx);
+}
+
+// Class for iterating over mip levels and faces/slices/... of a texture.
+class TextureImageIterator
+{
+public:
+                                               TextureImageIterator    (const ImageInfo info, int levelCount);
+                                               ~TextureImageIterator   (void)                                                  {}
+
+       // Need to call next image once, newly constructed not readable, except for getSize
+       bool                            nextImage                               (void);
+       bool                            hasNextImage                    (void) const                                    { return (m_currentLevel < (m_levelCount - 1)) || m_currentImage < (m_levelImageCount - 1); }
+
+       int                                     getMipLevel                             (void) const                                    { return m_currentLevel; }
+       int                                     getMipLevelCount                (void) const                                    { return m_levelCount; }
+       int                                     getCurrentImage                 (void) const                                    { return m_currentImage;}
+       int                                     getLevelImageCount              (void) const                                    { return m_levelImageCount; }
+       IVec2                           getSize                                 (void) const                                    { return m_levelSize.toWidth<2>(); }    // Assume that image sizes never grow over iteration
+       deUint32                        getTarget                               (void) const                                    { return m_info.getTarget(); }
+
+private:
+       int                                     m_levelImageCount;              // Need to be defined in CTOR for the hasNextImage to work!
+       const ImageInfo         m_info;
+       int                                     m_currentLevel;
+       IVec3                           m_levelSize;
+       int                                     m_currentImage;
+       const int                       m_levelCount;
+};
+
+TextureImageIterator::TextureImageIterator (const ImageInfo info, int levelCount)
+       : m_levelImageCount     (info.getTarget() == GL_TEXTURE_CUBE_MAP ? 6 : getLevelSize(info.getTarget(), info.getSize(), 0).z())
+       , m_info                        (info)
+       , m_currentLevel        (0)
+       , m_levelSize           (getLevelSize(info.getTarget(), info.getSize(), 0))
+       , m_currentImage        (-1)
+       , m_levelCount          (levelCount)
+{
+       DE_ASSERT(m_levelCount <= getLevelCount(info));
+}
+
+bool TextureImageIterator::nextImage (void)
+{
+       if (!hasNextImage())
+               return false;
+
+       m_currentImage++;
+       if (m_currentImage == m_levelImageCount)
+       {
+               m_currentLevel++;
+               m_currentImage          = 0;
+
+               m_levelSize                     = getLevelSize(m_info.getTarget(), m_info.getSize(), m_currentLevel);
+
+               if (getTarget() == GL_TEXTURE_CUBE_MAP)
+                       m_levelImageCount = 6;
+               else
+                       m_levelImageCount = m_levelSize.z();
+       }
+       DE_ASSERT(m_currentLevel < m_levelCount);
+       DE_ASSERT(m_currentImage < m_levelImageCount);
+       return true;
+}
+
+// Get name
+string getTextureImageName (int textureTarget, int mipLevel, int imageIndex)
+{
+       std::ostringstream result;
+       result << "Level";
+       result << mipLevel;
+       switch (textureTarget)
+       {
+               case GL_TEXTURE_2D:                     break;
+               case GL_TEXTURE_3D:                     result << "Slice" << imageIndex; break;
+               case GL_TEXTURE_CUBE_MAP:       result << "Face" << imageIndex; break;
+               case GL_TEXTURE_2D_ARRAY:       result << "Layer" << imageIndex; break;
+               default:
+                       DE_FATAL("Unsupported texture target");
+                       break;
+       }
+       return result.str();
+}
+
+// Get description
+string getTextureImageDescription (int textureTarget, int mipLevel, int imageIndex)
+{
+       std::ostringstream result;
+       result << "level ";
+       result << mipLevel;
+
+       switch (textureTarget)
+       {
+               case GL_TEXTURE_2D:                     break;
+               case GL_TEXTURE_3D:                     result << " and Slice " << imageIndex; break;
+               case GL_TEXTURE_CUBE_MAP:       result << " and Face " << imageIndex; break;
+               case GL_TEXTURE_2D_ARRAY:       result << " and Layer " << imageIndex; break;
+               default:
+                       DE_FATAL("Unsupported texture target");
+                       break;
+       }
+       return result.str();
+}
+
+// Compute texture coordinates
+void computeQuadTexCoords(vector<float>& texCoord, const TextureImageIterator& iteration)
+{
+       const int currentImage = iteration.getCurrentImage();
+       switch (iteration.getTarget())
+       {
+               case GL_TEXTURE_2D:
+                       computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
+                       break;
+
+               case GL_TEXTURE_3D:
+               {
+                       const float r = (float(currentImage) + 0.5f) / (float)iteration.getLevelImageCount();
+                       computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0, 1, 2));
+                       break;
+               }
+
+               case GL_TEXTURE_CUBE_MAP:
+                       computeQuadTexCoordCube(texCoord, glu::getCubeFaceFromGL(mapFaceNdxToFace(currentImage)));
+                       break;
+
+               case GL_TEXTURE_2D_ARRAY:
+                       computeQuadTexCoord2DArray(texCoord, currentImage, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported texture target");
+       }
+}
+
+// Struct for storing each reference image with necessary metadata.
+struct CellContents
+{
+       IVec2                   origin;
+       tcu::Surface    reference;
+       std::string             name;
+       std::string             description;
+};
+
 // Return format that has more restrictions on texel data.
 deUint32 getMoreRestrictiveFormat (deUint32 formatA, deUint32 formatB)
 {
@@ -358,26 +627,6 @@ IVec3 getTexelBlockPixelSize (deUint32 format)
                return IVec3(1, 1, 1);
 }
 
-IVec3 getLevelSize (deUint32 target, const IVec3& baseSize, int level)
-{
-       IVec3 size;
-
-       if (target != GL_TEXTURE_2D_ARRAY)
-       {
-               for (int i = 0; i < 3; i++)
-                       size[i] = de::max(baseSize[i] >> level, 1);
-       }
-       else
-       {
-               for (int i = 0; i < 2; i++)
-                       size[i] = de::max(baseSize[i] >> level, 1);
-
-               size[2] = baseSize[2];
-       }
-
-       return size;
-}
-
 bool isColorRenderable (deUint32 format)
 {
        switch (format)
@@ -502,23 +751,6 @@ IVec3 divRoundUp (const IVec3& a, const IVec3& b)
        return res;
 }
 
-deUint32 mapFaceNdxToFace (int ndx)
-{
-       const deUint32 cubeFaces[] =
-       {
-               GL_TEXTURE_CUBE_MAP_POSITIVE_X,
-               GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
-
-               GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
-               GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
-
-               GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
-               GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
-       };
-
-       return de::getSizedArrayElement<6>(cubeFaces, ndx);
-}
-
 deUint32 getFormatForInternalFormat (deUint32 format)
 {
        return glu::getTransferFormat(glu::mapGLInternalFormat(format)).format;
@@ -891,22 +1123,119 @@ void copyImage (const glw::Functions&                                   gl,
                                  srcImageData, srcImageInfo, srcLevel, srcPos, copySize);
 }
 
-void verifyTexture2DView (tcu::TestContext&                    testContext,
+template<class TextureView>
+void renderTexture (glu::RenderContext&                renderContext,
+                                       TextureRenderer&                renderer,
+                                       ReferenceParams&                renderParams,
+                                       tcu::ResultCollector&   results,
+                                       de::Random&                             rng,
+                                       const TextureView&              refTexture,
+                                       const Verify                    verify,
+                                       TextureImageIterator&   imageIterator,
+                                       tcu::TestLog&                   log)
+{
+       const tcu::RenderTarget&        renderTarget            = renderContext.getRenderTarget();
+       const tcu::RGBA                         threshold                       = renderTarget.getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
+       const glw::Functions&           gl                                      = renderContext.getFunctions();
+       const IVec2                                     renderTargetSize        = IVec2(renderTarget.getWidth(), renderTarget.getHeight());
+
+       while (imageIterator.hasNextImage())
+       {
+               // \note: Reserve space upfront to avoid assigning tcu::Surface, which incurs buffer mem copy. Using a
+               // conservative estimate for simplicity
+               const int                               imagesOnLevel   = imageIterator.getLevelImageCount();
+               const int                               imageEstimate   = (imageIterator.getMipLevelCount() - imageIterator.getMipLevel()) * imagesOnLevel;
+               RandomizedRenderGrid    renderGrid              (renderTargetSize, imageIterator.getSize(), imageEstimate, rng.getUint32());
+               vector<CellContents>    cellContents    (renderGrid.getCellCount());
+               int                                             cellsUsed               = 0;
+
+               // \note: Ordering of conditions is significant. If put the other way around, the code would skip one of the
+               // images if the grid runs out of cells before the texture runs out of images. Advancing one grid cell over the
+               // needed number has no negative impact.
+               while (renderGrid.nextCell() && imageIterator.nextImage())
+               {
+                       const int               level     = imageIterator.getMipLevel();
+                       const IVec2             levelSize = imageIterator.getSize();
+                       const IVec2             origin    = renderGrid.getOrigin();
+                       vector<float>   texCoord;
+
+                       DE_ASSERT(imageIterator.getTarget() != GL_TEXTURE_CUBE_MAP || levelSize.x() >= 4 || levelSize.y() >= 4);
+
+                       renderParams.baseLevel  = level;
+                       renderParams.maxLevel   = level;
+
+                       gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_BASE_LEVEL, level);
+                       gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_MAX_LEVEL, level);
+
+                       computeQuadTexCoords(texCoord, imageIterator);
+
+                       // Setup base viewport.
+                       gl.viewport(origin.x(), origin.y(), levelSize.x(), levelSize.y());
+
+                       // Draw.
+                       renderer.renderQuad(0, &texCoord[0], renderParams);
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render.");
+
+                       if (verify == VERIFY_COMPARE_REFERENCE)
+                       {
+                               const int       target                                  = imageIterator.getTarget();
+                               const int       imageIndex                              = imageIterator.getCurrentImage();
+
+                               cellContents[cellsUsed].origin          = origin;
+                               cellContents[cellsUsed].name            = getTextureImageName(target, level, imageIndex);
+                               cellContents[cellsUsed].description     = getTextureImageDescription(target, level, imageIndex);
+
+                               cellContents[cellsUsed].reference.setSize(levelSize.x(), levelSize.y());
+
+                               // Compute reference.
+                               sampleTexture(tcu::SurfaceAccess(cellContents[cellsUsed].reference, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
+                               cellsUsed++;
+                       }
+               }
+
+               if (cellsUsed > 0)
+               {
+                       const IVec4             boundingBox             = renderGrid.getUsedAreaBoundingBox();
+                       tcu::Surface    renderedFrame   (boundingBox[2], boundingBox[3]);
+
+                       glu::readPixels(renderContext, boundingBox.x(), boundingBox.y(), renderedFrame.getAccess());
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to read pixels.");
+
+                       for (int idx = 0; idx < cellsUsed; idx++)
+                       {
+                               const CellContents&                                     cell             (cellContents[idx]);
+                               const IVec2                                                     cellOrigin       = cell.origin - boundingBox.toWidth<2>();
+                               const tcu::ConstPixelBufferAccess       resultAccess = getSubregion(renderedFrame.getAccess(), cellOrigin.x(), cellOrigin.y(), cell.reference.getWidth(), cell.reference.getHeight());
+
+                               if (!intThresholdCompare(log, cell.name.c_str(), cell.description.c_str(), cell.reference.getAccess(), resultAccess, threshold.toIVec().cast<deUint32>(), tcu::COMPARE_LOG_ON_ERROR))
+                                       results.fail("Image comparison of " + cell.description + " failed.");
+                               else
+                                       log << TestLog::Message << "Image comparison of " << cell.description << " passed." << TestLog::EndMessage;;
+                       }
+               }
+       }
+
+       gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_BASE_LEVEL, 0);
+       gl.texParameteri(imageIterator.getTarget(), GL_TEXTURE_MAX_LEVEL, 1000);
+}
+
+void renderTexture2DView (tcu::TestContext&                    testContext,
                                                  glu::RenderContext&           renderContext,
                                                  TextureRenderer&                      renderer,
                                                  tcu::ResultCollector&         results,
                                                  de::Random&                           rng,
                                                  deUint32                                      name,
                                                  const ImageInfo&                      info,
-                                                 const tcu::Texture2DView&     refTexture)
+                                                 const tcu::Texture2DView&     refTexture,
+                                                 Verify                                        verify)
 {
        tcu::TestLog&                                   log                             = testContext.getLog();
        const glw::Functions&                   gl                              = renderContext.getFunctions();
-       const tcu::RGBA                                 threshold               = renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
        const tcu::TextureFormat                format                  = refTexture.getLevel(0).getFormat();
        const tcu::TextureFormatInfo    spec                    = tcu::getTextureFormatInfo(format);
 
        ReferenceParams                                 renderParams    (TEXTURETYPE_2D);
+       TextureImageIterator                    imageIterator   (info, getLevelCount(info));
 
        renderParams.samplerType        = getSamplerType(format);
        renderParams.sampler            = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
@@ -923,43 +1252,7 @@ void verifyTexture2DView (tcu::TestContext&                       testContext,
        gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
 
-       for (int level = 0; level < getLevelCount(info); level++)
-       {
-               const IVec3                             levelSize               = getLevelSize(info.getTarget(), info.getSize(), level);
-               const RandomViewport    viewport                (renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
-
-               vector<float>                   texCoord;
-               tcu::Surface                    renderedFrame   (viewport.width, viewport.height);
-               tcu::Surface                    referenceFrame  (viewport.width, viewport.height);
-
-               renderParams.baseLevel  = level;
-               renderParams.maxLevel   = level;
-
-               gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, level);
-               gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
-
-               computeQuadTexCoord2D(texCoord, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
-
-               // Setup base viewport.
-               gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
-
-               // Draw.
-               renderer.renderQuad(0, &texCoord[0], renderParams);
-               glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
-               GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
-
-               // Compute reference.
-               sampleTexture(tcu::SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
-
-               // Compare and log.
-               if (!pixelThresholdCompare(log, ("Level" + de::toString(level)).c_str(), ("Render level " + de::toString(level)).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
-                       results.fail("Image comparison of level " + de::toString(level) + " failed.");
-               else
-                       log << TestLog::Message << "Image comparison of level " << level << " passed." << TestLog::EndMessage;
-       }
-
-       gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
-       gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1000);
+       renderTexture<tcu::Texture2DView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);
 
        gl.bindTexture(GL_TEXTURE_2D, 0);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
@@ -1016,14 +1309,15 @@ void decompressTexture (vector<ArrayBuffer<deUint8> >&                  levelDatas,
        }
 }
 
-void verifyTexture2D (tcu::TestContext&                                                testContext,
+void renderTexture2D (tcu::TestContext&                                                testContext,
                                          glu::RenderContext&                                   renderContext,
                                          TextureRenderer&                                              textureRenderer,
                                          tcu::ResultCollector&                                 results,
                                          de::Random&                                                   rng,
                                          deUint32                                                              name,
                                          const vector<ArrayBuffer<deUint8> >&  data,
-                                         const ImageInfo&                                              info)
+                                         const ImageInfo&                                              info,
+                                         Verify                                                                verify)
 {
        if (glu::isCompressedFormat(info.getFormat()))
        {
@@ -1035,7 +1329,7 @@ void verifyTexture2D (tcu::TestContext&                                           testContext,
                {
                        const tcu::Texture2DView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));
 
-                       verifyTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+                       renderTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
                }
        }
        else
@@ -1043,26 +1337,27 @@ void verifyTexture2D (tcu::TestContext&                                         testContext,
                const vector<tcu::ConstPixelBufferAccess>       levelAccesses   = getLevelAccesses(data, info);
                const tcu::Texture2DView                                        refTexture              ((int)levelAccesses.size(), &(levelAccesses[0]));
 
-               verifyTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+               renderTexture2DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
        }
 }
 
-void verifyTexture3DView (tcu::TestContext&                    testContext,
+void renderTexture3DView (tcu::TestContext&                    testContext,
                                                  glu::RenderContext&           renderContext,
                                                  TextureRenderer&                      renderer,
                                                  tcu::ResultCollector&         results,
                                                  de::Random&                           rng,
                                                  deUint32                                      name,
                                                  const ImageInfo&                      info,
-                                                 const tcu::Texture3DView&     refTexture)
+                                                 const tcu::Texture3DView&     refTexture,
+                                                 Verify                                        verify)
 {
        tcu::TestLog&                                   log                             = testContext.getLog();
        const glw::Functions&                   gl                              = renderContext.getFunctions();
-       const tcu::RGBA                                 threshold               = renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
        const tcu::TextureFormat                format                  = refTexture.getLevel(0).getFormat();
        const tcu::TextureFormatInfo    spec                    = tcu::getTextureFormatInfo(format);
 
        ReferenceParams                                 renderParams    (TEXTURETYPE_3D);
+       TextureImageIterator                    imageIterator   (info, getLevelCount(info));
 
        renderParams.samplerType        = getSamplerType(format);
        renderParams.sampler            = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
@@ -1080,60 +1375,21 @@ void verifyTexture3DView (tcu::TestContext&                     testContext,
        gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
 
-       for (int level = 0; level < getLevelCount(info); level++)
-       {
-               const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);
-
-               renderParams.baseLevel  = level;
-               renderParams.maxLevel   = level;
-
-               gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, level);
-               gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, level);
-
-               for (int slice = 0; slice < levelSize.z(); slice++)
-               {
-                       const RandomViewport    viewport                (renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
-                       const float                             r                               = (float(slice) + 0.5f) / (float)levelSize.z();
-                       tcu::Surface                    renderedFrame   (viewport.width, viewport.height);
-                       tcu::Surface                    referenceFrame  (viewport.width, viewport.height);
-                       vector<float>                   texCoord;
-
-                       computeQuadTexCoord3D(texCoord, tcu::Vec3(0.0f, 0.0f, r), tcu::Vec3(1.0f, 1.0f, r), tcu::IVec3(0, 1, 2));
-
-                       // Setup base viewport.
-                       gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
-
-                       // Draw.
-                       renderer.renderQuad(0, &texCoord[0], renderParams);
-                       glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
-                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
-
-                       // Compute reference.
-                       sampleTexture(tcu::SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
-
-                       // Compare and log.
-                       if (!pixelThresholdCompare(log, ("Level" + de::toString(level) + "Slice" + de::toString(slice)).c_str(), ("Render level " + de::toString(level) + ", Slice" + de::toString(slice)).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
-                               results.fail("Image comparison of level " + de::toString(level) + " and slice " + de::toString(slice) + " failed.");
-                       else
-                               log << TestLog::Message << "Image comparison of level " << level << " and slice " << slice << " passed." << TestLog::EndMessage;;
-               }
-       }
-
-       gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0);
-       gl.texParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 1000);
+       renderTexture<tcu::Texture3DView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);
 
        gl.bindTexture(GL_TEXTURE_3D, 0);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
 }
 
-void verifyTexture3D (tcu::TestContext&                                                testContext,
+void renderTexture3D (tcu::TestContext&                                                testContext,
                                          glu::RenderContext&                                   renderContext,
                                          TextureRenderer&                                              textureRenderer,
                                          tcu::ResultCollector&                                 results,
                                          de::Random&                                                   rng,
                                          deUint32                                                              name,
                                          const vector<ArrayBuffer<deUint8> >&  data,
-                                         const ImageInfo&                                              info)
+                                         const ImageInfo&                                              info,
+                                     Verify                                                            verify)
 {
        if (glu::isCompressedFormat(info.getFormat()))
        {
@@ -1145,7 +1401,7 @@ void verifyTexture3D (tcu::TestContext&                                           testContext,
                {
                        const tcu::Texture3DView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));
 
-                       verifyTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+                       renderTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
                }
        }
        else
@@ -1153,26 +1409,28 @@ void verifyTexture3D (tcu::TestContext&                                         testContext,
                const vector<tcu::ConstPixelBufferAccess>       levelAccesses   = getLevelAccesses(data, info);
                const tcu::Texture3DView                                        refTexture              ((int)levelAccesses.size(), &(levelAccesses[0]));
 
-               verifyTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+               renderTexture3DView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
        }
 }
 
-void verifyTextureCubemapView (tcu::TestContext&                       testContext,
+void renderTextureCubemapView (tcu::TestContext&                       testContext,
                                                           glu::RenderContext&                  renderContext,
                                                           TextureRenderer&                             renderer,
                                                           tcu::ResultCollector&                results,
                                                           de::Random&                                  rng,
                                                           deUint32                                             name,
                                                           const ImageInfo&                             info,
-                                                          const tcu::TextureCubeView&  refTexture)
+                                                          const tcu::TextureCubeView&  refTexture,
+                                                          Verify                                               verify)
 {
        tcu::TestLog&                                   log                             = testContext.getLog();
        const glw::Functions&                   gl                              = renderContext.getFunctions();
-       const tcu::RGBA                                 threshold               = renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
        const tcu::TextureFormat                format                  = refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X).getFormat();
        const tcu::TextureFormatInfo    spec                    = tcu::getTextureFormatInfo(format);
 
        ReferenceParams                                 renderParams    (TEXTURETYPE_CUBE);
+    // \note It seems we can't reliably sample two smallest texture levels with cubemaps
+       TextureImageIterator                    imageIterator   (info, getLevelCount(info) - 2);
 
        renderParams.samplerType        = getSamplerType(format);
        renderParams.sampler            = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
@@ -1189,64 +1447,21 @@ void verifyTextureCubemapView (tcu::TestContext&                        testContext,
        gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
 
-       for (int level = 0; level < getLevelCount(info); level++)
-       {
-               const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);
-
-               // \note It seems we can't reliably sample two smallest texture levels with cubemaps
-               if (levelSize.x() < 4 && levelSize.y() < 4)
-                       continue;
-
-               renderParams.baseLevel  = level;
-               renderParams.maxLevel   = level;
-
-               gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, level);
-               gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, level);
-
-               for (int face = 0; face < 6; face++)
-               {
-                       const RandomViewport    viewport                (renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
-                       const string                    cubemapFaceName = glu::getCubeMapFaceStr(mapFaceNdxToFace(face)).toString();
-                       tcu::Surface                    renderedFrame   (viewport.width, viewport.height);
-                       tcu::Surface                    referenceFrame  (viewport.width, viewport.height);
-                       vector<float>                   texCoord;
-
-                       computeQuadTexCoordCube(texCoord, glu::getCubeFaceFromGL(mapFaceNdxToFace(face)));
-
-                       // Setup base viewport.
-                       gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
-
-                       // Draw.
-                       renderer.renderQuad(0, &texCoord[0], renderParams);
-                       glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
-                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
-
-                       // Compute reference.
-                       sampleTexture(tcu::SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
-
-                       // Compare and log.
-                       if (!pixelThresholdCompare(log, ("Level" + de::toString(level) + "Face" + cubemapFaceName).c_str(), ("Render level " + de::toString(level) + ", Face " + cubemapFaceName).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
-                               results.fail("Image comparison of level " + de::toString(level) + " and face " + cubemapFaceName + " failed.");
-                       else
-                               log << TestLog::Message << "Image comparison of level " << level << " and face " << cubemapFaceName << " passed." << TestLog::EndMessage;
-               }
-       }
-
-       gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_BASE_LEVEL, 0);
-       gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 1000);
+       renderTexture<tcu::TextureCubeView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);
 
        gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
 }
 
-void verifyTextureCubemap (tcu::TestContext&                                   testContext,
+void renderTextureCubemap (tcu::TestContext&                                   testContext,
                                                   glu::RenderContext&                                  renderContext,
                                                   TextureRenderer&                                             textureRenderer,
                                                   tcu::ResultCollector&                                results,
                                                   de::Random&                                                  rng,
                                                   deUint32                                                             name,
                                                   const vector<ArrayBuffer<deUint8> >& data,
-                                                  const ImageInfo&                                             info)
+                                                  const ImageInfo&                                             info,
+                                                  Verify                                                               verify)
 {
        if (glu::isCompressedFormat(info.getFormat()))
        {
@@ -1304,7 +1519,7 @@ void verifyTextureCubemap (tcu::TestContext&                                      testContext,
                {
                        const tcu::TextureCubeView refTexture(getLevelCount(info), levels);
 
-                       verifyTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+                       renderTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
                }
        }
        else
@@ -1327,27 +1542,28 @@ void verifyTextureCubemap (tcu::TestContext&                                    testContext,
                {
                        const tcu::TextureCubeView refTexture(getLevelCount(info), levels);
 
-                       verifyTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+                       renderTextureCubemapView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
                }
        }
 }
 
-void verifyTexture2DArrayView (tcu::TestContext&                               testContext,
+void renderTexture2DArrayView (tcu::TestContext&                               testContext,
                                                           glu::RenderContext&                          renderContext,
                                                           TextureRenderer&                                     renderer,
                                                           tcu::ResultCollector&                        results,
                                                           de::Random&                                          rng,
                                                           deUint32                                                     name,
                                                           const ImageInfo&                                     info,
-                                                          const tcu::Texture2DArrayView&       refTexture)
+                                                          const tcu::Texture2DArrayView&       refTexture,
+                                                          Verify                                                       verify)
 {
        tcu::TestLog&                                   log                             = testContext.getLog();
        const glw::Functions&                   gl                              = renderContext.getFunctions();
-       const tcu::RGBA                                 threshold               = renderContext.getRenderTarget().getPixelFormat().getColorThreshold() + tcu::RGBA(1,1,1,1);
        const tcu::TextureFormat                format                  = refTexture.getLevel(0).getFormat();
        const tcu::TextureFormatInfo    spec                    = tcu::getTextureFormatInfo(format);
 
        ReferenceParams                                 renderParams    (TEXTURETYPE_2D_ARRAY);
+       TextureImageIterator                    imageIterator   (info, getLevelCount(info));
 
        renderParams.samplerType        = getSamplerType(format);
        renderParams.sampler            = Sampler(Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::CLAMP_TO_EDGE, Sampler::NEAREST_MIPMAP_NEAREST, Sampler::NEAREST);
@@ -1364,59 +1580,21 @@ void verifyTexture2DArrayView (tcu::TestContext&                                testContext,
        gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to setup texture filtering state.");
 
-       for (int level = 0; level < getLevelCount(info); level++)
-       {
-               const IVec3 levelSize = getLevelSize(info.getTarget(), info.getSize(), level);
-
-               renderParams.baseLevel  = level;
-               renderParams.maxLevel   = level;
-
-               gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, level);
-               gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, level);
-
-               for (int layer = 0; layer < levelSize.z(); layer++)
-               {
-                       const RandomViewport    viewport                (renderContext.getRenderTarget(), levelSize.x(), levelSize.y(), rng.getUint32());
-                       tcu::Surface                    renderedFrame   (viewport.width, viewport.height);
-                       tcu::Surface                    referenceFrame  (viewport.width, viewport.height);
-                       vector<float>                   texCoord;
-
-                       computeQuadTexCoord2DArray(texCoord, layer, tcu::Vec2(0.0f, 0.0f), tcu::Vec2(1.0f, 1.0f));
-
-                       // Setup base viewport.
-                       gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
-
-                       // Draw.
-                       renderer.renderQuad(0, &texCoord[0], renderParams);
-                       glu::readPixels(renderContext, viewport.x, viewport.y, renderedFrame.getAccess());
-                       GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to render and read pixels.");
-
-                       // Compute reference.
-                       sampleTexture(tcu::SurfaceAccess(referenceFrame, renderContext.getRenderTarget().getPixelFormat()), refTexture, &texCoord[0], renderParams);
-
-                       // Compare and log.
-                       if (!pixelThresholdCompare(log, ("Level" + de::toString(level) + "Layer" + de::toString(layer)).c_str(), ("Render level " + de::toString(level) + ", Layer" + de::toString(layer)).c_str(), referenceFrame, renderedFrame, threshold, tcu::COMPARE_LOG_ON_ERROR))
-                               results.fail("Image comparison of level " + de::toString(level) + " and layer " + de::toString(layer) + " failed.");
-                       else
-                               log << TestLog::Message << "Image comparison of level " << level << " and layer " << layer << " passed." << TestLog::EndMessage;
-               }
-       }
-
-       gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_BASE_LEVEL, 0);
-       gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_LEVEL, 1000);
+       renderTexture<tcu::Texture2DArrayView>(renderContext, renderer, renderParams, results, rng, refTexture, verify, imageIterator, log);
 
        gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind texture.");
 }
 
-void verifyTexture2DArray (tcu::TestContext&                                   testContext,
+void renderTexture2DArray (tcu::TestContext&                                   testContext,
                                                   glu::RenderContext&                                  renderContext,
                                                   TextureRenderer&                                             textureRenderer,
                                                   tcu::ResultCollector&                                results,
                                                   de::Random&                                                  rng,
                                                   deUint32                                                             name,
                                                   const vector<ArrayBuffer<deUint8> >& data,
-                                                  const ImageInfo&                                             info)
+                                                  const ImageInfo&                                             info,
+                                                  Verify                                                               verify)
 {
        if (glu::isCompressedFormat(info.getFormat()))
        {
@@ -1428,7 +1606,7 @@ void verifyTexture2DArray (tcu::TestContext&                                      testContext,
                {
                        const tcu::Texture2DArrayView refTexture((int)levelAccesses.size(), &(levelAccesses[0]));
 
-                       verifyTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+                       renderTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
                }
        }
        else
@@ -1436,7 +1614,7 @@ void verifyTexture2DArray (tcu::TestContext&                                      testContext,
                const vector<tcu::ConstPixelBufferAccess>       levelAccesses   = getLevelAccesses(data, info);
                const tcu::Texture2DArrayView                           refTexture              ((int)levelAccesses.size(), &(levelAccesses[0]));
 
-               verifyTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture);
+               renderTexture2DArrayView(testContext, renderContext, textureRenderer, results, rng, name, info, refTexture, verify);
        }
 }
 
@@ -1480,12 +1658,13 @@ Vec4 calculateThreshold (const tcu::TextureFormat& sourceFormat, const tcu::Text
        }
 }
 
-void verifyRenderbuffer (tcu::TestContext&                                             testContext,
+void renderRenderbuffer (tcu::TestContext&                                             testContext,
                                                 glu::RenderContext&                                    renderContext,
                                                 tcu::ResultCollector&                                  results,
                                                 deUint32                                                               name,
                                                 const vector<ArrayBuffer<deUint8> >&   data,
-                                                const ImageInfo&                                               info)
+                                                const ImageInfo&                                               info,
+                                                Verify                                                                 verify)
 {
        const glw::Functions&                           gl                                      = renderContext.getFunctions();
        TestLog&                                                        log                                     = testContext.getLog();
@@ -1509,71 +1688,76 @@ void verifyRenderbuffer (tcu::TestContext&                                              testContext,
                gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, name);
                GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to bind and attach renderbuffer to framebuffer.");
 
-               glu::readPixels(renderContext, 0, 0, renderbuffer.getAccess());
+               if (verify)
+                       glu::readPixels(renderContext, 0, 0, renderbuffer.getAccess());
 
                gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
                gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
                GLU_EXPECT_NO_ERROR(gl.getError(), "Failed to unbind renderbuffer and framebuffer.");
        }
 
-       if (isFloatFormat(info.getFormat()))
+       if (verify == VERIFY_COMPARE_REFERENCE)
        {
-               const tcu::UVec4 threshold (2, 2, 2, 2);
+               if (isFloatFormat(info.getFormat()))
+               {
+                       const tcu::UVec4 threshold (2, 2, 2, 2);
 
-               if (!(tcu::floatUlpThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
-                       results.fail("Image comparison failed.");
-               else
-                       log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
-       }
-       else if (isIntFormat(info.getFormat()) || isUintFormat(info.getFormat()))
-       {
-               const tcu::UVec4 threshold (1, 1, 1, 1);
+                       if (!(tcu::floatUlpThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
+                               results.fail("Image comparison failed.");
+                       else
+                               log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
+               }
+               else if (isIntFormat(info.getFormat()) || isUintFormat(info.getFormat()))
+               {
+                       const tcu::UVec4 threshold (1, 1, 1, 1);
 
-               if (!(tcu::intThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
-                       results.fail("Image comparison failed.");
+                       if (!(tcu::intThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
+                               results.fail("Image comparison failed.");
+                       else
+                               log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
+               }
                else
-                       log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
-       }
-       else
-       {
-               const Vec4 threshold = calculateThreshold(format, readPixelsFormat);
+               {
+                       const Vec4 threshold = calculateThreshold(format, readPixelsFormat);
 
-               if (!(tcu::floatThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
-                       results.fail("Image comparison failed.");
-               else
-                       log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
+                       if (!(tcu::floatThresholdCompare(log, "Image comparison", "Image comparison", refRenderbuffer, renderbuffer.getAccess(), threshold, tcu::COMPARE_LOG_ON_ERROR)))
+                               results.fail("Image comparison failed.");
+                       else
+                               log << TestLog::Message << "Image comarison passed." << TestLog::EndMessage;
+               }
        }
 }
 
-void verify (tcu::TestContext&                                         testContext,
+void render (tcu::TestContext&                                         testContext,
                         glu::RenderContext&                                    renderContext,
                         TextureRenderer&                                               textureRenderer,
                         tcu::ResultCollector&                                  results,
                         de::Random&                                                    rng,
                         deUint32                                                               name,
                         const vector<ArrayBuffer<deUint8> >&   data,
-                        const ImageInfo&                                               info)
+                        const ImageInfo&                                               info,
+                        Verify                                                                 verify)
 {
        switch (info.getTarget())
        {
                case GL_TEXTURE_2D:
-                       verifyTexture2D(testContext, renderContext, textureRenderer, results, rng, name, data, info);
+                       renderTexture2D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
                        break;
 
                case GL_TEXTURE_3D:
-                       verifyTexture3D(testContext, renderContext, textureRenderer, results, rng, name, data, info);
+                       renderTexture3D(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
                        break;
 
                case GL_TEXTURE_CUBE_MAP:
-                       verifyTextureCubemap(testContext, renderContext, textureRenderer, results, rng, name, data, info);
+                       renderTextureCubemap(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
                        break;
 
                case GL_TEXTURE_2D_ARRAY:
-                       verifyTexture2DArray(testContext, renderContext, textureRenderer, results, rng, name, data, info);
+                       renderTexture2DArray(testContext, renderContext, textureRenderer, results, rng, name, data, info, verify);
                        break;
 
                case GL_RENDERBUFFER:
-                       verifyRenderbuffer(testContext, renderContext, results, name, data, info);
+                       renderRenderbuffer(testContext, renderContext, results, name, data, info, verify);
                        break;
 
                default:
@@ -1626,13 +1810,30 @@ public:
        TestCase::IterateResult iterate                                 (void);
 
 private:
+
        void                                    logTestInfoIter                 (void);
        void                                    createImagesIter                (void);
        void                                    destroyImagesIter               (void);
        void                                    verifySourceIter                (void);
        void                                    verifyDestinationIter   (void);
+       void                                    renderSourceIter                (void);
+       void                                    renderDestinationIter   (void);
        void                                    copyImageIter                   (void);
 
+       typedef void (CopyImageTest::*IterationFunc)(void);
+
+       struct Iteration
+       {
+               Iteration (int methodCount_, const IterationFunc* methods_)
+                       : methodCount   (methodCount_)
+                       , methods               (methods_)
+               {
+               }
+
+               int                                             methodCount;
+               const IterationFunc*    methods;
+       };
+
        struct State
        {
                State (int                                      seed,
@@ -1807,7 +2008,7 @@ void CopyImageTest::verifySourceIter (void)
 
        log << TestLog::Message << "Verifying source image." << TestLog::EndMessage;
 
-       verify(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo);
+       render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_COMPARE_REFERENCE);
 }
 
 void CopyImageTest::verifyDestinationIter (void)
@@ -1822,7 +2023,37 @@ void CopyImageTest::verifyDestinationIter (void)
 
        log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage;
 
-       verify(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo);
+       render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_COMPARE_REFERENCE);
+}
+
+void CopyImageTest::renderSourceIter (void)
+{
+       TestLog&                                                log                                     = m_testCtx.getLog();
+       const tcu::ScopedLogSection             sourceSection           (log, "Source image verify.", "Source image verify.");
+
+       de::Random&                                             rng                                     = m_state->rng;
+       tcu::ResultCollector&                   results                         = m_state->results;
+       glu::ObjectWrapper&                             srcImage                        = *m_state->srcImage;
+       vector<ArrayBuffer<deUint8> >&  srcImageLevels          = m_state->srcImageLevels;
+
+       log << TestLog::Message << "Verifying source image." << TestLog::EndMessage;
+
+       render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *srcImage, srcImageLevels, m_srcImageInfo, VERIFY_NONE);
+}
+
+void CopyImageTest::renderDestinationIter (void)
+{
+       TestLog&                                                log                                     = m_testCtx.getLog();
+       const tcu::ScopedLogSection             destinationSection      (log, "Destination image verify.", "Destination image verify.");
+
+       de::Random&                                             rng                                     = m_state->rng;
+       tcu::ResultCollector&                   results                         = m_state->results;
+       glu::ObjectWrapper&                             dstImage                        = *m_state->dstImage;
+       vector<ArrayBuffer<deUint8> >&  dstImageLevels          = m_state->dstImageLevels;
+
+       log << TestLog::Message << "Verifying destination image." << TestLog::EndMessage;
+
+       render(m_testCtx, m_context.getRenderContext(), m_state->textureRenderer, results, rng, *dstImage, dstImageLevels, m_dstImageInfo, VERIFY_NONE);
 }
 
 struct Copy
@@ -1983,31 +2214,65 @@ void CopyImageTest::copyImageIter (void)
 
 TestCase::IterateResult CopyImageTest::iterate (void)
 {
-       void(CopyImageTest::*methods[])(void) =
+       // Note: Returning from iterate() has two side-effects: it touches
+       // watchdog and calls eglSwapBuffers. For the first it's important
+       // to keep work per iteration reasonable to avoid
+       // timeouts. Because of the latter, it's prudent to do more than
+       // trivial amount of work. Otherwise we'll end up waiting for a
+       // new buffer in swap, it seems.
+
+       // The split below tries to combine trivial work with actually
+       // expensive rendering iterations without having too much
+       // rendering in one iteration to avoid timeouts.
+       const IterationFunc iteration1[] =
        {
                &CopyImageTest::logTestInfoIter,
-
-               // Render both images and then copy and verify again.
                &CopyImageTest::createImagesIter,
-               &CopyImageTest::verifySourceIter,
-               &CopyImageTest::verifyDestinationIter,
+               &CopyImageTest::renderSourceIter
+       };
+       const IterationFunc iteration2[] =
+       {
+               &CopyImageTest::renderDestinationIter
+       };
+       const IterationFunc iteration3[] =
+       {
                &CopyImageTest::copyImageIter,
-               &CopyImageTest::verifySourceIter,
+               &CopyImageTest::verifySourceIter
+       };
+       const IterationFunc iteration4[] =
+       {
                &CopyImageTest::verifyDestinationIter,
-               &CopyImageTest::destroyImagesIter,
-
-               // Create images and immediately copies between thew and verify.
+               &CopyImageTest::destroyImagesIter
+       };
+       const IterationFunc iteration5[] =
+       {
                &CopyImageTest::createImagesIter,
                &CopyImageTest::copyImageIter,
-               &CopyImageTest::verifySourceIter,
+               &CopyImageTest::verifySourceIter
+       };
+       const IterationFunc iteration6[] =
+       {
                &CopyImageTest::verifyDestinationIter,
                &CopyImageTest::destroyImagesIter
        };
+       const Iteration iterations[] =
+       {
+               Iteration(DE_LENGTH_OF_ARRAY(iteration1), iteration1),
+               Iteration(DE_LENGTH_OF_ARRAY(iteration2), iteration2),
+               Iteration(DE_LENGTH_OF_ARRAY(iteration3), iteration3),
+               Iteration(DE_LENGTH_OF_ARRAY(iteration4), iteration4),
+               Iteration(DE_LENGTH_OF_ARRAY(iteration5), iteration5),
+               Iteration(DE_LENGTH_OF_ARRAY(iteration6), iteration6)
+       };
+
+       DE_ASSERT(m_iteration < DE_LENGTH_OF_ARRAY(iterations));
+       for (int method = 0; method < iterations[m_iteration].methodCount; method++)
+               (this->*iterations[m_iteration].methods[method])();
 
-       if (m_iteration < DE_LENGTH_OF_ARRAY(methods))
+       m_iteration++;
+
+       if (m_iteration < DE_LENGTH_OF_ARRAY(iterations))
        {
-               (this->*methods[m_iteration])();
-               m_iteration++;
                return CONTINUE;
        }
        else
@@ -2130,11 +2395,11 @@ void addCopyTests (TestCaseGroup* root, deUint32 srcFormat, deUint32 dstFormat)
 
                        const string    targetTestName  = string(targetToName(srcTarget)) + "_to_" + targetToName(dstTarget);
 
-                       const IVec3             targetSize2D    (128, 128, 1);
-                       const IVec3             targetSize3D    (128, 128, 16);
-
-                       const IVec3             srcSize                 = getTestedSize(srcTarget, srcFormat, (srcIs3D ? targetSize3D : targetSize2D));
-                       const IVec3             dstSize                 = getTestedSize(dstTarget, dstFormat, (dstIs3D ? targetSize3D : targetSize2D));
+                       // Compressed formats require more space to fit all block size combinations.
+                       const bool              isCompressedCase        = glu::isCompressedFormat(srcFormat) || glu::isCompressedFormat(dstFormat);
+                       const IVec3             targetSize                      = isCompressedCase ? IVec3(128, 128, 16) : IVec3(64, 64, 8);
+                       const IVec3             srcSize                         = getTestedSize(srcTarget, srcFormat, targetSize);
+                       const IVec3             dstSize                         = getTestedSize(dstTarget, dstFormat, targetSize);
 
                        group->addChild(new CopyImageTest(root->getContext(),
                                                                                        ImageInfo(srcFormat, srcTarget, srcSize),
index d6dde30..d41addb 100644 (file)
 #include "es31fNegativeShaderImageLoadStoreTests.hpp"
 #include "es31fNegativeShaderFunctionTests.hpp"
 #include "es31fNegativeShaderDirectiveTests.hpp"
+#include "es31fNegativeSSBOBlockTests.hpp"
 #include "es31fNegativePreciseTests.hpp"
 #include "es31fNegativeAdvancedBlendEquationTests.hpp"
+#include "es31fNegativeShaderStorageTests.hpp"
+#include "es31fNegativeTessellationTests.hpp"
 
 #include "deUniquePtr.hpp"
 #include "deRandom.hpp"
@@ -2945,6 +2948,7 @@ void DebugTests::init (void)
        const vector<FunctionContainer> fragmentFuncs                    = wrapCoreFunctions(NegativeTestShared::getNegativeFragmentApiTestFunctions());
        const vector<FunctionContainer> vaFuncs                                  = wrapCoreFunctions(NegativeTestShared::getNegativeVertexArrayApiTestFunctions());
        const vector<FunctionContainer> stateFuncs                               = wrapCoreFunctions(NegativeTestShared::getNegativeStateApiTestFunctions());
+       const vector<FunctionContainer> tessellationFuncs                = wrapCoreFunctions(NegativeTestShared::getNegativeTessellationTestFunctions());
        const vector<FunctionContainer> atomicCounterFuncs               = wrapCoreFunctions(NegativeTestShared::getNegativeAtomicCounterTestFunctions());
        const vector<FunctionContainer> imageLoadFuncs                   = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageLoadTestFunctions());
        const vector<FunctionContainer> imageStoreFuncs                  = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageStoreTestFunctions());
@@ -2952,8 +2956,10 @@ void DebugTests::init (void)
        const vector<FunctionContainer> imageAtomicExchangeFuncs = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageAtomicExchangeTestFunctions());
        const vector<FunctionContainer> shaderFunctionFuncs              = wrapCoreFunctions(NegativeTestShared::getNegativeShaderFunctionTestFunctions());
        const vector<FunctionContainer> shaderDirectiveFuncs     = wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions());
+       const vector<FunctionContainer> ssboBlockFuncs                   = wrapCoreFunctions(NegativeTestShared::getNegativeSSBOBlockTestFunctions());
        const vector<FunctionContainer> preciseFuncs                     = wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions());
        const vector<FunctionContainer> advancedBlendFuncs               = wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions());
+       const vector<FunctionContainer> shaderStorageFuncs               = wrapCoreFunctions(NegativeTestShared::getNegativeShaderStorageTestFunctions());
        const vector<FunctionContainer> externalFuncs                    = getUserMessageFuncs();
 
        {
@@ -3057,8 +3063,11 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_image_exchange",          "Negative Shader Image Atomic Exchange API Cases",      imageAtomicExchangeFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_function",                        "Negative Shader Function Cases",                                       shaderFunctionFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_directive",                       "Negative Shader Directive Cases",                                      shaderDirectiveFuncs));
+                       host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "ssbo_block",                                     "Negative SSBO Block Cases",                                            ssboBlockFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
+                       host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_storage",                         "Negative Shader Storage Cases",                                        shaderStorageFuncs));
+                       host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "tessellation",                           "Negative Tessellation Cases",                                          tessellationFuncs));
                }
 
                {
@@ -3079,8 +3088,11 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_image_exchange",       "Negative Shader Image Atomic Exchange API Cases",      imageAtomicExchangeFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_function",                     "Negative Shader Function Cases",                                       shaderFunctionFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_directive",            "Negative Shader Directive Cases",                                      shaderDirectiveFuncs));
+                       host->addChild(createChildCases(CASETYPE_LOG, m_context, "ssbo_block",                          "Negative SSBO Block Cases",                                            ssboBlockFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "precise",                                     "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "advanced_blend",                      "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
+                       host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_storage",                      "Negative Shader Storage Cases",                                        shaderStorageFuncs));
+                       host->addChild(createChildCases(CASETYPE_LOG, m_context, "tessellation",                        "Negative Tessellation Cases",                                          tessellationFuncs));
                }
 
                {
@@ -3101,8 +3113,11 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_image_exchange",          "Negative Shader Image Atomic Exchange API Cases",      imageAtomicExchangeFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_function",                        "Negative Shader Function Cases",                                       shaderFunctionFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_directive",                       "Negative Shader Directive Cases",                                      shaderDirectiveFuncs));
+                       host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "ssbo_block",                                     "Negative SSBO Block Cases",                                            ssboBlockFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
+                       host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_storage",                         "Negative Shader Storage Cases",                                        shaderStorageFuncs));
+                       host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "tessellation",                           "Negative Tessellation Cases",                                          tessellationFuncs));
                }
        }
 
index 784e70c..b2bdac6 100644 (file)
@@ -88,6 +88,7 @@
 #include "es31fCopyImageTests.hpp"
 #include "es31fDrawBuffersIndexedTests.hpp"
 #include "es31fDefaultVertexArrayObjectTests.hpp"
+#include "es31fSRGBDecodeTests.hpp"
 
 namespace deqp
 {
@@ -296,6 +297,20 @@ public:
        }
 };
 
+class SRGBTextureDecodeTests : public TestCaseGroup
+{
+public:
+       SRGBTextureDecodeTests (Context& context)
+               : TestCaseGroup (context, "srgb_texture_decode", "GL_EXT_texture_sRGB_decode tests")
+       {
+       }
+
+       void init (void)
+       {
+               addChild(new SRGBDecodeTests    (m_context));
+       }
+};
+
 FunctionalTests::FunctionalTests (Context& context)
        : TestCaseGroup(context, "functional", "Functionality Tests")
 {
@@ -337,6 +352,7 @@ void FunctionalTests::init (void)
        addChild(createCopyImageTests                                           (m_context));
        addChild(createDrawBuffersIndexedTests                          (m_context));
        addChild(new DefaultVertexArrayObjectTests                      (m_context));
+       addChild(new SRGBTextureDecodeTests                                     (m_context));
 }
 
 } // Functional
index 104630b..461ef4d 100644 (file)
@@ -873,7 +873,7 @@ void IntegerStateQueryTests::init (void)
        FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_uniform_components_" + verifierSuffix).c_str(),                      "Test MAX_TESS_CONTROL_UNIFORM_COMPONENTS",                     GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS,                 1024,   verifier,       glu::ApiType::es(3, 2)))
        FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_texture_image_units_" + verifierSuffix).c_str(),                     "Test MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS",            GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,                16,             verifier,       glu::ApiType::es(3, 2)))
        FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_output_components_" + verifierSuffix).c_str(),                       "Test MAX_TESS_CONTROL_OUTPUT_COMPONENTS",                      GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS,                  64,             verifier,       glu::ApiType::es(3, 2)))
-       FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_total_output_components_" + verifierSuffix).c_str(),         "Test MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS",        GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS,    4096,   verifier,       glu::ApiType::es(3, 2)))
+       FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_total_output_components_" + verifierSuffix).c_str(),         "Test MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS",        GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS,    2048,   verifier,       glu::ApiType::es(3, 2)))
        FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_input_components_" + verifierSuffix).c_str(),                        "Test MAX_TESS_CONTROL_INPUT_COMPONENTS",                       GL_MAX_TESS_CONTROL_INPUT_COMPONENTS,                   64,             verifier,       glu::ApiType::es(3, 2)))
        FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_uniform_blocks_" + verifierSuffix).c_str(),                          "Test MAX_TESS_CONTROL_UNIFORM_BLOCKS",                         GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,                             12,             verifier,       glu::ApiType::es(3, 2)))
        FOR_EACH_VERIFIER(new MinimumValueCase(m_context,       (std::string() + "max_tess_control_atomic_counter_buffers_" + verifierSuffix).c_str(),          "Test MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS",         GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS,             0,              verifier,       glu::ApiType::es(3, 2)))
index b11bcf3..bcb8fd9 100644 (file)
@@ -26,6 +26,7 @@
 #include "gluShaderProgram.hpp"
 #include "gluPixelTransfer.hpp"
 #include "gluTextureUtil.hpp"
+#include "gluContextInfo.hpp"
 
 #include "glwFunctions.hpp"
 #include "glwEnums.hpp"
@@ -71,7 +72,9 @@ enum ShaderType
 {
        SHADERTYPE_VERTEX = 0,
        SHADERTYPE_FRAGMENT,
-       SHADERTYPE_BOTH,
+       SHADERTYPE_TESS_CONTROL,
+       SHADERTYPE_TESS_EVALUATION,
+       SHADERTYPE_ALL,
 
        SHADERTYPE_LAST,
 };
@@ -94,7 +97,7 @@ std::string generateVertexShader (ShaderType shaderType, const std::string& shad
        switch (shaderType)
        {
                case SHADERTYPE_VERTEX:
-               case SHADERTYPE_BOTH:
+               case SHADERTYPE_ALL:
                {
                        std::ostringstream vertexShaderSource;
                        vertexShaderSource      <<      "#version 310 es\n"
@@ -114,6 +117,8 @@ std::string generateVertexShader (ShaderType shaderType, const std::string& shad
                }
 
                case SHADERTYPE_FRAGMENT:
+               case SHADERTYPE_TESS_CONTROL:
+               case SHADERTYPE_TESS_EVALUATION:
                        return s_simpleVertexShaderSource;
 
                default:
@@ -135,6 +140,8 @@ std::string generateFragmentShader (ShaderType shaderType, const std::string& sh
        switch (shaderType)
        {
                case SHADERTYPE_VERTEX:
+               case SHADERTYPE_TESS_CONTROL:
+               case SHADERTYPE_TESS_EVALUATION:
                        return s_simpleFragmentShaderSource;
 
                case SHADERTYPE_FRAGMENT:
@@ -153,7 +160,7 @@ std::string generateFragmentShader (ShaderType shaderType, const std::string& sh
 
                        return fragmentShaderSource.str();
                }
-               case SHADERTYPE_BOTH:
+               case SHADERTYPE_ALL:
                {
                        std::ostringstream fragmentShaderSource;
                        fragmentShaderSource    <<      "#version 310 es\n"
@@ -178,6 +185,96 @@ std::string generateFragmentShader (ShaderType shaderType, const std::string& sh
        }
 }
 
+std::string generateTessControlShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
+{
+       static const char* const s_simpleTessContorlShaderSource =      "#version 310 es\n"
+                                                                                                                               "#extension GL_EXT_tessellation_shader : require\n"
+                                                                                                                               "layout (vertices=3) out;\n"
+                                                                                                                               "\n"
+                                                                                                                               "void main (void)\n"
+                                                                                                                               "{\n"
+                                                                                                                               "       gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                                                                                                               "}\n";
+
+       switch (shaderType)
+       {
+               case SHADERTYPE_VERTEX:
+               case SHADERTYPE_FRAGMENT:
+               case SHADERTYPE_TESS_EVALUATION:
+                       return s_simpleTessContorlShaderSource;
+
+               case SHADERTYPE_TESS_CONTROL:
+               case SHADERTYPE_ALL:
+               {
+                       std::ostringstream tessControlShaderSource;
+                       tessControlShaderSource <<      "#version 310 es\n"
+                                                                       <<      "#extension GL_EXT_tessellation_shader : require\n"
+                                                                       <<      "layout (vertices=3) out;\n"
+                                                                       <<      "\n"
+                                                                       <<      "uniform highp int u_arrayNdx;\n\n"
+                                                                       <<      shaderUniformDeclarations << "\n"
+                                                                       <<      "void main (void)\n"
+                                                                       <<      "{\n"
+                                                                       <<      "       highp vec4 color;\n\n"
+                                                                       <<      shaderBody << "\n"
+                                                                       <<      "       gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                                                       <<      "}\n";
+
+                       return tessControlShaderSource.str();
+               }
+
+               default:
+                       DE_ASSERT(false);
+                       return "";
+       }
+}
+
+std::string generateTessEvaluationShader (ShaderType shaderType, const std::string& shaderUniformDeclarations, const std::string& shaderBody)
+{
+       static const char* const s_simpleTessEvaluationShaderSource =   "#version 310 es\n"
+                                                                                                                                       "#extension GL_EXT_tessellation_shader : require\n"
+                                                                                                                                       "layout (triangles) in;\n"
+                                                                                                                                       "\n"
+                                                                                                                                       "void main (void)\n"
+                                                                                                                                       "{\n"
+                                                                                                                                       "       gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position + gl_TessCoord[1] * gl_in[1].gl_Position + gl_TessCoord[2] * gl_in[2].gl_Position;\n"
+                                                                                                                                       "}\n";
+
+       switch (shaderType)
+       {
+               case SHADERTYPE_VERTEX:
+               case SHADERTYPE_FRAGMENT:
+               case SHADERTYPE_TESS_CONTROL:
+                       return s_simpleTessEvaluationShaderSource;
+
+               case SHADERTYPE_TESS_EVALUATION:
+               case SHADERTYPE_ALL:
+               {
+                       std::ostringstream tessEvaluationShaderSource;
+                       tessEvaluationShaderSource      << "#version 310 es\n"
+                                                                               << "#extension GL_EXT_tessellation_shader : require\n"
+                                                                               << "layout (triangles) in;\n"
+                                                                               << "\n"
+                                                                               << "uniform highp int u_arrayNdx;\n\n"
+                                                                               << shaderUniformDeclarations << "\n"
+                                                                               << "out mediump vec4 v_color;\n"
+                                                                               << "void main (void)\n"
+                                                                               << "{\n"
+                                                                               << "    highp vec4 color;\n\n"
+                                                                               <<      shaderBody << "\n"
+                                                                               << "    v_color = color;\n"
+                                                                               << "    gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position + gl_TessCoord[1] * gl_in[1].gl_Position + gl_TessCoord[2] * gl_in[2].gl_Position;\n"
+                                                                               << "}\n";
+
+                       return tessEvaluationShaderSource.str();
+               }
+
+               default:
+                       DE_ASSERT(false);
+                       return "";
+       }
+}
+
 std::string getUniformName (const std::string& name, int declNdx)
 {
        return name + de::toString(declNdx);
@@ -320,7 +417,7 @@ void LayoutBindingRenderCase::init (void)
                                maxUnits = maxFragmentUnits;
                                break;
 
-                       case SHADERTYPE_BOTH:
+                       case SHADERTYPE_ALL:
                                maxUnits = maxCombinedUnits/2;
                                break;
 
@@ -354,11 +451,11 @@ void LayoutBindingRenderCase::init (void)
                }
 
                // Check that we have enough uniforms in different shaders to perform the tests
-               if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
+               if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_ALL)) && (maxVertexUnits < m_numBindings) )
                        throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
-               if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
+               if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_ALL)) && (maxFragmentUnits < m_numBindings) )
                        throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
-               if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
+               if ( (m_shaderType == SHADERTYPE_ALL) && (maxCombinedUnits < m_numBindings*2) )
                        throw tcu::NotSupportedError("Not enough uniforms available for test");
 
                // Check that we have enough binding points to perform the tests
@@ -590,6 +687,8 @@ public:
                                                                                                                                                 glw::GLenum            maxBindingPointEnum,
                                                                                                                                                 glw::GLenum            maxVertexUnitsEnum,
                                                                                                                                                 glw::GLenum            maxFragmentUnitsEnum,
+                                                                                                                                                glw::GLenum            maxTessCtrlUnitsEnum,
+                                                                                                                                                glw::GLenum            maxTessEvalUnitsEnum,
                                                                                                                                                 glw::GLenum            maxCombinedUnitsEnum,
                                                                                                                                                 const std::string& uniformName);
        virtual                                                         ~LayoutBindingNegativeCase              (void);
@@ -608,11 +707,16 @@ protected:
        const glw::GLenum                                       m_maxBindingPointEnum;
        const glw::GLenum                                       m_maxVertexUnitsEnum;
        const glw::GLenum                                       m_maxFragmentUnitsEnum;
+       const glw::GLenum                                       m_maxTessCtrlUnitsEnum;
+       const glw::GLenum                                       m_maxTessEvalUnitsEnum;
        const glw::GLenum                                       m_maxCombinedUnitsEnum;
        const std::string                                       m_uniformName;
        glw::GLint                                                      m_numBindings;
        std::vector<glw::GLint>                         m_vertexShaderBinding;
        std::vector<glw::GLint>                         m_fragmentShaderBinding;
+       std::vector<glw::GLint>                         m_tessCtrlShaderBinding;
+       std::vector<glw::GLint>                         m_tessEvalShaderBinding;
+       bool                                                            m_tessSupport;
 
 private:
        void                                                            initBindingPoints                               (int minBindingPoint, int numBindingPoints);
@@ -626,6 +730,8 @@ LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context&                              context,
                                                                                                          ErrorType                             errorType,
                                                                                                          glw::GLenum                   maxBindingPointEnum,
                                                                                                          glw::GLenum                   maxVertexUnitsEnum,
+                                                                                                         glw::GLenum                   maxTessCtrlUnitsEnum,
+                                                                                                         glw::GLenum                   maxTessEvalUnitsEnum,
                                                                                                          glw::GLenum                   maxFragmentUnitsEnum,
                                                                                                          glw::GLenum                   maxCombinedUnitsEnum,
                                                                                                          const std::string&    uniformName)
@@ -637,9 +743,12 @@ LayoutBindingNegativeCase::LayoutBindingNegativeCase (Context&                             context,
        , m_maxBindingPointEnum         (maxBindingPointEnum)
        , m_maxVertexUnitsEnum          (maxVertexUnitsEnum)
        , m_maxFragmentUnitsEnum        (maxFragmentUnitsEnum)
+       , m_maxTessCtrlUnitsEnum        (maxTessCtrlUnitsEnum)
+       , m_maxTessEvalUnitsEnum        (maxTessEvalUnitsEnum)
        , m_maxCombinedUnitsEnum        (maxCombinedUnitsEnum)
        , m_uniformName                         (uniformName)
        , m_numBindings                         (0)
+       , m_tessSupport                         (false)
 {
 }
 
@@ -657,16 +766,40 @@ void LayoutBindingNegativeCase::init (void)
        glw::GLint                              maxVertexUnits          = 0;    // Available uniforms in the vertex shader
        glw::GLint                              maxFragmentUnits        = 0;    // Available uniforms in the fragment shader
        glw::GLint                              maxCombinedUnits        = 0;    // Available uniforms in all the shader stages combined
+       glw::GLint                              maxTessCtrlUnits        = 0;    // Available uniforms in tessellation control shader
+       glw::GLint                              maxTessEvalUnits        = 0;    // Available uniforms in tessellation evaluation shader
        glw::GLint                              maxUnits                        = 0;    // Maximum available uniforms for this test
 
+       m_tessSupport = m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader")
+                                       || contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+
+       if (!m_tessSupport && (m_shaderType == SHADERTYPE_TESS_EVALUATION || m_shaderType == SHADERTYPE_TESS_CONTROL))
+               TCU_THROW(NotSupportedError, "Tesselation shaders not supported");
+
+       int numShaderStages = m_tessSupport ? 4 : 2;
+
        gl.getIntegerv(m_maxVertexUnitsEnum, &maxVertexUnits);
        gl.getIntegerv(m_maxFragmentUnitsEnum, &maxFragmentUnits);
+
+       if (m_tessSupport)
+       {
+               gl.getIntegerv(m_maxTessCtrlUnitsEnum, &maxTessCtrlUnits);
+               gl.getIntegerv(m_maxTessEvalUnitsEnum, &maxTessEvalUnits);
+       }
+
        gl.getIntegerv(m_maxCombinedUnitsEnum, &maxCombinedUnits);
        gl.getIntegerv(m_maxBindingPointEnum, &numBindingPoints);
        GLU_EXPECT_NO_ERROR(gl.getError(), "Querying available uniform numbers failed");
 
        m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the vertex shader: " << maxVertexUnits << tcu::TestLog::EndMessage;
        m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the fragment shader: " << maxFragmentUnits << tcu::TestLog::EndMessage;
+
+       if (m_tessSupport)
+       {
+               m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the tessellation control shader: " << maxTessCtrlUnits << tcu::TestLog::EndMessage;
+               m_testCtx.getLog() << tcu::TestLog::Message << "Maximum units for uniform type in the tessellation evaluation shader: " << maxTessCtrlUnits << tcu::TestLog::EndMessage;
+       }
+
        m_testCtx.getLog() << tcu::TestLog::Message << "Maximum combined units for uniform type: " << maxCombinedUnits << tcu::TestLog::EndMessage;
        m_testCtx.getLog() << tcu::TestLog::Message << "Maximum binding point for uniform type: " << numBindingPoints-1 << tcu::TestLog::EndMessage;
 
@@ -681,8 +814,16 @@ void LayoutBindingNegativeCase::init (void)
                        maxUnits = maxFragmentUnits;
                        break;
 
-               case SHADERTYPE_BOTH:
-                       maxUnits = de::min(de::min(maxVertexUnits, maxFragmentUnits), maxCombinedUnits/2);
+               case SHADERTYPE_ALL:
+                       maxUnits = de::min(de::min(de::min(maxVertexUnits, maxFragmentUnits), de::min(maxTessCtrlUnits, maxTessEvalUnits)), maxCombinedUnits/numShaderStages);
+                       break;
+
+               case SHADERTYPE_TESS_CONTROL:
+                       maxUnits = maxTessCtrlUnits;
+                       break;
+
+               case SHADERTYPE_TESS_EVALUATION:
+                       maxUnits = maxTessEvalUnits;
                        break;
 
                default:
@@ -704,13 +845,13 @@ void LayoutBindingNegativeCase::init (void)
                        {
                                // leave room for contradictory case
                                if (maxUnits < 3)
-                                       throw tcu::NotSupportedError("Not enough uniforms available for test");
+                                       TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
                                m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits-1));
                        }
                        else
                        {
                                if (maxUnits < 2)
-                                       throw tcu::NotSupportedError("Not enough uniforms available for test");
+                                       TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
                                m_numBindings = rnd.getInt(2, deMin32(MAX_UNIFORM_ARRAY_SIZE, maxUnits));
                        }
                        break;
@@ -720,18 +861,27 @@ void LayoutBindingNegativeCase::init (void)
        }
 
        // Check that we have enough uniforms in different shaders to perform the tests
-       if ( ((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_BOTH)) && (maxVertexUnits < m_numBindings) )
-               throw tcu::NotSupportedError("Vertex shader: not enough uniforms available for test");
-       if ( ((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_BOTH)) && (maxFragmentUnits < m_numBindings) )
-               throw tcu::NotSupportedError("Fragment shader: not enough uniforms available for test");
-       if ( (m_shaderType == SHADERTYPE_BOTH) && (maxCombinedUnits < m_numBindings*2) )
-               throw tcu::NotSupportedError("Not enough uniforms available for test");
+       if (((m_shaderType == SHADERTYPE_VERTEX) || (m_shaderType == SHADERTYPE_ALL)) && (maxVertexUnits < m_numBindings) )
+               TCU_THROW(NotSupportedError, "Vertex shader: not enough uniforms available for test");
+
+       if (((m_shaderType == SHADERTYPE_FRAGMENT) || (m_shaderType == SHADERTYPE_ALL)) && (maxFragmentUnits < m_numBindings) )
+               TCU_THROW(NotSupportedError, "Fragment shader: not enough uniforms available for test");
+
+       if (m_tessSupport && ((m_shaderType == SHADERTYPE_TESS_CONTROL) || (m_shaderType == SHADERTYPE_ALL)) && (maxTessCtrlUnits < m_numBindings) )
+               TCU_THROW(NotSupportedError, "Tessellation control shader: not enough uniforms available for test");
+
+       if (m_tessSupport && ((m_shaderType == SHADERTYPE_TESS_EVALUATION) || (m_shaderType == SHADERTYPE_ALL)) && (maxTessEvalUnits < m_numBindings) )
+               TCU_THROW(NotSupportedError, "Tessellation evaluation shader: not enough uniforms available for test");
+
+       if ((m_shaderType == SHADERTYPE_ALL) && (maxCombinedUnits < m_numBindings*numShaderStages) )
+               TCU_THROW(NotSupportedError, "Not enough uniforms available for test");
 
        // Check that we have enough binding points to perform the tests
        if (numBindingPoints < m_numBindings)
-               throw tcu::NotSupportedError("Not enough binding points available for test");
+               TCU_THROW(NotSupportedError, "Not enough binding points available for test");
+
        if (m_errorType == ERRORTYPE_CONTRADICTORY && numBindingPoints == m_numBindings)
-               throw tcu::NotSupportedError("Not enough binding points available for test");
+               TCU_THROW(NotSupportedError, "Not enough binding points available for test");
 
        // Initialize the binding points i.e. populate the two binding point vectors
        initBindingPoints(0, numBindingPoints);
@@ -767,8 +917,21 @@ TestCase::IterateResult LayoutBindingNegativeCase::iterate (void)
 
                case ERRORTYPE_LESS_THAN_ZERO:          // Out of bounds binding points should cause a compile-time error
                case ERRORTYPE_OVER_MAX_UNITS:
-                       if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT)).compileOk)
-                               pass = true;
+                       if (m_tessSupport)
+                       {
+                               if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk
+                                       || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk)
+                                       || !(m_program->getShaderInfo(glu::SHADERTYPE_TESSELLATION_CONTROL).compileOk)
+                                       || !(m_program->getShaderInfo(glu::SHADERTYPE_TESSELLATION_EVALUATION)).compileOk)
+                                       pass = true;
+                       }
+                       else
+                       {
+                               if (!(m_program->getShaderInfo(glu::SHADERTYPE_VERTEX)).compileOk
+                                       || !(m_program->getShaderInfo(glu::SHADERTYPE_FRAGMENT).compileOk))
+                                       pass = true;
+                       }
+
                        failMessage = "Test failed - expected a compile-time error";
                        break;
 
@@ -794,6 +957,8 @@ void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numB
                {
                        m_vertexShaderBinding.push_back(numBindingPoints+1-m_numBindings);
                        m_fragmentShaderBinding.push_back(numBindingPoints+1-m_numBindings);
+                       m_tessCtrlShaderBinding.push_back(numBindingPoints+1-m_numBindings);
+                       m_tessEvalShaderBinding.push_back(numBindingPoints+1-m_numBindings);
                        break;
                }
 
@@ -802,6 +967,8 @@ void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numB
                        const glw::GLint binding = -rnd.getInt(1, m_numBindings);
                        m_vertexShaderBinding.push_back(binding);
                        m_fragmentShaderBinding.push_back(binding);
+                       m_tessCtrlShaderBinding.push_back(binding);
+                       m_tessEvalShaderBinding.push_back(binding);
                        break;
                }
 
@@ -809,7 +976,15 @@ void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numB
                {
                        m_vertexShaderBinding.push_back(minBindingPoint);
                        m_fragmentShaderBinding.push_back((minBindingPoint+1)%numBindingPoints);
-                       DE_ASSERT(m_vertexShaderBinding.back() != m_fragmentShaderBinding.back());
+                       m_tessCtrlShaderBinding.push_back((minBindingPoint+2)%numBindingPoints);
+                       m_tessEvalShaderBinding.push_back((minBindingPoint+3)%numBindingPoints);
+
+                       DE_ASSERT(m_vertexShaderBinding.back()          != m_fragmentShaderBinding.back());
+                       DE_ASSERT(m_fragmentShaderBinding.back()        != m_tessEvalShaderBinding.back());
+                       DE_ASSERT(m_tessEvalShaderBinding.back()        != m_tessCtrlShaderBinding.back());
+                       DE_ASSERT(m_tessCtrlShaderBinding.back()        != m_vertexShaderBinding.back());
+                       DE_ASSERT(m_vertexShaderBinding.back()          != m_tessEvalShaderBinding.back());
+                       DE_ASSERT(m_tessCtrlShaderBinding.back()        != m_fragmentShaderBinding.back());
                        break;
                }
 
@@ -822,6 +997,8 @@ void LayoutBindingNegativeCase::initBindingPoints (int minBindingPoint, int numB
        {
                m_vertexShaderBinding.push_back(m_vertexShaderBinding.front()+ndx);
                m_fragmentShaderBinding.push_back(m_fragmentShaderBinding.front()+ndx);
+               m_tessCtrlShaderBinding.push_back(m_tessCtrlShaderBinding.front()+ndx);
+               m_tessEvalShaderBinding.push_back(m_tessCtrlShaderBinding.front()+ndx);
        }
 }
 
@@ -1052,7 +1229,19 @@ SamplerBindingNegativeCase::SamplerBindingNegativeCase (Context&         context,
                                                                                                                TestType                testType,
                                                                                                                ErrorType               errorType,
                                                                                                                glw::GLenum             samplerType)
-       : LayoutBindingNegativeCase             (context, name, desc, shaderType, testType, errorType, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, GL_MAX_TEXTURE_IMAGE_UNITS, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, "u_sampler")
+       : LayoutBindingNegativeCase             (context,
+                                                                        name,
+                                                                        desc,
+                                                                        shaderType,
+                                                                        testType,
+                                                                        errorType,
+                                                                        GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
+                                                                        GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS,
+                                                                        GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS,
+                                                                        GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,
+                                                                        GL_MAX_TEXTURE_IMAGE_UNITS,
+                                                                        GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS,
+                                                                        "u_sampler")
        , m_samplerType                                 (samplerType)
 {
 }
@@ -1066,6 +1255,8 @@ glu::ShaderProgram*       SamplerBindingNegativeCase::generateShaders     (void) const
 {
        std::ostringstream              vertexUniformDecl;
        std::ostringstream              fragmentUniformDecl;
+       std::ostringstream              tessCtrlUniformDecl;
+       std::ostringstream              tessEvalUniformDecl;
        std::ostringstream              shaderBody;
 
        const std::string               texCoordType    = glu::getDataTypeName(getSamplerTexCoordType());
@@ -1080,6 +1271,10 @@ glu::ShaderProgram*      SamplerBindingNegativeCase::generateShaders     (void) const
                        << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
                fragmentUniformDecl << "layout(binding = " << m_fragmentShaderBinding[declNdx] << ") uniform highp " << samplerType
                        << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
+               tessCtrlUniformDecl << "layout(binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform highp " << samplerType
+                       << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
+               tessEvalUniformDecl << "layout(binding = " << m_tessEvalShaderBinding[declNdx] << ") uniform highp " << samplerType
+                       << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
        }
 
        // Generate the shader body for the vertex and fragment shaders
@@ -1096,9 +1291,16 @@ glu::ShaderProgram*      SamplerBindingNegativeCase::generateShaders     (void) const
                                << "            color = vec4(0.0, 0.0, 0.0, 1.0);\n"
                                << "    }\n";
 
-       return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
+       glu::ProgramSources sources = glu::ProgramSources()
                                << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
-                               << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
+                               << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
+
+       if (m_tessSupport)
+               sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
+                               << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
+
+       return new glu::ShaderProgram(m_context.getRenderContext(), sources);
+
 }
 
 glu::DataType SamplerBindingNegativeCase::getSamplerTexCoordType(void) const
@@ -1351,7 +1553,19 @@ ImageBindingNegativeCase::ImageBindingNegativeCase (Context&             context,
                                                                                                        TestType                testType,
                                                                                                        ErrorType               errorType,
                                                                                                        glw::GLenum             imageType)
-       : LayoutBindingNegativeCase             (context, name, desc, shaderType, testType, errorType, GL_MAX_IMAGE_UNITS, GL_MAX_VERTEX_IMAGE_UNIFORMS, GL_MAX_FRAGMENT_IMAGE_UNIFORMS, GL_MAX_COMBINED_IMAGE_UNIFORMS, "u_image")
+       : LayoutBindingNegativeCase             (context,
+                                                                        name,
+                                                                        desc,
+                                                                        shaderType,
+                                                                        testType,
+                                                                        errorType,
+                                                                        GL_MAX_IMAGE_UNITS,
+                                                                        GL_MAX_VERTEX_IMAGE_UNIFORMS,
+                                                                        GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS,
+                                                                        GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS,
+                                                                        GL_MAX_FRAGMENT_IMAGE_UNIFORMS,
+                                                                        GL_MAX_COMBINED_IMAGE_UNIFORMS,
+                                                                        "u_image")
        , m_imageType                                   (imageType)
 {
 }
@@ -1365,6 +1579,8 @@ glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
 {
        std::ostringstream              vertexUniformDecl;
        std::ostringstream              fragmentUniformDecl;
+       std::ostringstream              tessCtrlUniformDecl;
+       std::ostringstream              tessEvalUniformDecl;
        std::ostringstream              shaderBody;
 
        const std::string               texCoordType    = glu::getDataTypeName(getImageTexCoordType());
@@ -1379,6 +1595,10 @@ glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
                        << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
                fragmentUniformDecl << "layout(rgba8, binding = " << m_fragmentShaderBinding[declNdx] << ") uniform readonly highp " << imageType
                        << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
+               tessCtrlUniformDecl << "layout(rgba8, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform readonly highp " << imageType
+                       << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
+               tessEvalUniformDecl << "layout(rgba8, binding = " << m_tessEvalShaderBinding[declNdx] << ") uniform readonly highp " << imageType
+                       << " " << (arrayInstance ? getUniformName(m_uniformName, declNdx, m_numBindings) : getUniformName(m_uniformName, declNdx)) << ";\n";
        }
 
        // Generate the shader body for the vertex and fragment shaders
@@ -1395,9 +1615,15 @@ glu::ShaderProgram* ImageBindingNegativeCase::generateShaders (void) const
                                << "            color = vec4(0.0, 0.0, 0.0, 1.0);\n"
                                << "    }\n";
 
-       return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
-                                       << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
-                                       << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
+       glu::ProgramSources sources = glu::ProgramSources()
+                               << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
+                               << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
+
+       if (m_tessSupport)
+               sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
+                               << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
+
+       return new glu::ShaderProgram(m_context.getRenderContext(), sources);
 }
 
 glu::DataType ImageBindingNegativeCase::getImageTexCoordType(void) const
@@ -1596,7 +1822,19 @@ UBOBindingNegativeCase::UBOBindingNegativeCase (Context&         context,
                                                                                                ShaderType              shaderType,
                                                                                                TestType                testType,
                                                                                                ErrorType               errorType)
-       : LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_UNIFORM_BUFFER_BINDINGS, GL_MAX_VERTEX_UNIFORM_BLOCKS, GL_MAX_FRAGMENT_UNIFORM_BLOCKS, GL_MAX_COMBINED_UNIFORM_BLOCKS, "ColorBlock")
+       : LayoutBindingNegativeCase(context,
+                                                               name,
+                                                               desc,
+                                                               shaderType,
+                                                               testType,
+                                                               errorType,
+                                                               GL_MAX_UNIFORM_BUFFER_BINDINGS,
+                                                               GL_MAX_VERTEX_UNIFORM_BLOCKS,
+                                                               GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,
+                                                               GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,
+                                                               GL_MAX_FRAGMENT_UNIFORM_BLOCKS,
+                                                               GL_MAX_COMBINED_UNIFORM_BLOCKS,
+                                                               "ColorBlock")
 {
 }
 
@@ -1609,6 +1847,8 @@ glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
 {
        std::ostringstream              vertexUniformDecl;
        std::ostringstream              fragmentUniformDecl;
+       std::ostringstream              tessCtrlUniformDecl;
+       std::ostringstream              tessEvalUniformDecl;
        std::ostringstream              shaderBody;
        const bool                              arrayInstance   = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
        const int                               numDeclarations = (arrayInstance ? 1 : m_numBindings);
@@ -1629,6 +1869,20 @@ glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
                        << "    highp vec4 color1;\n"
                        << "    highp vec4 color2;\n"
                        << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
+
+               tessCtrlUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform "
+                       << getUniformName(m_uniformName, declNdx) << "\n"
+                       << "{\n"
+                       << "    highp vec4 color1;\n"
+                       << "    highp vec4 color2;\n"
+                       << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
+
+               tessEvalUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") uniform "
+                       << getUniformName(m_uniformName, declNdx) << "\n"
+                       << "{\n"
+                       << "    highp vec4 color1;\n"
+                       << "    highp vec4 color2;\n"
+                       << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
        }
 
        // Generate the shader body for the vertex and fragment shaders
@@ -1646,9 +1900,15 @@ glu::ShaderProgram* UBOBindingNegativeCase::generateShaders (void) const
                                << "            color = vec4(0.0, 0.0, 0.0, 1.0);\n"
                                << "    }\n";
 
-       return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
-                                       << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
-                                       << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
+       glu::ProgramSources sources = glu::ProgramSources()
+                               << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
+                               << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
+
+       if (m_tessSupport)
+               sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
+                               << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
+
+       return new glu::ShaderProgram(m_context.getRenderContext(), sources);
 }
 
 
@@ -1831,7 +2091,19 @@ SSBOBindingNegativeCase::SSBOBindingNegativeCase (Context& context,
                                                                                                  ShaderType shaderType,
                                                                                                  TestType testType,
                                                                                                  ErrorType errorType)
-       : LayoutBindingNegativeCase(context, name, desc, shaderType, testType, errorType, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, "ColorBuffer")
+       : LayoutBindingNegativeCase(context,
+                                                               name,
+                                                               desc,
+                                                               shaderType,
+                                                               testType,
+                                                               errorType,
+                                                               GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS,
+                                                               GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS,
+                                                               GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS,
+                                                               GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS,
+                                                               GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS,
+                                                               GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS,
+                                                               "ColorBuffer")
 {
 }
 
@@ -1844,6 +2116,8 @@ glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
 {
        std::ostringstream              vertexUniformDecl;
        std::ostringstream              fragmentUniformDecl;
+       std::ostringstream              tessCtrlUniformDecl;
+       std::ostringstream              tessEvalUniformDecl;
        std::ostringstream              shaderBody;
        const bool                              arrayInstance   = (m_testType == TESTTYPE_BINDING_ARRAY || m_testType == TESTTYPE_BINDING_MAX_ARRAY);
        const int                               numDeclarations = (arrayInstance ? 1 : m_numBindings);
@@ -1864,6 +2138,20 @@ glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
                        << "    highp vec4 color1;\n"
                        << "    highp vec4 color2;\n"
                        << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
+
+               tessCtrlUniformDecl << "layout(std140, binding = " << m_tessCtrlShaderBinding[declNdx] << ") buffer "
+                       << getUniformName(m_uniformName, declNdx) << "\n"
+                       << "{\n"
+                       << "    highp vec4 color1;\n"
+                       << "    highp vec4 color2;\n"
+                       << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
+
+               tessEvalUniformDecl << "layout(std140, binding = " << m_tessEvalShaderBinding[declNdx] << ") buffer "
+                       << getUniformName(m_uniformName, declNdx) << "\n"
+                       << "{\n"
+                       << "    highp vec4 color1;\n"
+                       << "    highp vec4 color2;\n"
+                       << "} " << (arrayInstance ? getUniformName("colors", declNdx, m_numBindings) : getUniformName("colors", declNdx)) << ";\n";
        }
 
        // Generate the shader body for the vertex and fragment shaders
@@ -1881,9 +2169,15 @@ glu::ShaderProgram* SSBOBindingNegativeCase::generateShaders (void) const
                                << "            color = vec4(0.0, 0.0, 0.0, 1.0);\n"
                                << "    }\n";
 
-       return new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
-                                       << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
-                                       << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str())));
+       glu::ProgramSources sources = glu::ProgramSources()
+                               << glu::VertexSource(generateVertexShader(m_shaderType, vertexUniformDecl.str(), shaderBody.str()))
+                               << glu::FragmentSource(generateFragmentShader(m_shaderType, fragmentUniformDecl.str(), shaderBody.str()));
+
+       if (m_tessSupport)
+               sources << glu::TessellationControlSource(generateTessControlShader(m_shaderType, tessCtrlUniformDecl.str(), shaderBody.str()))
+                               << glu::TessellationEvaluationSource(generateTessEvaluationShader(m_shaderType, tessEvalUniformDecl.str(), shaderBody.str()));
+
+       return new glu::ShaderProgram(m_context.getRenderContext(), sources);
 }
 
 
@@ -1956,18 +2250,26 @@ void LayoutBindingTests::init (void)
                std::string                                                             descPostfix;
        } s_negativeTestTypes[] =
        {
-               { SHADERTYPE_VERTEX,    TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "vertex_binding_over_max",                      "over maximum binding point"},
-               { SHADERTYPE_FRAGMENT,  TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "fragment_binding_over_max",            "over maximum binding point"},
-               { SHADERTYPE_VERTEX,    TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "vertex_binding_neg",                           "negative binding point"},
-               { SHADERTYPE_FRAGMENT,  TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "fragment_binding_neg",                         "negative binding point"},
-
-               { SHADERTYPE_VERTEX,    TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "vertex_binding_over_max_array",        "over maximum binding point"},
-               { SHADERTYPE_FRAGMENT,  TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "fragment_binding_over_max_array",      "over maximum binding point"},
-               { SHADERTYPE_VERTEX,    TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "vertex_binding_neg_array",                     "negative binding point"},
-               { SHADERTYPE_FRAGMENT,  TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "fragment_binding_neg_array",           "negative binding point"},
-
-               { SHADERTYPE_BOTH,              TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,             "binding_contradictory",                        "contradictory binding points"},
-               { SHADERTYPE_BOTH,              TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,             "binding_contradictory_array",          "contradictory binding points"},
+               { SHADERTYPE_VERTEX,                    TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "vertex_binding_over_max",                                      "over maximum binding point"   },
+               { SHADERTYPE_FRAGMENT,                  TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "fragment_binding_over_max",                            "over maximum binding point"   },
+               { SHADERTYPE_TESS_CONTROL,              TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "tess_control_binding_over_max",                        "over maximum binding point"   },
+               { SHADERTYPE_TESS_EVALUATION,   TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "tess_evaluation_binding_over_max",                     "over maximum binding point"   },
+               { SHADERTYPE_VERTEX,                    TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "vertex_binding_neg",                                           "negative binding point"           },
+               { SHADERTYPE_FRAGMENT,                  TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "fragment_binding_neg",                                         "negative binding point"           },
+               { SHADERTYPE_TESS_CONTROL,              TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "tess_control_binding_neg",                                     "negative binding point"           },
+               { SHADERTYPE_TESS_EVALUATION,   TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "tess_evaluation_binding_neg",                          "negative binding point"           },
+
+               { SHADERTYPE_VERTEX,                    TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "vertex_binding_over_max_array",                        "over maximum binding point"   },
+               { SHADERTYPE_FRAGMENT,                  TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "fragment_binding_over_max_array",                      "over maximum binding point"   },
+               { SHADERTYPE_TESS_CONTROL,              TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "tess_control_binding_over_max_array",          "over maximum binding point"   },
+               { SHADERTYPE_TESS_EVALUATION,   TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_OVER_MAX_UNITS,    "tess_evaluation_binding_over_max_array",       "over maximum binding point"   },
+               { SHADERTYPE_VERTEX,                    TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "vertex_binding_neg_array",                                     "negative binding point"           },
+               { SHADERTYPE_FRAGMENT,                  TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "fragment_binding_neg_array",                           "negative binding point"           },
+               { SHADERTYPE_TESS_CONTROL,              TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "tess_control_binding_neg_array",                       "negative binding point"           },
+               { SHADERTYPE_TESS_EVALUATION,   TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_LESS_THAN_ZERO,    "tess_evaluation_binding_neg_array",            "negative binding point"           },
+
+               { SHADERTYPE_ALL,                               TESTTYPE_BINDING_SINGLE,                LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,             "binding_contradictory",                                        "contradictory binding points" },
+               { SHADERTYPE_ALL,                               TESTTYPE_BINDING_ARRAY,                 LayoutBindingNegativeCase::ERRORTYPE_CONTRADICTORY,             "binding_contradictory_array",                          "contradictory binding points" },
        };
 
        // Render tests
index e4b67cd..39474ee 100644 (file)
@@ -196,6 +196,7 @@ void read_pixels (NegativeTestContext& ctx)
 
 void readn_pixels (NegativeTestContext& ctx)
 {
+       std::vector<GLfloat>    floatData       (4);
        std::vector<GLubyte>    ubyteData       (4);
        GLuint                                  fbo                     = 0x1234;
 
@@ -223,6 +224,8 @@ void readn_pixels (NegativeTestContext& ctx)
        ctx.beginSection("GL_INVALID_OPERATION is generated by ReadnPixels if the buffer size required to store the requested data is larger than bufSize.");
        ctx.glReadnPixels(0, 0, 0x1234, 0x1234, GL_RGBA, GL_UNSIGNED_BYTE, (int) ubyteData.size(), &ubyteData[0]);
        ctx.expectError(GL_INVALID_OPERATION);
+       ctx.glReadnPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, (int) floatData.size(), &floatData[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
@@ -240,7 +243,6 @@ void read_pixels_format_mismatch (NegativeTestContext& ctx)
 {
        std::vector<GLubyte>    ubyteData       (4);
        std::vector<GLushort>   ushortData      (4);
-       std::vector<GLfloat>    floatData       (4);
        GLint                                   readFormat      = 0x1234;
        GLint                                   readType        = 0x1234;
 
@@ -257,8 +259,6 @@ void read_pixels_format_mismatch (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_OPERATION);
        ctx.glReadPixels(0, 0, 1, 1, GL_ALPHA, GL_UNSIGNED_SHORT_5_5_5_1, &ushortData[0]);
        ctx.expectError(GL_INVALID_OPERATION);
-       ctx.glReadnPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, (int) floatData.size(), &floatData[0]);
-       ctx.expectError(GL_INVALID_OPERATION);
        ctx.endSection();
 
        ctx.beginSection("GL_RGBA/GL_UNSIGNED_BYTE is always accepted and the other acceptable pair can be discovered by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.");
@@ -446,15 +446,19 @@ void bind_buffer_range (NegativeTestContext& ctx)
                ctx.endSection();
 
                ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_ATOMIC_COUNTER_BUFFER and offset is not multiples of 4.");
-               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufTF, 5, 0);
+               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufTF, 5, 4);
                ctx.expectError(GL_INVALID_VALUE);
                ctx.endSection();
 
-               ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_SHADER_STORAGE_BUFFER and offset is not a multiple of the value of GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT.");
                ctx.glGetIntegerv(GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT, &ssAlignment);
-               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, 0, bufTF, ssAlignment+1, 0);
-               ctx.expectError(GL_INVALID_VALUE);
-               ctx.endSection();
+
+               if (ssAlignment != 1)
+               {
+                       ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_SHADER_STORAGE_BUFFER and offset is not a multiple of the value of GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT.");
+                       ctx.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 0, bufTF, ssAlignment+1, 4);
+                       ctx.expectError(GL_INVALID_VALUE);
+                       ctx.endSection();
+               }
        }
 
        ctx.glDeleteBuffers(1, &bufU);
@@ -497,24 +501,6 @@ void bind_buffer_base (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
-       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
-       {
-               int maxACize = 0x1234;
-               int maxSSize = 0x1234;
-
-               ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_ATOMIC_COUNTER_BUFFER and index is greater than or equal to GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS.");
-               ctx.glGetIntegerv(GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &maxACize);
-               ctx.glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, maxACize, bufU, 0, 4);
-               ctx.expectError(GL_INVALID_VALUE);
-               ctx.endSection();
-
-               ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_SHADER_STORAGE_BUFFER and index is greater than or equal to GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS.");
-               ctx.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxSSize);
-               ctx.glBindBufferRange(GL_SHADER_STORAGE_BUFFER, maxSSize, bufU, 0, 4);
-               ctx.expectError(GL_INVALID_VALUE);
-               ctx.endSection();
-       }
-
        ctx.glDeleteBuffers(1, &bufU);
        ctx.glDeleteBuffers(1, &bufTF);
 }
diff --git a/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp b/modules/gles31/functional/es31fNegativeSSBOBlockTests.cpp
new file mode 100644 (file)
index 0000000..bddd035
--- /dev/null
@@ -0,0 +1,617 @@
+/*-------------------------------------------------------------------------
+* drawElements Quality Program OpenGL ES 3.1 Module
+* -------------------------------------------------
+*
+* Copyright 2016 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 Negative Shader Storage Buffer Object (SSBO) tests.
+*//*--------------------------------------------------------------------*/
+#include "es31fNegativeSSBOBlockTests.hpp"
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+#include "tcuStringTemplate.hpp"
+#include "gluShaderProgram.hpp"
+#include <map>
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+using tcu::TestLog;
+using glu::CallLogWrapper;
+using namespace glw;
+namespace args
+{
+enum ArgMember
+{
+       ARGMEMBER_FORMAT                        =       0,
+       ARGMEMBER_BINDING_POINT,
+       ARGMEMBER_MATRIX_ORDER,
+       ARGMEMBER_MEMBER_TYPE,
+       ARGMEMBER_NAME,
+       ARGMEMBER_FIXED_ARRAY,
+       ARGMEMBER_VARIABLE_ARRAY,
+       ARGMEMBER_REORDER
+};
+
+// key pair ssbo arg data
+struct SsboArgData
+{
+       ArgMember       member;
+       std::string     data;
+
+       SsboArgData(const ArgMember& member_, const std::string& data_)
+       {
+               member  =       member_;
+               data    =       data_;
+       }
+};
+
+// class which manages string based argument used to build varying ssbo interface blocks and members
+class SsboArgs
+{
+public:
+                                       SsboArgs(const std::string version, tcu::TestLog& log);
+
+       void                    setSingleValue                                          (const SsboArgData argData);
+       bool                    setAllValues                                            (const std::vector<SsboArgData> argDataList);
+
+       const std::string&      getContextVersion                               (void) const;
+       const std::string&      getStdFormat                                    (void) const;
+       const std::string&      getBindingPoint                                 (void) const;
+       const std::string&      getMatrixOrder                                  (void) const;
+       const std::string&      getMemberType                                   (void) const;
+       const std::string&      getMemberName                                   (void) const;
+       const std::string&      getMemberFixedArrayName                 (void) const;
+       const std::string&      getMemberVariableArray                  (void) const;
+       bool                            getMemberReorder                                (void) const;
+       int                                     getNumberMembers                                (void) const;
+
+       void                            resetValues                                             (void);
+
+       std::map<std::string, std::string>      populateArgsMap (void) const;
+
+private:
+       std::string             m_negativeContextVersion;
+       std::string             m_stdFormat;
+       std::string             m_bindingPoint;
+       std::string             m_matrixOrder;
+       std::string             m_memberType;
+       std::string             m_memberName;
+       std::string             m_memberFixedArrayerName;
+       std::string             m_memberVariableArray;
+       bool                    m_memberReorder;
+       int                             m_numberMembers;
+       tcu::TestLog&   m_testLog;
+
+       void                    setDefaultValues                                        (void);
+};
+
+//constructor which ensure a proper context is passed into the struct
+SsboArgs::SsboArgs(const std::string version, tcu::TestLog& log)
+       : m_negativeContextVersion      (version)
+       , m_numberMembers                       (8)
+       , m_testLog                                     (log)
+{
+       setDefaultValues();
+}
+
+void SsboArgs::setSingleValue (const SsboArgData argData)
+{
+       std::string message;
+
+       switch (argData.member)
+       {
+               case ARGMEMBER_FORMAT:
+                       m_stdFormat                                     =       argData.data;
+                       return;
+               case ARGMEMBER_BINDING_POINT:
+                       m_bindingPoint                          =       argData.data;
+                       return;
+               case ARGMEMBER_MATRIX_ORDER:
+                       m_matrixOrder                           =       argData.data;
+                       return;
+               case ARGMEMBER_MEMBER_TYPE:
+                       m_memberType                            =       argData.data;
+                       return;
+               case ARGMEMBER_NAME:
+                       m_memberName                            =       argData.data;
+                       return;
+               case ARGMEMBER_FIXED_ARRAY:
+                       m_memberFixedArrayerName        =       argData.data;
+                       return;
+               case ARGMEMBER_VARIABLE_ARRAY:
+                       m_memberVariableArray           =       argData.data;
+                       return;
+               case ARGMEMBER_REORDER:
+                       if (argData.data == "true")
+                       {
+                               m_memberReorder                 =       true;
+                       }
+                       return;
+               default:
+                       message = "auto loop argument data member not recognised.";
+                       m_testLog << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+       }
+}
+
+bool SsboArgs::setAllValues (const std::vector<SsboArgData> argDataList)
+{
+       std::string     message;
+
+       if ((argDataList.size() == 0) || (argDataList.size() > (size_t)m_numberMembers))
+       {
+               message = "set of args does not match the number of args struct changeable members.";
+               m_testLog << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+
+               return false;
+       }
+       else
+       {
+               for (unsigned int idx = 0; idx < argDataList.size(); idx++)
+               {
+                       setSingleValue(argDataList[idx]);
+               }
+       }
+
+       return true;
+}
+
+const std::string& SsboArgs::getContextVersion (void) const
+{
+       return m_negativeContextVersion;
+}
+
+const std::string& SsboArgs::getStdFormat (void) const
+{
+       return m_stdFormat;
+}
+
+const std::string& SsboArgs::getBindingPoint (void) const
+{
+       return m_bindingPoint;
+}
+
+const std::string& SsboArgs::getMatrixOrder (void) const
+{
+       return m_matrixOrder;
+}
+
+const std::string& SsboArgs::getMemberType (void) const
+{
+       return m_memberType;
+}
+
+const std::string& SsboArgs::getMemberName (void) const
+{
+       return m_memberName;
+}
+
+const std::string& SsboArgs::getMemberFixedArrayName (void) const
+{
+       return m_memberFixedArrayerName;
+}
+
+const std::string& SsboArgs::getMemberVariableArray (void) const
+{
+       return m_memberVariableArray;
+}
+
+bool SsboArgs::getMemberReorder (void) const
+{
+       return m_memberReorder;
+}
+
+int SsboArgs::getNumberMembers (void) const
+{
+       return m_numberMembers;
+}
+
+void SsboArgs::resetValues (void)
+{
+       setDefaultValues();
+}
+
+//converts SsboArgs member variable into a map object to be used by tcu::StringTemplate
+std::map<std::string, std::string> SsboArgs::populateArgsMap (void) const
+{
+       std::map<std::string, std::string> argsMap;
+
+       // key placeholders located at specific points in the ssbo block
+       argsMap["NEGATIVE_CONTEXT_VERSION"]     =       m_negativeContextVersion;
+       argsMap["STD_FORMAT"]                           =       m_stdFormat;
+       argsMap["BINDING_POINT"]                        =       m_bindingPoint;
+       argsMap["MATRIX_ORDER"]                         =       m_matrixOrder;
+       argsMap["MEMBER_TYPE"]                          =       m_memberType;
+       argsMap["MEMBER_NAME"]                          =       m_memberName;
+       argsMap["MEMBER_FIXED_ARRAY"]           =       m_memberFixedArrayerName;
+       argsMap["MEMBER_VARIABLE_ARRAY"]        =       m_memberVariableArray;
+
+       return argsMap;
+}
+
+// default values i.e. same shader template
+void SsboArgs::setDefaultValues (void)
+{
+       m_stdFormat                                     =       "std430";
+       m_bindingPoint                          =       "0";
+       m_matrixOrder                           =       "column_major";
+       m_memberType                            =       "int";
+       m_memberName                            =       "matrix";
+       m_memberFixedArrayerName        =       "10";
+       m_memberVariableArray           =       "";
+       m_memberReorder                         =       false;
+}
+} // args
+
+std::string generateVaryingSSBOShader(const glw::GLenum shaderType, const args::SsboArgs& args, tcu::TestLog& log)
+{
+       std::map<std::string, std::string>      argsMap;
+       std::ostringstream                                      source;
+       std::string                                                     sourceString;
+       std::stringstream                                       ssboString;
+       std::string                                                     message;
+
+       if (args.getMemberReorder())
+       {
+               ssboString      << "    mediump vec4 array_1[${MEMBER_FIXED_ARRAY}];\n"
+                                       << "    highp mat4 ${MEMBER_NAME};\n"
+                                       << "    lowp ${MEMBER_TYPE} data;\n"
+                                       << "    mediump float array_2[${MEMBER_VARIABLE_ARRAY}];\n";
+       }
+       else
+       {
+               ssboString      << "    lowp ${MEMBER_TYPE} data;\n"
+                                       << "    highp mat4 ${MEMBER_NAME};\n"
+                                       << "    mediump vec4 array_1[${MEMBER_FIXED_ARRAY}];\n"
+                                       << "    mediump float array_2[${MEMBER_VARIABLE_ARRAY}];\n";
+       }
+
+       argsMap = args.populateArgsMap();
+
+       switch (shaderType)
+       {
+               case GL_VERTEX_SHADER:
+               {
+                       source  << "${NEGATIVE_CONTEXT_VERSION}\n"
+                                       << "layout (location = 0) in highp vec4 position;\n"
+                                       << "layout (location = 1) in mediump vec4 colour;\n"
+                                       << "out mediump vec4 vertex_colour;\n"
+                                       << "layout (${STD_FORMAT}, binding = ${BINDING_POINT}, ${MATRIX_ORDER}) buffer ssbo_block\n"
+                                       << "{\n";
+
+                       source << ssboString.str();
+
+                       source  << "} ssbo;\n"
+                                       << "void main()\n"
+                                       << "{\n"
+                                       << "    mediump vec4 variable;\n"
+                                       << "    gl_Position = ssbo.${MEMBER_NAME} * position;\n"
+                                       << "    for (int idx = 0; idx < ${MEMBER_FIXED_ARRAY}; idx++)\n"
+                                       << "    {\n"
+                                       << "            variable += ssbo.array_1[idx];\n"
+                                       << "    }\n"
+                                       << "    vertex_colour = colour + variable;\n"
+                                       << "}\n";
+
+                       sourceString = source.str();
+                       sourceString = tcu::StringTemplate(sourceString).specialize(argsMap);
+
+                       return sourceString;
+               }
+
+               case GL_FRAGMENT_SHADER:
+               {
+                       source  << "${NEGATIVE_CONTEXT_VERSION}\n"
+                                       << "in mediump vec4 vertex_colour;\n"
+                                       << "layout (location = 0) out mediump vec4 fragment_colour;\n"
+                                       << "layout (${STD_FORMAT}, binding = ${BINDING_POINT}, ${MATRIX_ORDER}) buffer ssbo_block\n"
+                                       << "{\n";
+
+                       source << ssboString.str();
+
+                       source  << "} ssbo;\n"
+                                       << "void main()\n"
+                                       << "{\n"
+                                       << "    mediump vec4 variable;\n"
+                                       << "    variable * ssbo.${MEMBER_NAME};\n"
+                                       << "    for (int idx = 0; idx < ${MEMBER_FIXED_ARRAY}; idx++)\n"
+                                       << "    {\n"
+                                       << "            variable += ssbo.array_1[idx];\n"
+                                       << "    }\n"
+                                       << "    fragment_colour = vertex_colour + variable;\n"
+                                       << "}\n";
+
+                       sourceString = source.str();
+                       sourceString = tcu::StringTemplate(sourceString).specialize(argsMap);
+
+                       return sourceString;
+               }
+
+               case GL_GEOMETRY_SHADER:
+               {
+                       // TODO:
+                       return sourceString;
+               }
+
+               case GL_TESS_CONTROL_SHADER:
+               {
+                       // TODO:
+                       return sourceString;
+               }
+
+               case GL_TESS_EVALUATION_SHADER:
+               {
+                       // TODO:
+                       return sourceString;
+               }
+
+               case GL_COMPUTE_SHADER:
+               {
+                       // TODO:
+                       return sourceString;
+               }
+
+               default:
+               {
+                       message = "shader type not recognised.";
+                       log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+               }
+       }
+
+       return std::string();
+}
+
+void logProgramInfo(NegativeTestContext& ctx, GLint program)
+{
+       GLint                   maxLength       =       0;
+       std::string             message;
+       tcu::TestLog&   log                     =       ctx.getLog();
+
+       ctx.glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
+
+       message = "Program log:";
+       log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+
+       if (maxLength == 0)
+       {
+               message = "No available info log.";
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+               return;
+       }
+
+       std::vector<GLchar> infoLog(maxLength);
+       ctx.glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
+
+       std::string programLogMessage(&infoLog[0], maxLength);
+       log << tcu::TestLog::Message << programLogMessage << tcu::TestLog::EndMessage;
+}
+
+void ssbo_block_matching(NegativeTestContext& ctx)
+{
+       const bool                              isES32                                                                                                  =       contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version                                                                                                 =       isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       tcu::TestLog&                   log                                                                                                             =       ctx.getLog();
+       std::string                             message;
+       std::string                             versionString(glu::getGLSLVersionDeclaration(version));
+       args::SsboArgs                  ssboArgs(versionString, log);
+       GLint                                   shaderVertexGL;
+       std::string                             shaderVertexString;
+       const char*                             shaderVertexCharPtr;
+
+       // List of arguments used to create varying ssbo objects in the fragment shader
+       const args::SsboArgData argDataArrayFrag[] = {  args::SsboArgData(args::ARGMEMBER_FORMAT,                       "std140"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_BINDING_POINT,        "10"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_MATRIX_ORDER,         "row_major"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_MEMBER_TYPE,          "vec2"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_NAME,                         "name_changed"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_FIXED_ARRAY,          "20"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_VARIABLE_ARRAY,       "5"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_REORDER,                      "true") };
+       std::vector<args::SsboArgData> argDataVectorFrag(argDataArrayFrag, argDataArrayFrag + sizeof(argDataArrayFrag) / sizeof(argDataArrayFrag[0]));
+
+       // create default vertex shader
+       shaderVertexString = generateVaryingSSBOShader(GL_VERTEX_SHADER, ssboArgs, log);
+       shaderVertexCharPtr = shaderVertexString.c_str();
+       shaderVertexGL = ctx.glCreateShader(GL_VERTEX_SHADER);
+
+       // log
+       message = shaderVertexString;
+       log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+
+       // compile
+       ctx.glShaderSource(shaderVertexGL, 1, &shaderVertexCharPtr, DE_NULL);
+       ctx.glCompileShader(shaderVertexGL);
+
+       for (std::size_t idx = 0; idx < argDataVectorFrag.size(); ++idx)
+       {
+               GLint                   linkStatus                              =       -1;
+               GLint                   program;
+               GLint                   shaderFragmentGL;
+               std::string             shaderFragmentString;
+               const char*             shaderFragmentCharPtr;
+
+               ctx.beginSection("Multiple shaders created using SSBO's sharing the same name but not matching layouts");
+
+               program = ctx.glCreateProgram();
+
+               // reset args to default and make a single change
+               ssboArgs.resetValues();
+               ssboArgs.setSingleValue(argDataVectorFrag[idx]);
+
+               // create fragment shader
+               shaderFragmentString = generateVaryingSSBOShader(GL_FRAGMENT_SHADER, ssboArgs, log);
+               shaderFragmentCharPtr = shaderFragmentString.c_str();
+               shaderFragmentGL = ctx.glCreateShader(GL_FRAGMENT_SHADER);
+
+               // log
+               message = shaderFragmentString;
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+
+               // compile
+               ctx.glShaderSource(shaderFragmentGL, 1, &shaderFragmentCharPtr, DE_NULL);
+               ctx.glCompileShader(shaderFragmentGL);
+
+               // attach shaders to program and attempt to link
+               ctx.glAttachShader(program, shaderVertexGL);
+               ctx.glAttachShader(program, shaderFragmentGL);
+               ctx.glLinkProgram(program);
+               ctx.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+
+               logProgramInfo(ctx, program);
+
+               if (linkStatus == GL_TRUE)
+               {
+                       ctx.fail("Program should not have linked");
+               }
+
+               // clean up resources
+               ctx.glDeleteShader(shaderFragmentGL);
+               ctx.glDeleteProgram(program);
+
+               ctx.endSection();
+       }
+
+       // clean up default resources
+       ctx.glDeleteShader(shaderVertexGL);
+}
+
+void ssbo_block_shared_qualifier(NegativeTestContext& ctx)
+{
+       const bool                              isES32                                                                                                  =       contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version                                                                                                 =       isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       tcu::TestLog&                   log                                                                                                             =       ctx.getLog();
+       std::string                             message;
+       std::string                             versionString(glu::getGLSLVersionDeclaration(version));
+       args::SsboArgs                  ssboArgs(versionString, log);
+       bool                                    result;
+       GLint                                   shaderVertexGL;
+       std::string                             shaderVertexString;
+       const char*                             shaderVertexCharPtr;
+
+       // default args used in vertex shader ssbo
+       const args::SsboArgData argDataArrayVert[] = {  args::SsboArgData(args::ARGMEMBER_FORMAT,                       "shared"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_BINDING_POINT,        "0"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_MATRIX_ORDER,         "column_major"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_FIXED_ARRAY,          "10"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_VARIABLE_ARRAY,       "10"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_REORDER,                      "false") };
+       std::vector<args::SsboArgData> argDataVectorVert(argDataArrayVert, argDataArrayVert + sizeof(argDataArrayVert) / sizeof(argDataArrayVert[0]));
+
+       // args changed in fragment shader ssbo
+       const args::SsboArgData argDataArrayFrag[] = {  args::SsboArgData(args::ARGMEMBER_MATRIX_ORDER,         "row_major"),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_VARIABLE_ARRAY,       ""),
+                                                                                                       args::SsboArgData(args::ARGMEMBER_FIXED_ARRAY,          "20") };
+       std::vector<args::SsboArgData> argDataVectorFrag(argDataArrayFrag, argDataArrayFrag + sizeof(argDataArrayFrag) / sizeof(argDataArrayFrag[0]));
+
+       // set default vertex ssbo args
+       result = ssboArgs.setAllValues(argDataVectorVert);
+
+       if (result == false)
+       {
+               message = "Invalid use of args.setAllValues()";
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+               return;
+       }
+
+       // create default vertex shader
+       shaderVertexString = generateVaryingSSBOShader(GL_VERTEX_SHADER, ssboArgs, log);
+       shaderVertexCharPtr = shaderVertexString.c_str();
+       shaderVertexGL = ctx.glCreateShader(GL_VERTEX_SHADER);
+
+       // log
+       message = shaderVertexString;
+       log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+
+       // compile
+       ctx.glShaderSource(shaderVertexGL, 1, &shaderVertexCharPtr, DE_NULL);
+       ctx.glCompileShader(shaderVertexGL);
+
+       for (std::size_t idx = 0; idx < argDataVectorFrag.size(); idx++)
+       {
+               GLint           linkStatus                              =       -1;
+               GLint           program;
+               GLint           shaderFragmentGL;
+               std::string     shaderFragmentString;
+               const char*     shaderFragmentCharPtr;
+
+               ctx.beginSection("Multiple shaders created using SSBO's sharing the same name but not matching layouts");
+
+               program = ctx.glCreateProgram();
+
+               // reset args to default and make a single change
+               ssboArgs.setAllValues(argDataVectorVert);
+               ssboArgs.setSingleValue(argDataVectorFrag[idx]);
+
+               // create fragment shader
+               shaderFragmentString = generateVaryingSSBOShader(GL_FRAGMENT_SHADER, ssboArgs, log);
+               shaderFragmentCharPtr = shaderFragmentString.c_str();
+               shaderFragmentGL = ctx.glCreateShader(GL_FRAGMENT_SHADER);
+
+               // log
+               message = shaderFragmentString;
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+
+               // compile
+               ctx.glShaderSource(shaderFragmentGL, 1, &shaderFragmentCharPtr, DE_NULL);
+               ctx.glCompileShader(shaderFragmentGL);
+
+               // attach shaders to the program and attempt to link
+               ctx.glAttachShader(program, shaderVertexGL);
+               ctx.glAttachShader(program, shaderFragmentGL);
+               ctx.glLinkProgram(program);
+               ctx.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+
+               logProgramInfo(ctx, program);
+
+               if (linkStatus == GL_TRUE)
+               {
+                       ctx.fail("Program should not have linked");
+               }
+
+               // clean up resources
+               ctx.glDeleteShader(shaderFragmentGL);
+               ctx.glDeleteProgram(program);
+
+               ctx.endSection();
+       }
+
+       // clean up default resources
+       ctx.glDeleteShader(shaderVertexGL);
+}
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeSSBOBlockTestFunctions (void)
+{
+       const FunctionContainer funcs[] =
+       {
+               { ssbo_block_matching,                  "ssbo_block_interface_matching_tests",  "Invalid Shader Linkage" },
+               { ssbo_block_shared_qualifier,  "ssbo_using_shared_qualifier_tests",    "Invalid Shader Linkage" },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+} // NegativeTestShared
+} //Functional
+} //gles31
+} //deqp
diff --git a/modules/gles31/functional/es31fNegativeSSBOBlockTests.hpp b/modules/gles31/functional/es31fNegativeSSBOBlockTests.hpp
new file mode 100644 (file)
index 0000000..db1d3bb
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _ES31FNEGATIVESSBOBLOCKTESTS_HPP
+#define _ES31FNEGATIVESSBOBLOCKTESTS_HPP
+/*-------------------------------------------------------------------------
+* drawElements Quality Program OpenGL ES 3.1 Module
+* -------------------------------------------------
+*
+* Copyright 2016 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 Negative Shader Storage Block Object (SSBO) API tests.
+*//*--------------------------------------------------------------------*/
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeSSBOBlockTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVESSBOBLOCKTESTS_HPP
\ No newline at end of file
index 7c3fc0f..a80d6ca 100644 (file)
@@ -2334,7 +2334,7 @@ void link_compute_shader (NegativeTestContext& ctx)
        }
 }
 
-void compile_compute_shader_helper (NegativeTestContext& ctx, const char** computeShaderSource, GLint* compileStatus)
+void compile_compute_shader_helper (NegativeTestContext& ctx, const char* const* computeShaderSource, GLint* compileStatus)
 {
        GLuint shader = ctx.glCreateShader(GL_COMPUTE_SHADER);
 
@@ -2351,68 +2351,155 @@ void compile_compute_shader (NegativeTestContext& ctx)
        ctx.beginSection("Compile Computer Shader");
 
        {
-               const char* computeShaderSource         =       "#version 300 es\n"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 300 es\n"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled with #version 300 es.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "buffer SSBO { vec4 data }"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data }"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: incorrect SSBO syntax.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "buffer SSBO { vec4 data;};"
-                                                                                               "uniform mat4 data;"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data;};"
+                                                                                                               "uniform mat4 data;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: buffer variable redefinition.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "buffer SSBO { vec4 data[]; vec4 moreData;};"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data[]; vec4 moreData;};"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: unspecified length buffer member not at the end.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "in vec4 data;"
-                                                                                               "void main (void)\n"
-                                                                                               "{\n"
-                                                                                               "}\n\0";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "in vec4 data;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: input qualifier used.");
        }
        {
-               const char* computeShaderSource         =       "#version 310 es\n"
-                                                                                               "shared uint data = 0;";
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "shared uint data = 0;";
 
                compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
                if (compileStatus != GL_FALSE)
                        ctx.fail("Compute Shader should not have compiled: shared-qualified variable initialized.");
        }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data; vec4 moreData[];} ssbo;"
+                                                                                                               "void test (vec4 data[10]) {}"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "    test(ssbo.moreData);"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: unspecified length buffer member passed as argument to function.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO { vec4 data; vec4 moreData[];} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "    vec4 var = ssbo.moreData[-1];"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: unspecified length buffer member indexed with negative constant expression.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "layout(binding=-1) buffer SSBO { vec4 data;};"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: binding point less than zero.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "layout(binding=1) buffer;"
+                                                                                                               "layout(binding=2) buffer SSBO { vec4 data;};"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: binding point specified for global scope.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "buffer SSBO {"
+                                                                                                               "       layout(binding=1) vec4 data;"
+                                                                                                               "       layout(binding=2) vec4 moreData[];"
+                                                                                                               "} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: binding point specified for block member declarations.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "readonly buffer SSBO {vec4 data;} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                                       "ssbo.data = vec4(1, 1, 1, 1);"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: writing to buffer block qualified with readonly.");
+       }
+       {
+               const char* const computeShaderSource           =       "#version 310 es\n"
+                                                                                                               "writeonly buffer SSBO {vec4 data;} ssbo;"
+                                                                                                               "void main (void)\n"
+                                                                                                               "{\n"
+                                                                                                                       "vec4 var = ssbo.data;"
+                                                                                                               "}\n";
+
+               compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
+               if (compileStatus != GL_FALSE)
+                       ctx.fail("Compute Shader should not have compiled: reading from buffer block qualified with writeonly.");
+       }
+
        ctx.endSection();
 }
 
index 2b54462..8d87a21 100644 (file)
@@ -126,14 +126,42 @@ void primitive_bounding_box (NegativeTestContext& ctx)
        if (contextSupports(ctx.getRenderContext().getType() , glu::ApiType::es(3, 2)))
        {
                ctx.beginSection("gl_BoundingBox does not require the OES/EXT suffix in a 320 es shader.");
-               const std::string source =      "#version 320 es\n"
-                                                                       "layout(vertices = 3) out;\n"
-                                                                       "void main()\n"
-                                                                       "{\n"
-                                                                       "       gl_BoundingBox[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
-                                                                       "       gl_BoundingBox[1] = vec4(0.0, 0.0, 0.0, 0.0);\n"
-                                                                       "}\n";
-               verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source, EXPECT_RESULT_PASS);
+               {
+                       const std::string source =      "#version 320 es\n"
+                                                                               "layout(vertices = 3) out;\n"
+                                                                               "void main()\n"
+                                                                               "{\n"
+                                                                               "       gl_BoundingBox[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
+                                                                               "       gl_BoundingBox[1] = vec4(0.0, 0.0, 0.0, 0.0);\n"
+                                                                               "}\n";
+                       verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source, EXPECT_RESULT_PASS);
+               }
+               ctx.endSection();
+
+               ctx.beginSection("Invalid index used when assigning to gl_BoundingBox in 320 es shader.");
+               {
+                       const std::string source =      "#version 320 es\n"
+                                                                               "layout(vertices = 3) out;\n"
+                                                                               "void main()\n"
+                                                                               "{\n"
+                                                                               "       gl_BoundingBox[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
+                                                                               "       gl_BoundingBox[2] = vec4(0.0, 0.0, 0.0, 0.0);\n"
+                                                                               "}\n";
+                       verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source, EXPECT_RESULT_FAIL);
+               }
+               ctx.endSection();
+
+               ctx.beginSection("Invalid type assignment to per-patch output array in 320 es shader.");
+               {
+                       const std::string source =      "#version 320 es\n"
+                                                                               "layout(vertices = 3) out;\n"
+                                                                               "void main()\n"
+                                                                               "{\n"
+                                                                               "       gl_BoundingBox[0] = ivec4(0, 0, 0, 0);\n"
+                                                                               "       gl_BoundingBox[1] = ivec4(0, 0, 0, 0);\n"
+                                                                               "}\n";
+                       verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source, EXPECT_RESULT_FAIL);
+               }
                ctx.endSection();
        }
 }
@@ -474,6 +502,113 @@ void texture_cube_map_array (NegativeTestContext& ctx)
        ctx.endSection();
 }
 
+void executeAccessingBoundingBoxType (NegativeTestContext& ctx, const std::string builtInTypeName, glu::GLSLVersion glslVersion)
+{
+       std::ostringstream      sourceStream;
+       std::string                     version;
+       std::string                     extensionPrim;
+       std::string                     extensionTess;
+
+       if (glslVersion == glu::GLSL_VERSION_310_ES)
+       {
+               version = "#version 310 es\n";
+               extensionPrim = "#extension GL_EXT_primitive_bounding_box : require\n";
+               extensionTess = "#extension GL_EXT_tessellation_shader : require\n";
+       }
+       else if (glslVersion >= glu::GLSL_VERSION_320_ES)
+       {
+               version = "#version 320 es\n";
+               extensionPrim = "";
+               extensionTess = "";
+       }
+       else
+       {
+               DE_FATAL("error: context below 3.1 and not supported");
+       }
+
+       ctx.beginSection("cannot access built-in type " + builtInTypeName + "[]" + " in vertex shader");
+       sourceStream    << version
+                                       << extensionPrim
+                                       << "void main()\n"
+                                       << "{\n"
+                                       << "    " + builtInTypeName + "[0] = vec4(1.0, 1.0, 1.0, 1.0);\n"
+                                       << "    gl_Position = " + builtInTypeName + "[0];\n"
+                                       << "}\n";
+       verifyShader(ctx, glu::SHADERTYPE_VERTEX, sourceStream.str(), EXPECT_RESULT_FAIL);
+       ctx.endSection();
+
+       sourceStream.str(std::string());
+
+       if (ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_EVALUATION))
+       {
+               ctx.beginSection("cannot access built-in type " + builtInTypeName + "[]" + " in tessellation evaluation shader");
+               sourceStream    << version
+                                               << extensionPrim
+                                               << extensionTess
+                                               << "layout (triangles, equal_spacing, ccw) in;\n"
+                                               << "void main()\n"
+                                               << "{\n"
+                                               << "    " + builtInTypeName + "[0] = vec4(1.0, 1.0, 1.0, 1.0);\n"
+                                               << "    gl_Position = ( gl_TessCoord.x * " +  builtInTypeName + "[0] +\n"
+                                               << "                                    gl_TessCoord.y * " +  builtInTypeName + "[0] +\n"
+                                               << "                                    gl_TessCoord.z * " +  builtInTypeName + "[0]);\n"
+                                               << "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_EVALUATION, sourceStream.str(), EXPECT_RESULT_FAIL);
+               ctx.endSection();
+
+               sourceStream.str(std::string());
+       }
+
+       if (ctx.isShaderSupported(glu::SHADERTYPE_GEOMETRY))
+       {
+               ctx.beginSection("cannot access built-in type " + builtInTypeName + "[]" + " in geometry shader");
+               sourceStream    << version
+                                               << extensionPrim
+                                               << "layout (triangles) in;\n"
+                                               << "layout (triangle_strip, max_vertices = 3) out;\n"
+                                               << "void main()\n"
+                                               << "{\n"
+                                               << "    " + builtInTypeName + "[0] = vec4(1.0, 1.0, 1.0, 1.0);\n"
+                                               << "    for (int idx = 0; idx < 3; idx++)\n"
+                                               << "    {\n"
+                                               << "            gl_Position = gl_in[idx].gl_Position * " + builtInTypeName + "[0];\n"
+                                               << "            EmitVertex();\n"
+                                               << "    }\n"
+                                               << "    EndPrimitive();\n"
+                                               << "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_GEOMETRY, sourceStream.str(), EXPECT_RESULT_FAIL);
+               ctx.endSection();
+
+               sourceStream.str(std::string());
+       }
+
+       ctx.beginSection("cannot access built-in type " + builtInTypeName + "[]" + " in fragment shader");
+       sourceStream    << version
+                                       << extensionPrim
+                                       << "layout (location = 0) out mediump vec4 fs_colour;\n"
+                                       << "void main()\n"
+                                       << "{\n"
+                                       << "    " + builtInTypeName + "[0] = vec4(1.0, 1.0, 1.0, 1.0);\n"
+                                       << "    fs_colour = " + builtInTypeName + "[0];\n"
+                                       << "}\n";
+       verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, sourceStream.str(), EXPECT_RESULT_FAIL);
+       ctx.endSection();
+}
+
+void accessing_bounding_box_type (NegativeTestContext& ctx)
+{
+       // Extension requirements and name differences depending on the context
+       if ((ctx.getRenderContext().getType().getMajorVersion() == 3) && (ctx.getRenderContext().getType().getMinorVersion() == 1))
+       {
+               executeAccessingBoundingBoxType(ctx, "gl_BoundingBoxEXT", glu::GLSL_VERSION_310_ES);
+       }
+       else
+       {
+               executeAccessingBoundingBoxType(ctx, "gl_BoundingBox", glu::GLSL_VERSION_320_ES);
+       }
+
+}
+
 } // anonymous
 
 std::vector<FunctionContainer> getNegativeShaderDirectiveTestFunctions (void)
@@ -492,6 +627,7 @@ std::vector<FunctionContainer> getNegativeShaderDirectiveTestFunctions (void)
                {tessellation_shader,                                   "tessellation_shader",                                  "GL_EXT_tessellation_shader is required in 310 es shaders to use AEP features"                                                                                                  },
                {texture_buffer,                                                "texture_buffer",                                               "GL_EXT_texture_buffer is required in 310 es shaders to use AEP features"                                                                                                               },
                {texture_cube_map_array,                                "texture_cube_map_array",                               "GL_EXT_texture_cube_map_array is required in 310 es shaders to use AEP features"                                                                                               },
+               {accessing_bounding_box_type,                   "accessing_bounding_box_type",                  "Should not be able to access gl_BoundingBoxEXT[] and gl_BoundingBox[] in shaders other than tess control and evaluation"               },
        };
 
        return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
diff --git a/modules/gles31/functional/es31fNegativeShaderStorageTests.cpp b/modules/gles31/functional/es31fNegativeShaderStorageTests.cpp
new file mode 100644 (file)
index 0000000..31d425e
--- /dev/null
@@ -0,0 +1,330 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 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 Negative Shader Storage Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeShaderStorageTests.hpp"
+
+#include "gluShaderProgram.hpp"
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+void verifyProgram(NegativeTestContext& ctx, glu::ProgramSources sources)
+{
+       tcu::TestLog&                           log                     = ctx.getLog();
+       const glu::ShaderProgram        program         (ctx.getRenderContext(), sources);
+       bool                                            testFailed      = false;
+
+       log << program;
+
+       testFailed = program.getProgramInfo().linkOk;
+
+       if (testFailed)
+       {
+               const char* const message("Program was not expected to link.");
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+               ctx.fail(message);
+       }
+}
+
+const char* getShaderExtensionDeclaration (glw::GLenum glShaderType)
+{
+       switch (glShaderType)
+       {
+               case GL_TESS_CONTROL_SHADER:
+               case GL_TESS_EVALUATION_SHADER: return "#extension GL_EXT_tessellation_shader : require\n";
+               case GL_GEOMETRY_SHADER:                return "#extension GL_EXT_geometry_shader : require\n";
+               default:
+                       return "";
+       }
+}
+
+glu::ShaderType getGLUShaderType (glw::GLenum glShaderType)
+{
+       switch (glShaderType)
+       {
+               case GL_VERTEX_SHADER:                   return glu::SHADERTYPE_VERTEX;
+               case GL_FRAGMENT_SHADER:                 return glu::SHADERTYPE_FRAGMENT;
+               case GL_TESS_CONTROL_SHADER:     return glu::SHADERTYPE_TESSELLATION_CONTROL;
+               case GL_TESS_EVALUATION_SHADER:  return glu::SHADERTYPE_TESSELLATION_EVALUATION;
+               case GL_GEOMETRY_SHADER:                 return glu::SHADERTYPE_GEOMETRY;
+               case GL_COMPUTE_SHADER:                  return glu::SHADERTYPE_COMPUTE;
+               default:
+                       DE_FATAL("Unknown shader type");
+                       return glu::SHADERTYPE_LAST;
+       }
+}
+
+glw::GLenum getMaxSSBlockSizeEnum (glw::GLenum glShaderType)
+{
+       switch (glShaderType)
+       {
+               case GL_VERTEX_SHADER:                   return GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS;
+               case GL_FRAGMENT_SHADER:                 return GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS;
+               case GL_TESS_CONTROL_SHADER:     return GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS;
+               case GL_TESS_EVALUATION_SHADER:  return GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS;
+               case GL_GEOMETRY_SHADER:                 return GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS;
+               case GL_COMPUTE_SHADER:                  return GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS;
+               default:
+                        DE_FATAL("Unknown shader type");
+                        return -1;
+       }
+}
+
+int getMaxSSBlockSize (NegativeTestContext& ctx, glw::GLenum glShaderType)
+{
+       int maxSSBlocks = 0;
+       ctx.glGetIntegerv(getMaxSSBlockSizeEnum(glShaderType), &maxSSBlocks);
+
+       return maxSSBlocks;
+}
+
+std::string genBlockSource (NegativeTestContext& ctx, deInt64 numSSBlocks, glw::GLenum shaderType)
+{
+       const bool                              isES32          = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version         = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       std::ostringstream              source;
+
+       source  << glu::getGLSLVersionDeclaration(version) << "\n"
+                       << ((isES32) ? "" : getShaderExtensionDeclaration(shaderType));
+
+       switch (shaderType)
+       {
+               case GL_VERTEX_SHADER:
+               case GL_FRAGMENT_SHADER:
+                       break;
+
+               case GL_COMPUTE_SHADER:
+                       source << "layout (local_size_x = 1) in;\n";
+                       break;
+
+               case GL_GEOMETRY_SHADER:
+                       source << "layout(points) in;\n"
+                                  << "layout(line_strip, max_vertices = 3) out;\n";
+                       break;
+
+               case GL_TESS_CONTROL_SHADER:
+                       source << "layout(vertices = 10) out;\n";
+                       break;
+
+               case GL_TESS_EVALUATION_SHADER:
+                       source << "layout(triangles) in;\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unknown shader type");
+                       break;
+       }
+
+       source  << "\n"
+                       << "layout(std430, binding = 0) buffer Block {\n"
+                       << "    int value;\n"
+                       << "} sb_in[" << numSSBlocks << "];\n"
+                       << "void main(void) { sb_in[0].value = 1; }\n";
+
+       return source.str();
+}
+
+std::string genCommonSource (NegativeTestContext& ctx, glw::GLenum shaderType)
+{
+       const bool                              isES32          = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version         = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       std::ostringstream              source;
+
+       source << glu::getGLSLVersionDeclaration(version) << "\n"
+                  << ((isES32) ? "" : getShaderExtensionDeclaration(shaderType));
+
+       switch (shaderType)
+       {
+               case GL_TESS_CONTROL_SHADER:
+                       source  << "layout(vertices = 3) out;\n"
+                                       << "void main() {}\n";
+                       break;
+
+               case GL_TESS_EVALUATION_SHADER:
+                       source  << "layout(triangles, equal_spacing, cw) in;\n"
+                                       << "void main() {}\n";
+                       break;
+
+               default:
+                       source  << "void main() {}\n";
+                       break;
+       }
+
+       return source.str();
+}
+
+int genMaxSSBlocksSource (NegativeTestContext& ctx, glw::GLenum glShaderType, glu::ProgramSources& sources)
+{
+       int             maxSSBlocks                             = getMaxSSBlockSize(ctx, glShaderType);
+       const   std::string shaderSrc   = genBlockSource(ctx, (maxSSBlocks), glShaderType);
+
+       sources.sources[getGLUShaderType(glShaderType)].push_back(shaderSrc);
+
+       return maxSSBlocks;
+}
+
+void block_number_limits (NegativeTestContext& ctx)
+{
+       const glw::GLenum glShaderTypes[] =
+       {
+               GL_VERTEX_SHADER,
+               GL_FRAGMENT_SHADER,
+               GL_TESS_CONTROL_SHADER,
+               GL_TESS_EVALUATION_SHADER,
+               GL_GEOMETRY_SHADER,
+               GL_COMPUTE_SHADER,
+       };
+
+       const std::string       vertSource                      = genCommonSource(ctx, GL_VERTEX_SHADER);
+       const std::string       fragSource                      = genCommonSource(ctx, GL_FRAGMENT_SHADER);
+       const std::string       tessControlSource       = genCommonSource(ctx, GL_TESS_CONTROL_SHADER);
+       const std::string       tessEvalSource          = genCommonSource(ctx, GL_TESS_EVALUATION_SHADER);
+
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(glShaderTypes); ndx++)
+       {
+               ctx.beginSection("maxShaderStorageBlocks: Exceed limits");
+
+               if (!ctx.isShaderSupported(static_cast<glu::ShaderType>(getGLUShaderType(glShaderTypes[ndx]))))
+               {
+                       ctx.endSection();
+                       continue;
+               }
+
+               int                                     maxSSBlocks                     = getMaxSSBlockSize(ctx, glShaderTypes[ndx]);
+               std::string                     source                          = genBlockSource(ctx, maxSSBlocks+1, glShaderTypes[ndx]);
+
+               glu::ProgramSources sources;
+
+               if (maxSSBlocks == 0)
+               {
+                       ctx.endSection();
+                       continue;
+               }
+
+               switch (glShaderTypes[ndx])
+               {
+                       case GL_VERTEX_SHADER:
+                               sources << glu::VertexSource(source)
+                                               << glu::FragmentSource(fragSource);
+                               break;
+
+                       case GL_FRAGMENT_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(source);
+                               break;
+
+                       case GL_TESS_CONTROL_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(fragSource)
+                                               << glu::TessellationControlSource(source)
+                                               << glu::TessellationEvaluationSource(tessEvalSource);
+                               break;
+
+                       case GL_TESS_EVALUATION_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(fragSource)
+                                               << glu::TessellationControlSource(tessControlSource)
+                                               << glu::TessellationEvaluationSource(source);
+                               break;
+
+                       case GL_GEOMETRY_SHADER:
+                               sources << glu::VertexSource(vertSource)
+                                               << glu::FragmentSource(fragSource)
+                                               << glu::GeometrySource(source);
+                               break;
+
+                       case GL_COMPUTE_SHADER:
+                               sources << glu::ComputeSource(source);
+                               break;
+
+                       default:
+                               DE_FATAL("Unknown shader type");
+                               break;
+               }
+
+               verifyProgram(ctx, sources);
+               ctx.endSection();
+       }
+}
+
+void max_combined_block_number_limit (NegativeTestContext& ctx)
+{
+       ctx.beginSection("maxCombinedShaderStorageBlocks: Exceed limits");
+
+       glu::ProgramSources sources;
+
+       int combinedSSBlocks    = 0;
+       int maxCombinedSSBlocks = 0;
+
+       combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_VERTEX_SHADER, sources);
+       combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_FRAGMENT_SHADER, sources);
+
+       if ((ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_CONTROL)) && (ctx.isShaderSupported(glu::SHADERTYPE_TESSELLATION_EVALUATION)))
+       {
+               combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_TESS_CONTROL_SHADER, sources);
+               combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_TESS_EVALUATION_SHADER, sources);
+       }
+
+       if (ctx.isShaderSupported(glu::SHADERTYPE_GEOMETRY))
+               combinedSSBlocks += genMaxSSBlocksSource(ctx, GL_GEOMETRY_SHADER, sources);
+
+       ctx.glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &maxCombinedSSBlocks);
+
+       ctx.getLog() << tcu::TestLog::Message << "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: " << maxCombinedSSBlocks << tcu::TestLog::EndMessage;
+       ctx.getLog() << tcu::TestLog::Message << "Combined shader storage blocks: " << combinedSSBlocks << tcu::TestLog::EndMessage;
+
+       if (combinedSSBlocks > maxCombinedSSBlocks)
+               verifyProgram(ctx, sources);
+       else
+               ctx.getLog() << tcu::TestLog::Message << "Test skipped: Combined shader storage blocks < GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: " << tcu::TestLog::EndMessage;
+
+       ctx.endSection();
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeShaderStorageTestFunctions ()
+{
+       const FunctionContainer funcs[] =
+       {
+               { block_number_limits,                          "block_number_limits",                          "Invalid shader linkage" },
+               { max_combined_block_number_limit,      "max_combined_block_number_limit",      "Invalid shader linkage" },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeShaderStorageTests.hpp b/modules/gles31/functional/es31fNegativeShaderStorageTests.hpp
new file mode 100644 (file)
index 0000000..13cbd1f
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVESHADERSTORAGETESTS_HPP
+#define _ES31FNEGATIVESHADERSTORAGETESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 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 Negative Shader Storage Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeShaderStorageTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVESHADERSTORAGETESTS_HPP
index 1f1cfeb..19184c6 100644 (file)
@@ -184,8 +184,9 @@ void get_integer64v (NegativeTestContext& ctx)
 
 void get_integeri_v (NegativeTestContext& ctx)
 {
-       GLint data                                              = -1;
-       GLint maxUniformBufferBindings  = 0;
+       GLint data                                                              = -1;
+       GLint maxUniformBufferBindings                  =  0;
+       GLint maxShaderStorageBufferBindings    =  0;
 
        ctx.beginSection("GL_INVALID_ENUM is generated if name is not an accepted value.");
        ctx.glGetIntegeri_v(-1, 0, &data);
@@ -198,12 +199,20 @@ void get_integeri_v (NegativeTestContext& ctx)
        ctx.glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, maxUniformBufferBindings, &data);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if index is outside of the valid range for the indexed state target.");
+       ctx.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glGetIntegeri_v(GL_SHADER_STORAGE_BUFFER_BINDING, maxShaderStorageBufferBindings, &data);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
 }
 
 void get_integer64i_v (NegativeTestContext& ctx)
 {
-       GLint64 data                                            = (GLint64)-1;
-       GLint   maxUniformBufferBindings        = 0;
+       GLint64 data                                                    = (GLint64)-1;
+       GLint   maxUniformBufferBindings                = 0;
+       GLint   maxShaderStorageBufferBindings  = 0;
 
        ctx.beginSection("GL_INVALID_ENUM is generated if name is not an accepted value.");
        ctx.glGetInteger64i_v(-1, 0, &data);
@@ -216,6 +225,15 @@ void get_integer64i_v (NegativeTestContext& ctx)
        ctx.glGetInteger64i_v(GL_UNIFORM_BUFFER_START, maxUniformBufferBindings, &data);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if index is outside of the valid range for the indexed state target.");
+       ctx.glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &maxShaderStorageBufferBindings);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_START, maxShaderStorageBufferBindings, &data);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glGetInteger64i_v(GL_SHADER_STORAGE_BUFFER_SIZE, maxShaderStorageBufferBindings, &data);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
 }
 
 void get_string (NegativeTestContext& ctx)
diff --git a/modules/gles31/functional/es31fNegativeTessellationTests.cpp b/modules/gles31/functional/es31fNegativeTessellationTests.cpp
new file mode 100644 (file)
index 0000000..39c9b32
--- /dev/null
@@ -0,0 +1,426 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 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 Negative Tessellation tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeTessellationTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluShaderProgram.hpp"
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+#include "tcuStringTemplate.hpp"
+
+namespace deqp
+{
+
+using std::string;
+using std::map;
+
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+using tcu::TestLog;
+using namespace glw;
+
+static const char* vertexShaderSource          =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "\n"
+                                                                                               "void main (void)\n"
+                                                                                               "{\n"
+                                                                                               "       gl_Position = vec4(0.0);\n"
+                                                                                               "}\n";
+
+static const char* fragmentShaderSource                =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "precision mediump float;\n"
+                                                                                               "layout(location = 0) out mediump vec4 fragColor;\n"
+                                                                                               "\n"
+                                                                                               "void main (void)\n"
+                                                                                               "{\n"
+                                                                                               "       fragColor = vec4(1.0);\n"
+                                                                                               "}\n";
+
+static const char* tessControlShaderSource     =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "${GLSL_TESS_EXTENSION_STRING}\n"
+                                                                                               "layout (vertices=3) out;\n"
+                                                                                               "\n"
+                                                                                               "void main()\n"
+                                                                                               "{\n"
+                                                                                               "       gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                                                                               "}\n";
+
+static const char* tessEvalShaderSource                =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "${GLSL_TESS_EXTENSION_STRING}\n"
+                                                                                               "layout(triangles) in;\n"
+                                                                                               "\n"
+                                                                                               "void main()\n"
+                                                                                               "{\n"
+                                                                                               "       gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position;\n"
+                                                                                               "}\n";
+
+static void checkExtensionSupport (NegativeTestContext& ctx, const char* extName)
+{
+       if (!ctx.getContextInfo().isExtensionSupported(extName))
+               throw tcu::NotSupportedError(string(extName) + " not supported");
+}
+
+static void checkTessellationSupport (NegativeTestContext& ctx)
+{
+       checkExtensionSupport(ctx, "GL_EXT_tessellation_shader");
+}
+
+// Helper for constructing tessellation pipeline sources.
+static glu::ProgramSources makeTessPipelineSources (const std::string& vertexSrc, const std::string& fragmentSrc, const std::string& tessCtrlSrc, const std::string& tessEvalSrc)
+{
+       glu::ProgramSources sources;
+       sources.sources[glu::SHADERTYPE_VERTEX].push_back(vertexSrc);
+       sources.sources[glu::SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
+
+       if (!tessCtrlSrc.empty())
+               sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(tessCtrlSrc);
+
+       if (!tessEvalSrc.empty())
+               sources.sources[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back(tessEvalSrc);
+
+       return sources;
+}
+
+// Incomplete active tess shaders
+void single_tessellation_stage (NegativeTestContext& ctx)
+{
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const bool                                      requireTES = !ctx.getContextInfo().isExtensionSupported("GL_NV_gpu_shader5");
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       checkTessellationSupport(ctx);
+
+       {
+               glu::ShaderProgram program(ctx.getRenderContext(),
+                                                                  makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(tessControlShaderSource).specialize(args),
+                                                                                                                  "")); // missing tessEvalShaderSource
+               tcu::TestLog& log = ctx.getLog();
+               log << program;
+
+               ctx.beginSection("A link error is generated if a non-separable program has a tessellation control shader but no tessellation evaluation shader, unless GL_NV_gpu_shader5 is supported.");
+
+               if (requireTES && program.isOk())
+                       ctx.fail("Program was not expected to link");
+               else if (!requireTES && !program.isOk())
+                       ctx.fail("Program was expected to link");
+
+               ctx.endSection();
+       }
+
+       {
+               glu::ShaderProgram program(ctx.getRenderContext(),
+                                                                  makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(tessControlShaderSource).specialize(args),
+                                                                                                                  "") // missing tessEvalShaderSource
+                                                                  << glu::ProgramSeparable(true));
+               tcu::TestLog& log = ctx.getLog();
+               log << program;
+
+               if (!program.isOk())
+                       TCU_THROW(TestError, "failed to build program");
+
+               ctx.glUseProgram(program.getProgram());
+               ctx.expectError(GL_NO_ERROR);
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if current program state has tessellation control shader but no tessellation evaluation shader, unless GL_NV_gpu_shader5 is supported.");
+               ctx.glDrawArrays(GL_PATCHES, 0, 3);
+               ctx.expectError(requireTES ? GL_INVALID_OPERATION : GL_NO_ERROR);
+               ctx.endSection();
+
+               ctx.glUseProgram(0);
+       }
+
+       {
+               glu::ShaderProgram program(ctx.getRenderContext(),
+                                                                  makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                                  "", // missing tessControlShaderSource
+                                                                                                                  tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
+               tcu::TestLog& log = ctx.getLog();
+               log << program;
+
+               ctx.beginSection("A link error is generated if a non-separable program has a tessellation evaluation shader but no tessellation control shader.");
+
+               if (program.isOk())
+                       ctx.fail("Program was not expected to link");
+
+               ctx.endSection();
+       }
+
+       {
+               glu::ShaderProgram program(ctx.getRenderContext(),
+                                                                  makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                                  "", // missing tessControlShaderSource
+                                                                                                                  tcu::StringTemplate(tessEvalShaderSource).specialize(args))
+                                                                       << glu::ProgramSeparable(true));
+               tcu::TestLog& log = ctx.getLog();
+               log << program;
+
+               if (!program.isOk())
+                       TCU_THROW(TestError, "failed to build program");
+
+               ctx.glUseProgram(program.getProgram());
+               ctx.expectError(GL_NO_ERROR);
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if current program state has tessellation evaluation shader but no tessellation control shader.");
+               ctx.glDrawArrays(GL_PATCHES, 0, 3);
+               ctx.expectError(GL_INVALID_OPERATION);
+               ctx.endSection();
+
+               ctx.glUseProgram(0);
+       }
+}
+
+// Complete active tess shaders invalid primitive mode
+void invalid_primitive_mode (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       glu::ShaderProgram program(ctx.getRenderContext(),
+                                                          makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessControlShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
+       tcu::TestLog& log = ctx.getLog();
+       log << program;
+
+       ctx.glUseProgram(program.getProgram());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is active and primitive mode is not GL_PATCHES.");
+       ctx.glDrawArrays(GL_TRIANGLES, 0, 3);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glUseProgram(0);
+}
+
+void tessellation_not_active (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glw::GLenum                       tessErr = ctx.getContextInfo().isExtensionSupported("GL_NV_gpu_shader5") ? GL_NO_ERROR : GL_INVALID_OPERATION;
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       glu::ShaderProgram program(ctx.getRenderContext(),
+                                                          makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                          "",          // missing tessControlShaderSource
+                                                                                                          ""));        // missing tessEvalShaderSource
+       tcu::TestLog& log = ctx.getLog();
+       log << program;
+
+       ctx.glUseProgram(program.getProgram());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is not active and primitive mode is GL_PATCHES, unless GL_NV_gpu_shader5 is supported.");
+       ctx.glDrawArrays(GL_PATCHES, 0, 3);
+       ctx.expectError(tessErr);
+       ctx.endSection();
+
+       ctx.glUseProgram(0);
+}
+
+void invalid_program_state (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       glu::FragmentSource frgSource(tcu::StringTemplate(fragmentShaderSource).specialize(args));
+       glu::TessellationControlSource tessCtrlSource(tcu::StringTemplate(tessControlShaderSource).specialize(args));
+       glu::TessellationEvaluationSource tessEvalSource(tcu::StringTemplate(tessEvalShaderSource).specialize(args));
+
+       glu::ProgramPipeline pipeline(ctx.getRenderContext());
+
+       glu::ShaderProgram      fragProgram     (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << frgSource);
+       glu::ShaderProgram      tessCtrlProgram (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << tessCtrlSource);
+       glu::ShaderProgram      tessEvalProgram (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << tessEvalSource);
+
+       tcu::TestLog& log = ctx.getLog();
+       log << fragProgram << tessCtrlProgram << tessEvalProgram;
+
+       if (!fragProgram.isOk() || !tessCtrlProgram.isOk() || !tessEvalProgram.isOk())
+               throw tcu::TestError("failed to build program");
+
+       ctx.glBindProgramPipeline(pipeline.getPipeline());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.glUseProgramStages(pipeline.getPipeline(), GL_FRAGMENT_SHADER_BIT, fragProgram.getProgram());
+       ctx.glUseProgramStages(pipeline.getPipeline(), GL_TESS_CONTROL_SHADER_BIT, tessCtrlProgram.getProgram());
+       ctx.glUseProgramStages(pipeline.getPipeline(), GL_TESS_EVALUATION_SHADER_BIT, tessEvalProgram.getProgram());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is active and vertex shader is missing.");
+       ctx.glDrawArrays(GL_PATCHES, 0, 3);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glBindProgramPipeline(0);
+       ctx.expectError(GL_NO_ERROR);
+}
+
+void tessellation_control_invalid_vertex_count (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const char* const tessControlVertLimitSource    =       "${GLSL_VERSION_STRING}\n"
+                                                                                                               "${GLSL_TESS_EXTENSION_STRING}\n"
+                                                                                                               "layout (vertices=${GL_MAX_PATCH_LIMIT}) out;\n"
+                                                                                                               "void main()\n"
+                                                                                                               "{\n"
+                                                                                                               "       gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                                                                                               "}\n";
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       int maxPatchVertices= 0;
+
+       ctx.beginSection("Output vertex count exceeds GL_MAX_PATCH_VERTICES.");
+       ctx.glGetIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
+       ctx.expectError(GL_NO_ERROR);
+
+       std::ostringstream                              oss;
+       oss << (maxPatchVertices + 1);
+       args["GL_MAX_PATCH_LIMIT"] =    oss.str();
+
+
+       glu::ShaderProgram program(ctx.getRenderContext(),
+                                                          makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessControlVertLimitSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
+       tcu::TestLog& log = ctx.getLog();
+       log << program;
+
+       bool testFailed = program.getProgramInfo().linkOk;
+
+       if (testFailed)
+               ctx.fail("Program was not expected to link");
+
+       ctx.endSection();
+}
+
+void invalid_get_programiv (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       GLuint  program         = ctx.glCreateProgram();
+       GLint   params[1]       = { 0 };
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_CONTROL_OUTPUT_VERTICES, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_MODE is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_MODE, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_SPACING is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_SPACING, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_VERTEX_ORDER is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_VERTEX_ORDER, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_POINT_MODE is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_POINT_MODE, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glDeleteProgram(program);
+}
+
+void invalid_patch_parameteri (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       ctx.beginSection("GL_INVALID_ENUM is generated if pname is not GL_PATCH_VERTICES.");
+       ctx.glPatchParameteri(-1, 1);
+       ctx.expectError(GL_INVALID_ENUM);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if value is less than or equal to zero.");
+       ctx.glPatchParameteri(GL_PATCH_VERTICES, 0);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
+
+       int maxPatchVertices= 0;
+       ctx.glGetIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if value is greater than GL_MAX_PATCH_VERTICES.");
+       ctx.glPatchParameteri(GL_PATCH_VERTICES, maxPatchVertices + 1);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
+}
+
+std::vector<FunctionContainer> getNegativeTessellationTestFunctions (void)
+{
+       const FunctionContainer funcs[] =
+       {
+               { single_tessellation_stage,                                    "single_tessellation_stage",                                    "Invalid program state with single tessellation stage"                                                  },
+               { invalid_primitive_mode,                                               "invalid_primitive_mode",                                               "Invalid primitive mode when tessellation is active"                                                    },
+               { tessellation_not_active,                                              "tessellation_not_active",                                              "Use of GL_PATCHES when tessellation is not active"                                                             },
+               { invalid_program_state,                                                "invalid_program_state",                                                "Invalid program state when tessellation active but no vertex shader present"   },
+               { invalid_get_programiv,                                                "get_programiv",                                                                "Invalid glGetProgramiv() usage"                                                                                                },
+               { invalid_patch_parameteri,                                             "invalid_program_queries",                                              "Invalid glPatchParameteri() usage"                                                                                             },
+               { tessellation_control_invalid_vertex_count,    "tessellation_control_invalid_vertex_count",    "Exceed vertex count limit in tessellation control shader"                                              },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeTessellationTests.hpp b/modules/gles31/functional/es31fNegativeTessellationTests.hpp
new file mode 100644 (file)
index 0000000..d376656
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVETESSELLATIONTESTS_HPP
+#define _ES31FNEGATIVETESSELLATIONTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 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 Negative Tessellation tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeTessellationTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles3
+} // deqp
+
+#endif // _ES31FNEGATIVETESSELLATIONTESTS_HPP
index 6038b40..52f7146 100644 (file)
@@ -2916,8 +2916,6 @@ void texsubimage3d_neg_level (NegativeTestContext& ctx)
        ctx.glTexImage3D                (GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
        ctx.glBindTexture               (GL_TEXTURE_2D_ARRAY, textures[1]);
        ctx.glTexImage3D                (GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-       ctx.glBindTexture               (GL_TEXTURE_CUBE_MAP_ARRAY, textures[2]);
-       ctx.glTexImage3D                (GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 4, 4, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
        ctx.expectError                 (GL_NO_ERROR);
 
        ctx.beginSection("GL_INVALID_VALUE is generated if level is less than 0.");
@@ -2928,6 +2926,10 @@ void texsubimage3d_neg_level (NegativeTestContext& ctx)
 
        if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.getContextInfo().isExtensionSupported("GL_OES_texture_cube_map_array"))
        {
+               ctx.glBindTexture               (GL_TEXTURE_CUBE_MAP_ARRAY, textures[2]);
+               ctx.glTexImage3D                (GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 4, 4, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+               ctx.expectError                 (GL_NO_ERROR);
+
                ctx.glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, -1, 0, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
                ctx.expectError(GL_INVALID_VALUE);
        }
@@ -2971,8 +2973,6 @@ void texsubimage3d_neg_offset (NegativeTestContext& ctx)
        ctx.glTexImage3D                (GL_TEXTURE_3D, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
        ctx.glBindTexture               (GL_TEXTURE_2D_ARRAY, textures[1]);
        ctx.glTexImage3D                (GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, 4, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
-       ctx.glBindTexture               (GL_TEXTURE_CUBE_MAP_ARRAY, textures[2]);
-       ctx.glTexImage3D                (GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 4, 4, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
        ctx.expectError                 (GL_NO_ERROR);
 
        ctx.beginSection("GL_INVALID_VALUE is generated if xoffset, yoffset or zoffset are negative.");
@@ -2995,6 +2995,10 @@ void texsubimage3d_neg_offset (NegativeTestContext& ctx)
 
        if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.getContextInfo().isExtensionSupported("GL_OES_texture_cube_map_array"))
        {
+               ctx.glBindTexture               (GL_TEXTURE_CUBE_MAP_ARRAY, textures[2]);
+               ctx.glTexImage3D                (GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 4, 4, 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
+               ctx.expectError                 (GL_NO_ERROR);
+
                ctx.glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, -1, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
                ctx.expectError(GL_INVALID_VALUE);
                ctx.glTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, 0, -1, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
index c1fa0af..01cefc8 100644 (file)
@@ -1402,6 +1402,11 @@ private:
        {
                SCANRESULT_NUM_LINES_OK_BIT             = (1 << 0),
                SCANRESULT_LINE_WIDTH_OK_BIT    = (1 << 1),
+               SCANRESULT_LINE_WIDTH_WARN_BIT  = (1 << 2),
+               SCANRESULT_LINE_WIDTH_ERR_BIT   = (1 << 3),
+               SCANRESULT_LINE_CONT_OK_BIT             = (1 << 4),
+               SCANRESULT_LINE_CONT_ERR_BIT    = (1 << 5),
+               SCANRESULT_LINE_CONT_WARN_BIT   = (1 << 6),
        };
 
        void                            init                                                    (void);
@@ -1418,11 +1423,12 @@ private:
        void                            verifyRenderResult                              (const IterationConfig& config);
 
        tcu::IVec2                      getNumberOfLinesRange                   (int queryAreaBegin, int queryAreaEnd, float patternStart, float patternSize, int viewportArea, QueryDirection queryDir) const;
-       deUint8                         scanRow                                                 (const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, const tcu::IVec2& numLines, int& floodCounter) const;
-       deUint8                         scanColumn                                              (const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, const tcu::IVec2& numLines, int& floodCounter) const;
+       deUint8                         scanRow                                                 (const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, int rowViewportBegin, int rowViewportEnd, const tcu::IVec2& numLines, int& floodCounter) const;
+       deUint8                         scanColumn                                              (const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, int columnViewportBegin, int columnViewportEnd, const tcu::IVec2& numLines, int& floodCounter) const;
        bool                            checkAreaNumLines                               (const tcu::ConstPixelBufferAccess& access, const tcu::IVec4& area, int& floodCounter, int componentNdx, const tcu::IVec2& numLines) const;
+       deUint8                         checkLineContinuity                             (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const;
        tcu::IVec2                      getNumMinimaMaxima                              (const tcu::ConstPixelBufferAccess& access, int componentNdx) const;
-       bool                            checkLineWidths                                 (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& floodCounter) const;
+       deUint8                         checkLineWidths                                 (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& floodCounter) const;
        void                            printLineWidthError                             (const tcu::IVec2& pos, int detectedLineWidth, const tcu::IVec2& lineWidthRange, bool isHorizontal, int& floodCounter) const;
 
        const int                       m_patternSide;
@@ -1787,23 +1793,38 @@ void LineRenderCase::renderTestPattern (const IterationConfig& config)
 
 void LineRenderCase::verifyRenderResult (const IterationConfig& config)
 {
-       const glw::Functions&   gl                                              = m_context.getRenderContext().getFunctions();
-       const bool                              isMsaa                                  = m_context.getRenderTarget().getNumSamples() > 1;
-       const ProjectedBBox             projectedBBox                   = projectBoundingBox(config.bbox);
-       const float                             lineWidth                               = (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);
-       const tcu::IVec4                viewportBBoxArea                = getViewportBoundingBoxArea(projectedBBox, config.viewportSize, lineWidth);
-       const tcu::IVec4                viewportPatternArea             = getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
-       const tcu::IVec2                expectedHorizontalLines = getNumberOfLinesRange(viewportBBoxArea.y(), viewportBBoxArea.w(), config.patternPos.y(), config.patternSize.y(), config.viewportSize.y(), DIRECTION_VERTICAL);
-       const tcu::IVec2                expectedVerticalLines   = getNumberOfLinesRange(viewportBBoxArea.x(), viewportBBoxArea.z(), config.patternPos.x(), config.patternSize.x(), config.viewportSize.x(), DIRECTION_HORIZONTAL);
-       const tcu::IVec4                verificationArea                = tcu::IVec4(de::max(viewportBBoxArea.x(), 0),
-                                                                                                                                de::max(viewportBBoxArea.y(), 0),
-                                                                                                                                de::min(viewportBBoxArea.z(), config.viewportSize.x()),
-                                                                                                                                de::min(viewportBBoxArea.w(), config.viewportSize.y()));
+       const glw::Functions&   gl                                                      = m_context.getRenderContext().getFunctions();
+       const bool                              isMsaa                                          = m_context.getRenderTarget().getNumSamples() > 1;
+       const ProjectedBBox             projectedBBox                           = projectBoundingBox(config.bbox);
+       const float                             lineWidth                                       = (m_isWideLineCase) ? ((float)m_wideLineLineWidth) : (1.0f);
+       const tcu::IVec4                viewportBBoxArea                        = getViewportBoundingBoxArea(projectedBBox, config.viewportSize, lineWidth);
+       const tcu::IVec4                viewportPatternArea                     = getViewportPatternArea(config.patternPos, config.patternSize, config.viewportSize, ROUND_INWARDS);
+       const tcu::IVec2                expectedHorizontalLines         = getNumberOfLinesRange(viewportBBoxArea.y(), viewportBBoxArea.w(), config.patternPos.y(), config.patternSize.y(), config.viewportSize.y(), DIRECTION_VERTICAL);
+       const tcu::IVec2                expectedVerticalLines           = getNumberOfLinesRange(viewportBBoxArea.x(), viewportBBoxArea.z(), config.patternPos.x(), config.patternSize.x(), config.viewportSize.x(), DIRECTION_HORIZONTAL);
+       const tcu::IVec4                verificationArea                        = tcu::IVec4(de::max(viewportBBoxArea.x(), 0),
+                                                                                                                                        de::max(viewportBBoxArea.y(), 0),
+                                                                                                                                        de::min(viewportBBoxArea.z(), config.viewportSize.x()),
+                                                                                                                                        de::min(viewportBBoxArea.w(), config.viewportSize.y()));
+
+       tcu::Surface                    viewportSurface                         (config.viewportSize.x(), config.viewportSize.y());
+       int                                             messageLimitCounter                     = 8;
+
+       enum ScanResultCodes
+       {
+               SCANRESULT_NUM_LINES_ERR        = 0,
+               SCANRESULT_LINE_WIDTH_MSAA      = 1,
+               SCANRESULT_LINE_WIDTH_WARN      = 2,
+               SCANRESULT_LINE_WIDTH_ERR       = 3,
+               SCANRESULT_LINE_CONT_ERR        = 4,
+               SCANRESULT_LINE_CONT_WARN       = 5,
+               SCANRESULT_LINE_LAST
+       };
 
-       tcu::Surface                    viewportSurface                 (config.viewportSize.x(), config.viewportSize.y());
-       bool                                    anyError                                = false;
-       bool                                    msaaRelaxationRequired  = false;
-       int                                             messageLimitCounter             = 8;
+       int                                             rowScanResult[SCANRESULT_LINE_LAST]             = {0, 0, 0, 0, 0, 0};
+       int                                             columnScanResult[SCANRESULT_LINE_LAST]  = {0, 0, 0, 0, 0, 0};
+       bool                                    anyError                                                                = false;
+       bool                                    msaaRelaxationRequired                                  = false;
+       bool                                    hwIssueRelaxationRequired                               = false;
 
        if (!m_calcPerPrimitiveBBox)
                m_testCtx.getLog()
@@ -1841,20 +1862,34 @@ void LineRenderCase::verifyRenderResult (const IterationConfig& config)
                                                                           y,
                                                                           verificationArea.x(),
                                                                           verificationArea.z(),
+                                                                          de::max(verificationArea.x(), viewportPatternArea.x()),
+                                                                          de::min(verificationArea.z(), viewportPatternArea.z()),
                                                                           expectedVerticalLines,
                                                                           messageLimitCounter);
 
                if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
-                       anyError = true;
+                       rowScanResult[SCANRESULT_NUM_LINES_ERR]++;
+               if ((result & SCANRESULT_LINE_CONT_OK_BIT) == 0)
+               {
+                       if ((result & SCANRESULT_LINE_CONT_WARN_BIT) != 0)
+                               rowScanResult[SCANRESULT_LINE_CONT_WARN]++;
+                       else
+                               rowScanResult[SCANRESULT_LINE_CONT_ERR]++;
+               }
                else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
                {
                        if (m_isWideLineCase && isMsaa)
                        {
                                // multisampled wide lines might not be supported
-                               msaaRelaxationRequired = true;
+                               rowScanResult[SCANRESULT_LINE_WIDTH_MSAA]++;
+                       }
+                       else if ((result & SCANRESULT_LINE_WIDTH_ERR_BIT) == 0 &&
+                                        (result & SCANRESULT_LINE_WIDTH_WARN_BIT) != 0)
+                       {
+                               rowScanResult[SCANRESULT_LINE_WIDTH_WARN]++;
                        }
                        else
-                               anyError = true;
+                               rowScanResult[SCANRESULT_LINE_WIDTH_ERR]++;
                }
        }
 
@@ -1865,24 +1900,63 @@ void LineRenderCase::verifyRenderResult (const IterationConfig& config)
                                                                                  x,
                                                                                  verificationArea.y(),
                                                                                  verificationArea.w(),
+                                                                                 de::min(verificationArea.y(), viewportPatternArea.y()),
+                                                                                 de::min(verificationArea.w(), viewportPatternArea.w()),
                                                                                  expectedHorizontalLines,
                                                                                  messageLimitCounter);
 
                if ((result & SCANRESULT_NUM_LINES_OK_BIT) == 0)
-                       anyError = true;
+                       columnScanResult[SCANRESULT_NUM_LINES_ERR]++;
+               if ((result & SCANRESULT_LINE_CONT_OK_BIT) == 0)
+               {
+                       if ((result & SCANRESULT_LINE_CONT_WARN_BIT) != 0)
+                               columnScanResult[SCANRESULT_LINE_CONT_WARN]++;
+                       else
+                               columnScanResult[SCANRESULT_LINE_CONT_ERR]++;
+               }
                else if ((result & SCANRESULT_LINE_WIDTH_OK_BIT) == 0)
                {
                        if (m_isWideLineCase && isMsaa)
                        {
                                // multisampled wide lines might not be supported
-                               msaaRelaxationRequired = true;
+                               columnScanResult[SCANRESULT_LINE_WIDTH_MSAA]++;
+                       }
+                       else if ((result & SCANRESULT_LINE_WIDTH_ERR_BIT) == 0 &&
+                                        (result & SCANRESULT_LINE_WIDTH_WARN_BIT) != 0)
+                       {
+                               columnScanResult[SCANRESULT_LINE_WIDTH_WARN]++;
                        }
                        else
-                               anyError = true;
+                               columnScanResult[SCANRESULT_LINE_WIDTH_ERR]++;
                }
        }
 
-       if (anyError || msaaRelaxationRequired)
+       if (columnScanResult[SCANRESULT_LINE_WIDTH_ERR] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_ERR] != 0)
+               anyError = true;
+       else if(columnScanResult[SCANRESULT_LINE_CONT_ERR] != 0 || rowScanResult[SCANRESULT_LINE_CONT_ERR] != 0)
+               anyError = true;
+       else if (columnScanResult[SCANRESULT_LINE_WIDTH_MSAA] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_MSAA] != 0)
+               msaaRelaxationRequired = true;
+       else if (columnScanResult[SCANRESULT_LINE_WIDTH_WARN] != 0 || rowScanResult[SCANRESULT_LINE_WIDTH_WARN] != 0)
+               hwIssueRelaxationRequired = true;
+       else if (columnScanResult[SCANRESULT_NUM_LINES_ERR] != 0)
+       {
+               // found missing lines in a columnw and row line continuity check reported a warning (not an error) -> line width precision issue
+               if (rowScanResult[SCANRESULT_LINE_CONT_ERR] == 0 && rowScanResult[SCANRESULT_LINE_CONT_WARN])
+                       hwIssueRelaxationRequired = true;
+               else
+                       anyError = true;
+       }
+       else if (rowScanResult[SCANRESULT_NUM_LINES_ERR] != 0)
+       {
+               // found missing lines in a row and column line continuity check reported a warning (not an error) -> line width precision issue
+               if (columnScanResult[SCANRESULT_LINE_CONT_ERR] == 0 && columnScanResult[SCANRESULT_LINE_CONT_WARN])
+                       hwIssueRelaxationRequired = true;
+               else
+                       anyError = true;
+       }
+
+       if (anyError || msaaRelaxationRequired || hwIssueRelaxationRequired)
        {
                if (messageLimitCounter < 0)
                        m_testCtx.getLog() << tcu::TestLog::Message << "Omitted " << (-messageLimitCounter) << " row/column error descriptions." << tcu::TestLog::EndMessage;
@@ -1897,6 +1971,11 @@ void LineRenderCase::verifyRenderResult (const IterationConfig& config)
 
                if (anyError)
                        m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Image verification failed");
+               else if (hwIssueRelaxationRequired)
+               {
+                       // Line width hw issue
+                       m_testCtx.setTestResult(QP_TEST_RESULT_QUALITY_WARNING, "Line width verification failed");
+               }
                else
                {
                        // MSAA wide lines are optional
@@ -1947,22 +2026,50 @@ tcu::IVec2 LineRenderCase::getNumberOfLinesRange (int queryAreaBegin, int queryA
        return tcu::IVec2(numLinesMin, numLinesMax);
 }
 
-deUint8 LineRenderCase::scanRow (const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
+deUint8 LineRenderCase::scanRow (const tcu::ConstPixelBufferAccess& access, int row, int rowBegin, int rowEnd, int rowViewportBegin, int rowViewportEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
 {
-       const bool numLinesOk   = checkAreaNumLines(access, tcu::IVec4(rowBegin, row, rowEnd - rowBegin, 1), messageLimitCounter, SCAN_ROW_COMPONENT_NDX, numLines);
-       const bool lineWidthOk  = checkLineWidths(access, tcu::IVec2(rowBegin, row), tcu::IVec2(rowEnd, row), SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
+       const bool              numLinesOk                      = checkAreaNumLines(access, tcu::IVec4(rowBegin, row, rowEnd - rowBegin, 1), messageLimitCounter, SCAN_ROW_COMPONENT_NDX, numLines);
+       const deUint8   lineWidthRes            = checkLineWidths(access, tcu::IVec2(rowBegin, row), tcu::IVec2(rowEnd, row), SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
+       const deUint8   lineContinuityRes       = checkLineContinuity(access, tcu::IVec2(rowViewportBegin, row), tcu::IVec2(rowViewportEnd, row), SCAN_COL_COMPONENT_NDX, messageLimitCounter);
+       deUint8                 result                          = 0;
 
-       return  (deUint8)((numLinesOk   ? (deUint8)SCANRESULT_NUM_LINES_OK_BIT  : 0u) |
-                                         (lineWidthOk  ? (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT : 0u));
+       if (numLinesOk)
+               result |= (deUint8)SCANRESULT_NUM_LINES_OK_BIT;
+
+       if (lineContinuityRes == 0)
+               result |= (deUint8)SCANRESULT_LINE_CONT_OK_BIT;
+       else
+               result |= lineContinuityRes;
+
+       if (lineWidthRes == 0)
+               result |= (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT;
+       else
+               result |= lineWidthRes;
+
+       return result;
 }
 
-deUint8 LineRenderCase::scanColumn (const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
+deUint8 LineRenderCase::scanColumn (const tcu::ConstPixelBufferAccess& access, int column, int columnBegin, int columnEnd, int columnViewportBegin, int columnViewportEnd, const tcu::IVec2& numLines, int& messageLimitCounter) const
 {
-       const bool numLinesOk   = checkAreaNumLines(access, tcu::IVec4(column, columnBegin, 1, columnEnd - columnBegin), messageLimitCounter, SCAN_COL_COMPONENT_NDX, numLines);
-       const bool lineWidthOk  = checkLineWidths(access, tcu::IVec2(column, columnBegin), tcu::IVec2(column, columnEnd), SCAN_COL_COMPONENT_NDX, messageLimitCounter);
+       const bool              numLinesOk                      = checkAreaNumLines(access, tcu::IVec4(column, columnBegin, 1, columnEnd - columnBegin), messageLimitCounter, SCAN_COL_COMPONENT_NDX, numLines);
+       const deUint8   lineWidthRes            = checkLineWidths(access, tcu::IVec2(column, columnBegin), tcu::IVec2(column, columnEnd), SCAN_COL_COMPONENT_NDX, messageLimitCounter);
+       const deUint8   lineContinuityRes       = checkLineContinuity(access, tcu::IVec2(column, columnViewportBegin), tcu::IVec2(column, columnViewportEnd), SCAN_ROW_COMPONENT_NDX, messageLimitCounter);
+       deUint8                 result                          = 0;
+
+       if (numLinesOk)
+               result |= (deUint8)SCANRESULT_NUM_LINES_OK_BIT;
+
+       if (lineContinuityRes == 0)
+               result |= (deUint8)SCANRESULT_LINE_CONT_OK_BIT;
+       else
+               result |= lineContinuityRes;
 
-       return  (deUint8)((numLinesOk   ? (deUint8)SCANRESULT_NUM_LINES_OK_BIT  : 0u) |
-                                         (lineWidthOk  ? (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT : 0u));
+       if (lineWidthRes == 0)
+               result |= (deUint8)SCANRESULT_LINE_WIDTH_OK_BIT;
+       else
+               result |= lineWidthRes;
+
+       return result;
 }
 
 bool LineRenderCase::checkAreaNumLines (const tcu::ConstPixelBufferAccess& access, const tcu::IVec4& area, int& messageLimitCounter, int componentNdx, const tcu::IVec2& numLines) const
@@ -2052,19 +2159,64 @@ tcu::IVec2 LineRenderCase::getNumMinimaMaxima (const tcu::ConstPixelBufferAccess
        return tcu::IVec2(numMinima, numMaxima);
 }
 
-bool LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const
+deUint8 LineRenderCase::checkLineContinuity (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const
 {
-       const bool                      multisample             = m_context.getRenderTarget().getNumSamples() > 1;
-       const int                       lineRenderWidth = (m_isWideLineCase) ? (m_wideLineLineWidth) : 1;
-       const tcu::IVec2        lineWidthRange  = (multisample)
-                                                                                       ? (tcu::IVec2(lineRenderWidth, lineRenderWidth+1))      // multisampled "smooth" lines may spread to neighboring pixel
-                                                                                       : (tcu::IVec2(lineRenderWidth, lineRenderWidth));
+       bool                            line                                    = false;
+       const tcu::IVec2        advance                                 = (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
+       int                                     missedPixels                    = 0;
+       int                                     totalPixels                             = 0;
+       deUint8                         errorMask                               = 0;
 
-       int                                     lineWidth               = 0;
-       bool                            bboxLimitedLine = false;
-       bool                            anyError                = false;
+       for (tcu::IVec2 cursor = begin; cursor != end; cursor += advance)
+       {
+               const bool hit = (access.getPixelInt(cursor.x(), cursor.y())[componentNdx] != 0);
+
+               if (hit)
+                       line = true;
+               else if (line && !hit)
+               {
+                       // non-continuous line detected
+                       const tcu::IVec2 advanceNeighbor        = tcu::IVec2(1, 1) - advance;
+                       const tcu::IVec2 cursorNeighborPos      = cursor + advanceNeighbor;
+                       const tcu::IVec2 cursorNeighborNeg      = cursor - advanceNeighbor;
+                       // hw precision issues may lead to a line being non-straight -> check neighboring pixels
+                       if ((access.getPixelInt(cursorNeighborPos.x(), cursorNeighborPos.y())[componentNdx] == 0) && (access.getPixelInt(cursorNeighborNeg.x(), cursorNeighborNeg.y())[componentNdx] == 0))
+                               ++missedPixels;
+               }
+               ++totalPixels;
+       }
+
+       if (missedPixels > 0 && --messageLimitCounter >= 0)
+       {
+               m_testCtx.getLog()
+                       << tcu::TestLog::Message
+                       << "Found non-continuous " << ((advance.x() == 1)  ? ("horizontal") : ("vertical")) << " line near " << begin << ". "
+                       << "Missed pixels: " << missedPixels
+                       << tcu::TestLog::EndMessage;
+               // allow 10% missing pixels for warning
+               if (missedPixels <= deRoundFloatToInt32((float)totalPixels * 0.1f))
+                       errorMask = SCANRESULT_LINE_CONT_WARN_BIT;
+               else
+                       errorMask =  SCANRESULT_LINE_CONT_ERR_BIT;
+       }
+
+       return errorMask;
+}
+
+deUint8 LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access, const tcu::IVec2& begin, const tcu::IVec2& end, int componentNdx, int& messageLimitCounter) const
+{
+       const bool                      multisample                             = m_context.getRenderTarget().getNumSamples() > 1;
+       const int                       lineRenderWidth                 = (m_isWideLineCase) ? (m_wideLineLineWidth) : 1;
+       const tcu::IVec2        lineWidthRange                  = (multisample)
+                                                                                                       ? (tcu::IVec2(lineRenderWidth, lineRenderWidth+1))      // multisampled "smooth" lines may spread to neighboring pixel
+                                                                                                       : (tcu::IVec2(lineRenderWidth, lineRenderWidth));
+       const tcu::IVec2        relaxedLineWidthRange   = (tcu::IVec2(lineRenderWidth-1, lineRenderWidth+1));
 
-       const tcu::IVec2        advance                 = (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
+       int                                     lineWidth                               = 0;
+       bool                            bboxLimitedLine                 = false;
+       deUint8                         errorMask                               = 0;
+
+       const tcu::IVec2        advance                                 = (begin.x() == end.x()) ? (tcu::IVec2(0, 1)) : (tcu::IVec2(1, 0));
 
        // fragments before begin?
        if (access.getPixelInt(begin.x(), begin.y())[componentNdx] != 0)
@@ -2099,7 +2251,13 @@ bool LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access,
 
                        if (incorrectLineWidth)
                        {
-                               anyError = true;
+                               const bool incorrectRelaxedLineWidth = (lineWidth < relaxedLineWidthRange.x() && !bboxLimitedLine) || (lineWidth > relaxedLineWidthRange.y());
+
+                               if (incorrectRelaxedLineWidth)
+                                       errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
+                               else
+                                       errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;
+
                                printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
                        }
 
@@ -2117,7 +2275,11 @@ bool LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access,
                        {
                                if (lineWidth > lineWidthRange.y())
                                {
-                                       anyError = true;
+                                       if (lineWidth > relaxedLineWidthRange.y())
+                                               errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
+                                       else
+                                               errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;
+
                                        printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
                                }
 
@@ -2135,7 +2297,13 @@ bool LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access,
 
                                if (incorrectLineWidth)
                                {
-                                       anyError = true;
+                                       const bool incorrectRelaxedLineWidth = (lineWidth > relaxedLineWidthRange.y());
+
+                                       if (incorrectRelaxedLineWidth)
+                                               errorMask |= SCANRESULT_LINE_WIDTH_ERR_BIT;
+                                       else
+                                               errorMask |= SCANRESULT_LINE_WIDTH_WARN_BIT;
+
                                        printLineWidthError(cursor, lineWidth, lineWidthRange, advance.x() == 0, messageLimitCounter);
                                }
 
@@ -2144,7 +2312,7 @@ bool LineRenderCase::checkLineWidths (const tcu::ConstPixelBufferAccess& access,
                }
        }
 
-       return !anyError;
+       return errorMask;
 }
 
 void LineRenderCase::printLineWidthError (const tcu::IVec2& pos, int detectedLineWidth, const tcu::IVec2& lineWidthRange, bool isHorizontal, int& messageLimitCounter) const
diff --git a/modules/gles31/functional/es31fSRGBDecodeTests.cpp b/modules/gles31/functional/es31fSRGBDecodeTests.cpp
new file mode 100644 (file)
index 0000000..d3f947f
--- /dev/null
@@ -0,0 +1,2057 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 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 Texture format tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fSRGBDecodeTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluCallLogWrapper.hpp"
+#include "gluRenderContext.hpp"
+#include "gluTexture.hpp"
+#include "glsTextureTestUtil.hpp"
+#include "tcuPixelFormat.hpp"
+#include "tcuTestContext.hpp"
+#include "tcuRenderTarget.hpp"
+#include "gluTextureUtil.hpp"
+#include "tcuTextureUtil.hpp"
+#include "glwFunctions.hpp"
+#include "gluDefs.hpp"
+#include "glwEnums.hpp"
+#include "deUniquePtr.hpp"
+#include "gluPixelTransfer.hpp"
+#include "tcuDefs.hpp"
+#include "tcuVectorUtil.hpp"
+#include "gluObjectWrapper.hpp"
+#include "gluStrUtil.hpp"
+#include "tcuTestLog.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace
+{
+
+using glu::TextureTestUtil::TEXTURETYPE_2D;
+
+enum SRGBDecode
+{
+       SRGBDECODE_SKIP_DECODE          = 0,
+       SRGBDECODE_DECODE,
+       SRGBDECODE_DECODE_DEFAULT
+};
+
+enum ShaderOutputs
+{
+       SHADEROUTPUTS_ONE       = 1,
+       SHADEROUTPUTS_TWO,
+};
+
+enum ShaderUniforms
+{
+       SHADERUNIFORMS_ONE      = 1,
+       SHADERUNIFORMS_TWO,
+};
+
+enum ShaderSamplingGroup
+{
+       SHADERSAMPLINGGROUP_TEXTURE             = 0,
+       SHADERSAMPLINGGROUP_TEXEL_FETCH
+};
+
+enum ShaderSamplingType
+{
+       TEXTURESAMPLING_TEXTURE                                                                                                 = 0,
+       TEXTURESAMPLING_TEXTURE_LOD,
+       TEXTURESAMPLING_TEXTURE_GRAD,
+       TEXTURESAMPLING_TEXTURE_OFFSET,
+       TEXTURESAMPLING_TEXTURE_PROJ,
+       TEXTURESAMPLING_TEXELFETCH,
+       TEXTURESAMPLING_TEXELFETCH_OFFSET,
+
+       // ranges required for looping mechanism in a case nodes iteration function
+       TEXTURESAMPLING_TEXTURE_START           = TEXTURESAMPLING_TEXTURE,
+       TEXTURESAMPLING_TEXTURE_END                     = TEXTURESAMPLING_TEXTURE_PROJ          + 1,
+       TEXTURESAMPLING_TEXELFETCH_START        = TEXTURESAMPLING_TEXELFETCH,
+       TEXTURESAMPLING_TEXELFETCH_END          = TEXTURESAMPLING_TEXELFETCH_OFFSET     + 1
+};
+
+enum FunctionParameters
+{
+       FUNCTIONPARAMETERS_ONE = 1,
+       FUNCTIONPARAMETERS_TWO
+};
+
+enum Blending
+{
+       BLENDING_REQUIRED               = 0,
+       BLENDING_NOT_REQUIRED
+};
+
+enum Toggling
+{
+       TOGGLING_REQUIRED               = 0,
+       TOGGLING_NOT_REQUIRED
+};
+
+tcu::Vec4 getColorReferenceLinear (void)
+{
+       return tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f);
+}
+
+tcu::Vec4 getColorReferenceSRGB (void)
+{
+       return tcu::linearToSRGB(tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f));
+}
+
+tcu::Vec4 getColorGreenPass (void)
+{
+       return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
+}
+
+namespace TestDimensions
+{
+       const int WIDTH         = 128;
+       const int HEIGHT        = 128;
+} // global test texture dimensions
+
+namespace TestSamplingPositions
+{
+       const int X_POS = 0;
+       const int Y_POS = 0;
+} // global test sampling positions
+
+const char* getFunctionDefinitionSRGBToLinearCheck (void)
+{
+       static const char* functionDefinition =
+                       "mediump vec4 srgbToLinearCheck(in mediump vec4 texelSRGBA, in mediump vec4 texelLinear) \n"
+                       "{ \n"
+                       "       const int NUM_CHANNELS = 4;"
+                       "       mediump vec4 texelSRGBAConverted; \n"
+                       "       mediump vec4 epsilonErr = vec4(0.005); \n"
+                       "       mediump vec4 testResult; \n"
+                       "       for (int idx = 0; idx < NUM_CHANNELS; idx++) \n"
+                       "       { \n"
+                       "               texelSRGBAConverted[idx] = pow( (texelSRGBA[idx] + 0.055) / 1.055, 1.0 / 0.4116); \n"
+                       "       } \n"
+                       "       if ( all(lessThan(abs(texelSRGBAConverted - texelLinear), epsilonErr)) || all(equal(texelSRGBAConverted, texelLinear)) ) \n"
+                       "       { \n"
+                       "               return testResult = vec4(0.0, 1.0, 0.0, 1.0); \n"
+                       "       } \n"
+                       "       else \n"
+                       "       { \n"
+                       "               return testResult = vec4(1.0, 0.0, 0.0, 1.0); \n"
+                       "       } \n"
+                       "} \n";
+
+       return functionDefinition;
+}
+
+const char* getFunctionDefinitionEqualCheck (void)
+{
+       static const char* functionDefinition =
+                       "mediump vec4 colorsEqualCheck(in mediump vec4 colorA, in mediump vec4 colorB) \n"
+                       "{ \n"
+                       "       mediump vec4 epsilonErr = vec4(0.005); \n"
+                       "       mediump vec4 testResult; \n"
+                       "       if ( all(lessThan(abs(colorA - colorB), epsilonErr)) || all(equal(colorA, colorB)) ) \n"
+                       "       { \n"
+                       "               return testResult = vec4(0.0, 1.0, 0.0, 1.0); \n"
+                       "       } \n"
+                       "       else \n"
+                       "       { \n"
+                       "               return testResult = vec4(1.0, 0.0, 0.0, 1.0); \n"
+                       "       } \n"
+                       "} \n";
+
+       return functionDefinition;
+}
+
+namespace EpsilonError
+{
+       const float CPU = 0.005f;
+}
+
+struct TestGroupConfig
+{
+       TestGroupConfig                 (const char* groupName, const char* groupDescription, const tcu::TextureFormat groupInternalFormat)
+               : name                          (groupName)
+               , description           (groupDescription)
+               , internalFormat        (groupInternalFormat) {}
+
+       ~TestGroupConfig                (void) {};
+
+       const char*                                     name;
+       const char*                                     description;
+       const tcu::TextureFormat        internalFormat;
+};
+
+struct UniformData
+{
+       UniformData                     (glw::GLuint uniformLocation, const std::string& uniformName)
+               : location              (uniformLocation)
+               , name                  (uniformName)
+               , toggleDecode  (false) {}
+
+       ~UniformData            (void) {}
+
+       glw::GLuint     location;
+       std::string     name;
+       bool            toggleDecode;
+};
+
+struct UniformToToggle
+{
+       UniformToToggle         (const int uniformProgramIdx, const std::string& uniformName)
+               : programIdx    (uniformProgramIdx)
+               , name                  (uniformName) {}
+
+       ~UniformToToggle        (void) {}
+
+       int                     programIdx;
+       std::string     name;
+};
+
+struct ComparisonFunction
+{
+       ComparisonFunction              (const std::string& funcName, const FunctionParameters funcParameters, const std::string& funcImplementation)
+               : name                          (funcName)
+               , parameters            (funcParameters)
+               , implementation        (funcImplementation) {}
+
+       ~ComparisonFunction             (void) {}
+
+       std::string                     name;
+       FunctionParameters      parameters;
+       std::string                     implementation;
+};
+
+struct FragmentShaderParameters
+{
+       FragmentShaderParameters        (const ShaderOutputs    outputTotal,
+                                                                const ShaderUniforms   uniformTotal,
+                                                                ComparisonFunction*    comparisonFunction,
+                                                                Blending                               blendRequired,
+                                                                Toggling                               toggleRequired);
+
+       ~FragmentShaderParameters       (void);
+
+       ShaderOutputs                           outputTotal;
+       ShaderUniforms                          uniformTotal;
+       ShaderSamplingType                      samplingType;
+       std::string                                     functionName;
+       FunctionParameters                      functionParameters;
+       std::string                                     functionImplementation;
+       bool                                            hasFunction;
+       Blending                                        blendRequired;
+       Toggling                                        toggleRequired;
+       std::vector<std::string>        uniformsToToggle;
+};
+
+FragmentShaderParameters::FragmentShaderParameters     (const ShaderOutputs    paramsOutputTotal,
+                                                                                                        const ShaderUniforms   paramsUniformTotal,
+                                                                                                        ComparisonFunction*    paramsComparisonFunction,
+                                                                                                        Blending                               paramsBlendRequired,
+                                                                                                        Toggling                               paramsToggleRequired)
+       : outputTotal                                                                   (paramsOutputTotal)
+       , uniformTotal                                                                  (paramsUniformTotal)
+       , blendRequired                                                                 (paramsBlendRequired)
+       , toggleRequired                                                                (paramsToggleRequired)
+{
+       if (paramsComparisonFunction != DE_NULL)
+       {
+               functionName                    = paramsComparisonFunction->name;
+               functionParameters              = paramsComparisonFunction->parameters;
+               functionImplementation  = paramsComparisonFunction->implementation;
+
+               hasFunction = true;
+       }
+       else
+       {
+               hasFunction = false;
+       }
+}
+
+FragmentShaderParameters::~FragmentShaderParameters (void)
+{
+}
+
+class SRGBTestSampler
+{
+public:
+                               SRGBTestSampler         (Context&                                               context,
+                                                                        const tcu::Sampler::WrapMode   wrapS,
+                                                                        const tcu::Sampler::WrapMode   wrapT,
+                                                                        const tcu::Sampler::FilterMode minFilter,
+                                                                        const tcu::Sampler::FilterMode magFilter,
+                                                                        const SRGBDecode                               decoding);
+                               ~SRGBTestSampler        (void);
+
+       void            setDecode                       (const SRGBDecode decoding);
+       void            setTextureUnit          (const deUint32 textureUnit);
+       void            setIsActive                     (const bool isActive);
+
+       deUint32        getHandle                       (void) const;
+       bool            getIsActive                     (void) const;
+
+       void            bindToTexture           (void);
+       void            unbindFromTexture       (void);
+
+private:
+       const glw::Functions*           m_gl;
+       deUint32                                        m_samplerHandle;
+       tcu::Sampler::WrapMode          m_wrapS;
+       tcu::Sampler::WrapMode          m_wrapT;
+       tcu::Sampler::FilterMode        m_minFilter;
+       tcu::Sampler::FilterMode        m_magFilter;
+       SRGBDecode                                      m_decoding;
+       deUint32                                        m_textureUnit;
+       bool                                            m_isActive;
+};
+
+SRGBTestSampler::SRGBTestSampler       (Context&                                               context,
+                                                                        const tcu::Sampler::WrapMode   wrapS,
+                                                                        const tcu::Sampler::WrapMode   wrapT,
+                                                                        const tcu::Sampler::FilterMode minFilter,
+                                                                        const tcu::Sampler::FilterMode magFilter,
+                                                                        const SRGBDecode                               decoding)
+       : m_gl                                                  (&context.getRenderContext().getFunctions())
+       , m_wrapS                                               (wrapS)
+       , m_wrapT                                               (wrapT)
+       , m_minFilter                                   (minFilter)
+       , m_magFilter                                   (magFilter)
+       , m_isActive                                    (false)
+{
+       m_gl->genSamplers(1, &m_samplerHandle);
+
+       m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(m_wrapS));
+       m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(m_wrapT));
+       m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(m_minFilter));
+       m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(m_magFilter));
+
+       this->setDecode(decoding);
+}
+
+SRGBTestSampler::~SRGBTestSampler (void)
+{
+       m_gl->deleteSamplers(1, &m_samplerHandle);
+}
+
+void SRGBTestSampler::setDecode (const SRGBDecode decoding)
+{
+       if (decoding == SRGBDECODE_SKIP_DECODE)
+       {
+               m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+               GLU_EXPECT_NO_ERROR(m_gl->getError(), "samplerParameteri(m_samplerID, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)");
+       }
+       else if (decoding == SRGBDECODE_DECODE)
+       {
+               m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
+               GLU_EXPECT_NO_ERROR(m_gl->getError(), "samplerParameteri(m_samplerID, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)");
+       }
+       else
+       {
+               DE_FATAL("sRGB texture sampler must have either GL_SKIP_DECODE_EXT or GL_DECODE_EXT settings");
+       }
+
+       m_decoding = decoding;
+}
+
+void SRGBTestSampler::setTextureUnit (const deUint32 textureUnit)
+{
+       m_textureUnit = textureUnit;
+}
+
+void SRGBTestSampler::setIsActive (const bool isActive)
+{
+       m_isActive = isActive;
+}
+
+deUint32 SRGBTestSampler::getHandle (void) const
+{
+       return m_samplerHandle;
+}
+
+bool SRGBTestSampler::getIsActive (void) const
+{
+       return m_isActive;
+}
+
+void SRGBTestSampler::bindToTexture (void)
+{
+       m_gl->bindSampler(m_textureUnit, m_samplerHandle);
+}
+
+void SRGBTestSampler::unbindFromTexture (void)
+{
+       m_gl->bindSampler(m_textureUnit, 0);
+}
+
+class SRGBTestTexture
+{
+public:
+                               SRGBTestTexture         (Context&                                                                       context,
+                                                                        const glu::TextureTestUtil::TextureType        targetType,
+                                                                        const tcu::TextureFormat                                       internalFormat,
+                                                                        const int                                                                      width,
+                                                                        const int                                                                      height,
+                                                                        const tcu::Vec4                                                        color,
+                                                                        const tcu::Sampler::WrapMode                           wrapS,
+                                                                        const tcu::Sampler::WrapMode                           wrapT,
+                                                                        const tcu::Sampler::FilterMode                         minFilter,
+                                                                        const tcu::Sampler::FilterMode                         magFilter,
+                                                                        const SRGBDecode                                                       decoding);
+                               ~SRGBTestTexture        (void);
+
+       void            setParameters           (void);
+       void            setDecode                       (const SRGBDecode decoding);
+       void            setHasSampler           (const bool hasSampler);
+
+       deUint32        getHandle                       (void) const;
+       deUint32        getGLTargetType         (void) const;
+       SRGBDecode      getDecode                       (void) const;
+       bool            getHasSampler           (void) const;
+
+       void            upload                          (void);
+
+private:
+       void            setColor                        (void);
+
+       Context&                                                        m_context;
+       glu::Texture2D                                          m_source;
+       glu::TextureTestUtil::TextureType       m_targetType;
+       const tcu::TextureFormat                        m_internalFormat;
+       const int                                                       m_width;
+       const int                                                       m_height;
+       tcu::Vec4                                                       m_color;
+       tcu::Sampler::WrapMode                          m_wrapS;
+       tcu::Sampler::WrapMode                          m_wrapT;
+       tcu::Sampler::FilterMode                        m_minFilter;
+       tcu::Sampler::FilterMode                        m_magFilter;
+       SRGBDecode                                                      m_decoding;
+       bool                                                            m_hasSampler;
+};
+
+SRGBTestTexture::SRGBTestTexture       (Context&                                                                       context,
+                                                                        const glu::TextureTestUtil::TextureType        targetType,
+                                                                        const tcu::TextureFormat                                       internalFormat,
+                                                                        const int                                                                      width,
+                                                                        const int                                                                      height,
+                                                                        const tcu::Vec4                                                        color,
+                                                                        const tcu::Sampler::WrapMode                           wrapS,
+                                                                        const tcu::Sampler::WrapMode                           wrapT,
+                                                                        const tcu::Sampler::FilterMode                         minFilter,
+                                                                        const tcu::Sampler::FilterMode                         magFilter,
+                                                                        SRGBDecode                                                                     decoding)
+       : m_context                                             (context)
+       , m_source                                              (context.getRenderContext(), glu::getInternalFormat(internalFormat), width, height)
+       , m_targetType                                  (targetType)
+       , m_internalFormat                              (internalFormat)
+       , m_width                                               (width)
+       , m_height                                              (height)
+       , m_color                                               (color)
+       , m_wrapS                                               (wrapS)
+       , m_wrapT                                               (wrapT)
+       , m_minFilter                                   (minFilter)
+       , m_magFilter                                   (magFilter)
+       , m_decoding                                    (decoding)
+       , m_hasSampler                                  (false)
+{
+       this->setColor();
+}
+
+SRGBTestTexture::~SRGBTestTexture (void)
+{
+}
+
+void SRGBTestTexture::setParameters (void)
+{
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       gl.bindTexture(this->getGLTargetType(), this->getHandle());
+
+       gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_WRAP_S, glu::getGLWrapMode(m_wrapS));
+       gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_WRAP_T, glu::getGLWrapMode(m_wrapT));
+       gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(m_minFilter));
+       gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(m_magFilter));
+
+       gl.bindTexture(this->getGLTargetType(), 0);
+
+       setDecode(m_decoding);
+}
+
+void SRGBTestTexture::setDecode (const SRGBDecode decoding)
+{
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       gl.bindTexture(this->getGLTargetType(), this->getHandle());
+
+       switch (decoding)
+       {
+               case SRGBDECODE_SKIP_DECODE:
+               {
+                       gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)");
+                       break;
+               }
+               case SRGBDECODE_DECODE:
+               {
+                       gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
+                       GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)");
+                       break;
+               }
+               case SRGBDECODE_DECODE_DEFAULT:
+               {
+                       // do not use srgb decode options. Set to default
+                       break;
+               }
+               default:
+                       DE_FATAL("Error: Decoding option not recognised");
+       }
+
+       gl.bindTexture(this->getGLTargetType(), 0);
+
+       m_decoding = decoding;
+}
+
+void SRGBTestTexture::setHasSampler (const bool hasSampler)
+{
+       m_hasSampler = hasSampler;
+}
+
+deUint32 SRGBTestTexture::getHandle (void) const
+{
+       return m_source.getGLTexture();
+}
+
+deUint32 SRGBTestTexture::getGLTargetType (void) const
+{
+       switch (m_targetType)
+       {
+               case TEXTURETYPE_2D:
+               {
+                       return GL_TEXTURE_2D;
+               }
+               default:
+               {
+                       DE_FATAL("Error: Target type not recognised");
+                       return -1;
+               }
+       }
+}
+
+SRGBDecode SRGBTestTexture::getDecode (void) const
+{
+       return m_decoding;
+}
+
+bool SRGBTestTexture::getHasSampler (void) const
+{
+       return m_hasSampler;
+}
+
+void SRGBTestTexture::upload (void)
+{
+       m_source.upload();
+}
+
+void SRGBTestTexture::setColor (void)
+{
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       gl.bindTexture(this->getGLTargetType(), this->getHandle());
+
+       m_source.getRefTexture().allocLevel(0);
+
+       for (int py = 0; py < m_height; py++)
+       {
+               for (int px = 0; px < m_width; px++)
+               {
+                       m_source.getRefTexture().getLevel(0).setPixel(m_color, px, py);
+               }
+       }
+
+       gl.bindTexture(this->getGLTargetType(), 0);
+}
+
+class SRGBTestProgram
+{
+public:
+                                                                       SRGBTestProgram                 (Context& context, const FragmentShaderParameters& shaderParameters);
+                                                                       ~SRGBTestProgram                (void);
+
+       void                                                    setBlendRequired                (bool blendRequired);
+       void                                                    setToggleRequired               (bool toggleRequired);
+       void                                                    setUniformToggle                (int location, bool toggleDecodeValue);
+
+       int                                                             getUniformTotal                 (void) const;
+       const std::vector<UniformData>& getUniformDataList              (void) const;
+       const UniformData&                              getUniformAtLocation    (int location) const;
+       int                                                             getUniformLocation              (const std::string& name);
+       deUint32                                                getHandle                               (void) const;
+       bool                                                    getBlendRequired                (void) const;
+       bool                                                    getToggleRequired               (void) const;
+       const std::string&                              getFragmentShader               (void) const;
+
+private:
+       std::string                                             genFunctionCall                 (ShaderSamplingType samplingType, const int uniformIdx);
+       void                                                    genFragmentShader               (void);
+
+       Context&                                                m_context;
+       de::MovePtr<glu::ShaderProgram> m_program;
+       FragmentShaderParameters                m_shaderFragmentParameters;
+       std::string                                             m_shaderVertex;
+       std::string                                             m_shaderFragment;
+       std::vector<UniformData>                m_uniformDataList;
+       bool                                                    m_blendRequired;
+       bool                                                    m_toggleRequired;
+};
+
+SRGBTestProgram::SRGBTestProgram       (Context& context, const FragmentShaderParameters& shaderParameters)
+       : m_context                                             (context)
+       , m_shaderFragmentParameters    (shaderParameters)
+       , m_blendRequired                               (false)
+       , m_toggleRequired                              (false)
+{
+       const glw::Functions&   gl                                      = m_context.getRenderContext().getFunctions();
+       tcu::TestLog&                   log                                     = m_context.getTestContext().getLog();
+       glu::ShaderProgramInfo  buildInfo;
+       const int                               totalShaderStages       = 2;
+
+       // default vertex shader used in all tests
+       m_shaderVertex =        "#version 310 es \n"
+                                               "layout (location = 0) in mediump vec3 aPosition; \n"
+                                               "layout (location = 1) in mediump vec2 aTexCoord; \n"
+                                               "out mediump vec2 vs_aTexCoord; \n"
+                                               "void main () \n"
+                                               "{ \n"
+                                               "       gl_Position = vec4(aPosition, 1.0); \n"
+                                               "       vs_aTexCoord = aTexCoord; \n"
+                                               "} \n";
+
+       this->genFragmentShader();
+
+       m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(m_shaderVertex, m_shaderFragment)));
+
+       if (!m_program->isOk())
+       {
+               TCU_FAIL("Failed to compile shaders and link program");
+       }
+
+       glw::GLint activeUniforms, maxLen;
+       glw::GLint size, location;
+       glw::GLenum type;
+
+       gl.getProgramiv(this->getHandle(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
+       gl.getProgramiv(this->getHandle(), GL_ACTIVE_UNIFORMS, &activeUniforms);
+
+       std::vector<glw::GLchar> uniformName(static_cast<int>(maxLen));
+       for (int idx = 0; idx < activeUniforms; idx++)
+       {
+               gl.getActiveUniform(this->getHandle(), idx, maxLen, NULL, &size, &type, &uniformName[0]);
+               location = gl.getUniformLocation(this->getHandle(), &uniformName[0]);
+
+               UniformData uniformData(location, std::string(&uniformName[0], strlen(&uniformName[0])));
+               m_uniformDataList.push_back(uniformData);
+       }
+
+       // log shader program info. Only vertex and fragment shaders included
+       buildInfo.program = m_program->getProgramInfo();
+       for (int shaderIdx = 0; shaderIdx < totalShaderStages; shaderIdx++)
+       {
+               glu::ShaderInfo shaderInfo = m_program->getShaderInfo(static_cast<glu::ShaderType>(static_cast<int>(glu::SHADERTYPE_VERTEX) + static_cast<int>(shaderIdx)), 0);
+               buildInfo.shaders.push_back(shaderInfo);
+       }
+
+       log << buildInfo;
+}
+
+SRGBTestProgram::~SRGBTestProgram (void)
+{
+       m_program       = de::MovePtr<glu::ShaderProgram>(DE_NULL);
+}
+
+void SRGBTestProgram::setBlendRequired (bool blendRequired)
+{
+       m_blendRequired = blendRequired;
+}
+
+void SRGBTestProgram::setToggleRequired (bool toggleRequired)
+{
+       m_toggleRequired = toggleRequired;
+}
+
+void SRGBTestProgram::setUniformToggle (int location, bool toggleDecodeValue)
+{
+       if ( (m_uniformDataList.empty() == false) && (location >= 0) && (location <= (int)m_uniformDataList.size()) )
+       {
+               m_uniformDataList[location].toggleDecode = toggleDecodeValue;
+       }
+       else
+       {
+               TCU_THROW(TestError, "Error: Uniform location not found. glGetActiveUniforms returned uniforms incorrectly ");
+       }
+}
+
+int SRGBTestProgram::getUniformTotal (void) const
+{
+       return (int)m_uniformDataList.size();
+}
+
+const std::vector<UniformData>& SRGBTestProgram::getUniformDataList (void) const
+{
+       return m_uniformDataList;
+}
+
+const UniformData& SRGBTestProgram::getUniformAtLocation (int location) const
+{
+       return m_uniformDataList[location];
+}
+
+int SRGBTestProgram::getUniformLocation (const std::string& name)
+{
+       for (std::size_t idx = 0; idx < m_uniformDataList.size(); idx++)
+       {
+               if (m_uniformDataList[idx].name == name)
+               {
+                       return m_uniformDataList[idx].location;
+               }
+       }
+
+       TCU_THROW(TestError, "Error: If name correctly requested then glGetActiveUniforms() returned active uniform data incorrectly");
+       return -1;
+}
+
+glw::GLuint SRGBTestProgram::getHandle (void) const
+{
+       return m_program->getProgram();
+}
+
+bool SRGBTestProgram::getBlendRequired (void) const
+{
+       return m_blendRequired;
+}
+
+bool SRGBTestProgram::getToggleRequired (void) const
+{
+       return m_toggleRequired;
+}
+
+const std::string& SRGBTestProgram::getFragmentShader (void) const
+{
+       return m_shaderFragment;
+}
+
+std::string SRGBTestProgram::genFunctionCall (ShaderSamplingType samplingType, const int uniformIdx)
+{
+       std::ostringstream functionCall;
+
+       functionCall << "       mediump vec4 texelColor" << uniformIdx << " = ";
+
+       switch (samplingType)
+               {
+                       case TEXTURESAMPLING_TEXTURE:
+                       {
+                               functionCall << "texture(uTexture" << uniformIdx << ", vs_aTexCoord); \n";
+                               break;
+                       }
+                       case TEXTURESAMPLING_TEXTURE_LOD:
+                       {
+                               functionCall << "textureLod(uTexture" << uniformIdx << ", vs_aTexCoord, 0.0); \n";
+                               break;
+                       }
+                       case TEXTURESAMPLING_TEXTURE_GRAD:
+                       {
+                               functionCall << "textureGrad(uTexture" << uniformIdx << ", vs_aTexCoord, vec2(0.0, 0.0), vec2(0.0, 0.0)); \n";
+                               break;
+                       }
+                       case TEXTURESAMPLING_TEXTURE_OFFSET:
+                       {
+                               functionCall << "textureOffset(uTexture" << uniformIdx << ", vs_aTexCoord, ivec2(0.0, 0.0)); \n";
+                               break;
+                       }
+                       case TEXTURESAMPLING_TEXTURE_PROJ:
+                       {
+                               functionCall << "textureProj(uTexture" << uniformIdx << ", vec3(vs_aTexCoord, 1.0)); \n";
+                               break;
+                       }
+                       case TEXTURESAMPLING_TEXELFETCH:
+                       {
+                               functionCall << "texelFetch(uTexture" << uniformIdx << ", ivec2(vs_aTexCoord), 0); \n";
+                               break;
+                       }
+                       case TEXTURESAMPLING_TEXELFETCH_OFFSET:
+                       {
+                               functionCall << "texelFetchOffset(uTexture" << uniformIdx << ", ivec2(vs_aTexCoord), 0, ivec2(0.0, 0.0)); \n";
+                               break;
+                       }
+                       default:
+                       {
+                               DE_FATAL("Error: Sampling type not recognised");
+                       }
+               }
+
+       return functionCall.str();
+}
+
+void SRGBTestProgram::genFragmentShader (void)
+{
+       std::ostringstream source;
+       std::ostringstream sampleTexture;
+       std::ostringstream functionParameters;
+       std::ostringstream shaderOutputs;
+
+       // if comparison function is present resulting shader requires precisely one output
+       DE_ASSERT( !(m_shaderFragmentParameters.hasFunction && (static_cast<int>(m_shaderFragmentParameters.outputTotal) != static_cast<int>(SHADEROUTPUTS_ONE))) );
+
+       // function parameters must equal the number of uniforms i.e. textures passed into the function
+       DE_ASSERT( !(m_shaderFragmentParameters.hasFunction && (static_cast<int>(m_shaderFragmentParameters.uniformTotal) != static_cast<int>(m_shaderFragmentParameters.functionParameters))) );
+
+       // fragment shader cannot contain more outputs than the number of texture uniforms
+       DE_ASSERT( !(static_cast<int>(m_shaderFragmentParameters.outputTotal) > static_cast<int>(m_shaderFragmentParameters.uniformTotal)) ) ;
+
+       source << "#version 310 es \n"
+               << "in mediump vec2 vs_aTexCoord; \n";
+
+       for (int output = 0; output < m_shaderFragmentParameters.outputTotal; output++)
+       {
+               source << "layout (location = " << output << ") out mediump vec4 fs_aColor" << output << "; \n";
+       }
+
+       for (int uniform = 0; uniform < m_shaderFragmentParameters.uniformTotal; uniform++)
+       {
+               source << "uniform sampler2D uTexture" << uniform << "; \n";
+       }
+
+       if (m_shaderFragmentParameters.hasFunction == true)
+       {
+               source << m_shaderFragmentParameters.functionImplementation;
+       }
+
+       source << "void main () \n"
+               << "{ \n";
+
+       for (int uniformIdx = 0; uniformIdx < m_shaderFragmentParameters.uniformTotal; uniformIdx++)
+       {
+               source << this->genFunctionCall(m_shaderFragmentParameters.samplingType, uniformIdx);
+       }
+
+       if (m_shaderFragmentParameters.hasFunction == true)
+       {
+               switch ( static_cast<FunctionParameters>(m_shaderFragmentParameters.functionParameters) )
+               {
+                       case FUNCTIONPARAMETERS_ONE:
+                       {
+                               functionParameters << "(texelColor0)";
+                               break;
+                       }
+                       case FUNCTIONPARAMETERS_TWO:
+                       {
+                               functionParameters << "(texelColor0, texelColor1)";
+                               break;
+                       }
+                       default:
+                       {
+                               DE_FATAL("Error: Number of comparison function parameters invalid");
+                       }
+               }
+
+               shaderOutputs << "      fs_aColor0 = " << m_shaderFragmentParameters.functionName << functionParameters.str() << "; \n";
+       }
+       else
+       {
+               for (int output = 0; output < m_shaderFragmentParameters.outputTotal; output++)
+               {
+                       shaderOutputs << "      fs_aColor" << output << " = texelColor" << output << "; \n";
+               }
+       }
+
+       source << shaderOutputs.str();
+       source << "} \n";
+
+       m_shaderFragment = source.str();
+}
+
+class SRGBTestCase : public TestCase
+{
+public:
+                                                       SRGBTestCase                                    (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat);
+                                                       ~SRGBTestCase                                   (void);
+
+       void                                    init                                                    (void);
+       void                                    deinit                                                  (void);
+       virtual IterateResult   iterate                                                 (void);
+
+       void                                    setSamplingGroup                                (const ShaderSamplingGroup samplingGroup);
+       void                                    setSamplingLocations                    (const int px, const int py);
+       void                                    setShaderProgramBlendRequired   (const int programIdx, const bool blend);
+       void                                    setShaderProgramToggleRequired  (const int programIdx, const bool toggle);
+       void                                    setUniformToggle                                (const int programIdx, const std::string& uniformName, bool toggleDecode);
+
+       deUint32                                getShaderProgramHandle                  (const int programIdx) const;
+       deUint32                                getTextureHandle                                (const int textureIdx) const;
+
+       void                                    addTexture                                              (const glu::TextureTestUtil::TextureType        targetType,
+                                                                                                                        const int                                                                      width,
+                                                                                                                        const int                                                                      height,
+                                                                                                                        const tcu::Vec4                                                        color,
+                                                                                                                        const tcu::Sampler::WrapMode                           wrapS,
+                                                                                                                        const tcu::Sampler::WrapMode                           wrapT,
+                                                                                                                        const tcu::Sampler::FilterMode                         minFilter,
+                                                                                                                        const tcu::Sampler::FilterMode                         magFilter,
+                                                                                                                        const SRGBDecode                                                       decoding);
+       void                                    addSampler                                              (const tcu::Sampler::WrapMode   wrapS,
+                                                                                                                        const tcu::Sampler::WrapMode   wrapT,
+                                                                                                                        const tcu::Sampler::FilterMode minFilter,
+                                                                                                                        const tcu::Sampler::FilterMode magFilter,
+                                                                                                                        const SRGBDecode                               decoding);
+       void                                    addShaderProgram                                (const FragmentShaderParameters& shaderParameters);
+
+       void                                    genShaderPrograms                               (ShaderSamplingType samplingType);
+       void                                    deleteShaderPrograms                    (void);
+
+       void                                    readResultTextures                              (void);
+       void                                    storeResultPixels                               (std::vector<tcu::Vec4>& resultPixelData);
+
+       void                                    toggleDecode                                    (const std::vector<UniformData>& uniformDataList);
+       void                                    bindSamplerToTexture                    (const int samplerIdx, const int textureIdx, const deUint32 textureUnit);
+       void                                    activateSampler                                 (const int samplerIdx, const bool active);
+       void                                    logColor                                                (const std::string& colorLogMessage, int colorIdx, tcu::Vec4 color) const;
+       tcu::Vec4                               formatReferenceColor                    (tcu::Vec4 referenceColor);
+
+       // render function has a default implentation. Can be overriden for special cases
+       virtual void                    render                                                  (void);
+
+       // following functions must be overidden to perform individual test cases
+       virtual void                    setupTest                                               (void) = 0;
+       virtual bool                    verifyResult                                    (void) = 0;
+
+protected:
+       de::MovePtr<glu::Framebuffer>                   m_framebuffer;
+       std::vector<SRGBTestTexture*>                   m_textureSourceList;
+       std::vector<SRGBTestSampler*>                   m_samplerList;
+       std::vector<glw::GLuint>                                m_renderBufferList;
+       const tcu::Vec4                                                 m_epsilonError;
+       std::vector<tcu::TextureLevel>                  m_textureResultList;
+       int                                                                             m_resultOutputTotal;
+       tcu::TextureFormat                                              m_resultTextureFormat;
+       glw::GLuint                                                             m_vaoID;
+       glw::GLuint                                                             m_vertexDataID;
+       std::vector<FragmentShaderParameters>   m_shaderParametersList;
+       std::vector<SRGBTestProgram*>                   m_shaderProgramList;
+       ShaderSamplingGroup                                             m_samplingGroup;
+       int                                                                             m_px;
+       int                                                                             m_py;
+       const tcu::TextureFormat                                m_internalFormat;
+
+private:
+       void                    uploadTextures  (void);
+       void                    initFrameBuffer (void);
+       void                    initVertexData  (void);
+
+                                       SRGBTestCase    (const SRGBTestCase&);
+       SRGBTestCase&   operator=               (const SRGBTestCase&);
+};
+
+SRGBTestCase::SRGBTestCase     (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+       : TestCase                              (context, name, description)
+       , m_epsilonError                (EpsilonError::CPU)
+       , m_resultTextureFormat (tcu::TextureFormat(tcu::TextureFormat::sRGBA, tcu::TextureFormat::UNORM_INT8))
+       , m_vaoID                               (0)
+       , m_vertexDataID                (0)
+       , m_samplingGroup               (SHADERSAMPLINGGROUP_TEXTURE)
+       , m_internalFormat              (internalFormat)
+{
+}
+
+SRGBTestCase::~SRGBTestCase (void)
+{
+       deinit();
+}
+
+void SRGBTestCase::init (void)
+{
+       // extension requirements for test
+       if ( (glu::getInternalFormat(m_internalFormat) == GL_SRGB8_ALPHA8) && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_decode") )
+       {
+               throw tcu::NotSupportedError("Test requires GL_EXT_texture_sRGB_decode extension");
+       }
+
+       if ( (glu::getInternalFormat(m_internalFormat) == GL_SR8_EXT) && !(m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_R8")) )
+       {
+               throw tcu::NotSupportedError("Test requires GL_EXT_texture_sRGB_R8 extension");
+       }
+
+       m_framebuffer = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
+}
+
+void SRGBTestCase::deinit (void)
+{
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       m_framebuffer   = de::MovePtr<glu::Framebuffer>(DE_NULL);
+
+       for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
+       {
+               gl.deleteRenderbuffers(1, &m_renderBufferList[renderBufferIdx]);
+       }
+       m_renderBufferList.clear();
+
+       for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++)
+       {
+               delete m_textureSourceList[textureSourceIdx];
+       }
+       m_textureSourceList.clear();
+
+       for (std::size_t samplerIdx = 0; samplerIdx < m_samplerList.size(); samplerIdx++)
+       {
+               delete m_samplerList[samplerIdx];
+       }
+       m_samplerList.clear();
+
+       if (m_vaoID != 0)
+       {
+               gl.deleteVertexArrays(1, &m_vaoID);
+               m_vaoID = 0;
+       }
+
+       if (m_vertexDataID != 0)
+       {
+               gl.deleteBuffers(1, &m_vertexDataID);
+               m_vertexDataID = 0;
+       }
+}
+
+SRGBTestCase::IterateResult SRGBTestCase::iterate (void)
+{
+       bool    result;
+       int             startIdx        = -1;
+       int             endIdx          = -1;
+
+       this->setupTest();
+
+       if (m_samplingGroup == SHADERSAMPLINGGROUP_TEXTURE)
+       {
+               startIdx        = static_cast<int>(TEXTURESAMPLING_TEXTURE_START);
+               endIdx          = static_cast<int>(TEXTURESAMPLING_TEXTURE_END);
+       }
+       else if (m_samplingGroup == SHADERSAMPLINGGROUP_TEXEL_FETCH)
+       {
+               startIdx        = static_cast<int>(TEXTURESAMPLING_TEXELFETCH_START);
+               endIdx          = static_cast<int>(TEXTURESAMPLING_TEXELFETCH_END);
+       }
+       else
+       {
+               DE_FATAL("Error: Sampling group not defined");
+       }
+
+       this->initVertexData();
+       this->initFrameBuffer();
+
+       // loop through all sampling types in the required sampling group, performing individual tests for each
+       for (int samplingTypeIdx = startIdx; samplingTypeIdx < endIdx; samplingTypeIdx++)
+       {
+               this->genShaderPrograms(static_cast<ShaderSamplingType>(samplingTypeIdx));
+               this->uploadTextures();
+               this->render();
+
+               result = this->verifyResult();
+
+               this->deleteShaderPrograms();
+
+               if (result == true)
+               {
+                       m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
+               }
+               else
+               {
+                       m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
+                       return STOP;
+               }
+       }
+
+       return STOP;
+}
+
+void SRGBTestCase::setSamplingGroup (const ShaderSamplingGroup samplingGroup)
+{
+       m_samplingGroup = samplingGroup;
+}
+
+void SRGBTestCase::setSamplingLocations (const int px, const int py)
+{
+       m_px = px;
+       m_py = py;
+}
+
+void SRGBTestCase::setShaderProgramBlendRequired (const int programIdx, const bool blend)
+{
+       m_shaderProgramList[programIdx]->setBlendRequired(blend);
+}
+
+void SRGBTestCase::setShaderProgramToggleRequired (const int programIdx, const bool toggle)
+{
+       m_shaderProgramList[programIdx]->setToggleRequired(toggle);
+}
+
+void SRGBTestCase::setUniformToggle (const int programIdx, const std::string& uniformName, bool toggleDecodeValue)
+{
+       int uniformLocation = m_shaderProgramList[programIdx]->getUniformLocation(uniformName);
+       m_shaderProgramList[programIdx]->setUniformToggle(uniformLocation, toggleDecodeValue);
+}
+
+deUint32 SRGBTestCase::getShaderProgramHandle (const int programIdx) const
+{
+       return m_shaderProgramList[programIdx]->getHandle();
+}
+
+deUint32 SRGBTestCase::getTextureHandle (const int textureIdx) const
+{
+       return m_textureSourceList[textureIdx]->getHandle();
+}
+
+void SRGBTestCase::addTexture (        const glu::TextureTestUtil::TextureType targetType,
+                                                               const int                                                               width,
+                                                               const int                                                               height,
+                                                               const tcu::Vec4                                                 color,
+                                                               const tcu::Sampler::WrapMode                    wrapS,
+                                                               const tcu::Sampler::WrapMode                    wrapT,
+                                                               const tcu::Sampler::FilterMode                  minFilter,
+                                                               const tcu::Sampler::FilterMode                  magFilter,
+                                                               const SRGBDecode                                                decoding)
+{
+       SRGBTestTexture* texture = new SRGBTestTexture(m_context, targetType, m_internalFormat, width, height, color, wrapS, wrapT, minFilter, magFilter, decoding);
+       m_textureSourceList.push_back(texture);
+}
+
+void SRGBTestCase::addSampler (        const tcu::Sampler::WrapMode    wrapS,
+                                                               const tcu::Sampler::WrapMode    wrapT,
+                                                               const tcu::Sampler::FilterMode  minFilter,
+                                                               const tcu::Sampler::FilterMode  magFilter,
+                                                               const SRGBDecode                                decoding)
+{
+       SRGBTestSampler *sampler = new SRGBTestSampler(m_context, wrapS, wrapT, minFilter, magFilter, decoding);
+       m_samplerList.push_back(sampler);
+}
+
+void SRGBTestCase::addShaderProgram (const FragmentShaderParameters& shaderParameters)
+{
+       m_shaderParametersList.push_back(shaderParameters);
+       m_resultOutputTotal = shaderParameters.outputTotal;
+}
+
+void SRGBTestCase::genShaderPrograms (ShaderSamplingType samplingType)
+{
+       for (int shaderParamsIdx = 0; shaderParamsIdx < (int)m_shaderParametersList.size(); shaderParamsIdx++)
+       {
+               m_shaderParametersList[shaderParamsIdx].samplingType = samplingType;
+               SRGBTestProgram* shaderProgram = new SRGBTestProgram(m_context, m_shaderParametersList[shaderParamsIdx]);
+
+               if (m_shaderParametersList[shaderParamsIdx].blendRequired == BLENDING_REQUIRED)
+               {
+                       shaderProgram->setBlendRequired(true);
+               }
+
+               if (m_shaderParametersList[shaderParamsIdx].toggleRequired == TOGGLING_REQUIRED)
+               {
+                       shaderProgram->setToggleRequired(true);
+                       std::vector<std::string> uniformsToToggle = m_shaderParametersList[shaderParamsIdx].uniformsToToggle;
+
+                       for (int uniformNameIdx = 0; uniformNameIdx < (int)uniformsToToggle.size(); uniformNameIdx++)
+                       {
+                               shaderProgram->setUniformToggle(shaderProgram->getUniformLocation(uniformsToToggle[uniformNameIdx]), true);
+                       }
+               }
+
+               m_shaderProgramList.push_back(shaderProgram);
+       }
+}
+
+void SRGBTestCase::deleteShaderPrograms (void)
+{
+       for (std::size_t idx = 0; idx < m_shaderProgramList.size(); idx++)
+       {
+               delete m_shaderProgramList[idx];
+       }
+       m_shaderProgramList.clear();
+}
+
+void SRGBTestCase::readResultTextures (void)
+{
+       const glw::Functions&   gl              = m_context.getRenderContext().getFunctions();
+       int                                             width   = m_context.getRenderContext().getRenderTarget().getWidth();
+       int                                             height  = m_context.getRenderContext().getRenderTarget().getHeight();
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
+
+       m_textureResultList.resize(m_renderBufferList.size());
+
+       for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
+       {
+               gl.readBuffer(GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx);
+               m_textureResultList[renderBufferIdx].setStorage(m_resultTextureFormat, width, height);
+               glu::readPixels(m_context.getRenderContext(), 0, 0, m_textureResultList[renderBufferIdx].getAccess());
+               GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
+       }
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void SRGBTestCase::storeResultPixels (std::vector<tcu::Vec4>& resultPixelData)
+{
+       tcu::TestLog&           log                     = m_context.getTestContext().getLog();
+       std::ostringstream      message;
+       int                                     width           = m_context.getRenderContext().getRenderTarget().getWidth();
+       int                                     height          = m_context.getRenderContext().getRenderTarget().getHeight();
+
+       // ensure result sampling coordinates are within range of the result color attachment
+       DE_ASSERT((m_px >= 0) && (m_px < width));
+       DE_ASSERT((m_py >= 0) && (m_py < height));
+       DE_UNREF(width && height);
+
+       for (int idx = 0; idx < (int)m_textureResultList.size(); idx++)
+       {
+               resultPixelData.push_back(m_textureResultList[idx].getAccess().getPixel(m_px, m_py));
+               this->logColor(std::string("Result color: "), idx, resultPixelData[idx]);
+       }
+
+       // log error rate (threshold)
+       message << m_epsilonError;
+       log << tcu::TestLog::Message << std::string("Epsilon error: ") << message.str() << tcu::TestLog::EndMessage;
+}
+
+void SRGBTestCase::toggleDecode (const std::vector<UniformData>& uniformDataList)
+{
+       DE_ASSERT( uniformDataList.size() <= m_textureSourceList.size() );
+
+       for (int uniformIdx = 0; uniformIdx < (int)uniformDataList.size(); uniformIdx++)
+       {
+               if (uniformDataList[uniformIdx].toggleDecode == true)
+               {
+                       if (m_textureSourceList[uniformIdx]->getDecode() == SRGBDECODE_DECODE_DEFAULT)
+                       {
+                               // cannot toggle default
+                               continue;
+                       }
+
+                       // toggle sRGB decode values (ignoring value if set to default)
+                       m_textureSourceList[uniformIdx]->setDecode((SRGBDecode)((m_textureSourceList[uniformIdx]->getDecode() + 1) % SRGBDECODE_DECODE_DEFAULT));
+               }
+       }
+}
+
+void SRGBTestCase::bindSamplerToTexture (const int samplerIdx, const int textureIdx, const deUint32 textureUnit)
+{
+       deUint32 enumConversion = textureUnit - GL_TEXTURE0;
+       m_textureSourceList[textureIdx]->setHasSampler(true);
+       m_samplerList[samplerIdx]->setTextureUnit(enumConversion);
+}
+
+void SRGBTestCase::activateSampler (const int samplerIdx, const bool active)
+{
+       m_samplerList[samplerIdx]->setIsActive(active);
+}
+
+void SRGBTestCase::logColor (const std::string& colorLogMessage, int colorIdx, tcu::Vec4 color) const
+{
+       tcu::TestLog&                   log             = m_context.getTestContext().getLog();
+       std::ostringstream              message;
+
+       message << colorLogMessage << colorIdx << " = (" << color.x() << ", " << color.y() << ", " << color.z() << ", " << color.w() << ")";
+       log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
+}
+
+tcu::Vec4 SRGBTestCase::formatReferenceColor (tcu::Vec4 referenceColor)
+{
+       switch (glu::getInternalFormat(m_internalFormat))
+       {
+               case GL_SRGB8_ALPHA8:
+               {
+                       return referenceColor;
+               }
+               case GL_SR8_EXT:
+               {
+                       // zero unwanted color channels
+                       referenceColor.y() = 0;
+                       referenceColor.z() = 0;
+                       return referenceColor;
+               }
+               default:
+               {
+                       DE_FATAL("Error: Internal format not recognised");
+                       return referenceColor;
+               }
+       }
+}
+
+void SRGBTestCase::render (void)
+{
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       // default rendering only uses one program
+       gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
+       gl.bindVertexArray(m_vaoID);
+
+       gl.useProgram(m_shaderProgramList[0]->getHandle());
+
+       for (int textureSourceIdx = 0; textureSourceIdx < (int)m_textureSourceList.size(); textureSourceIdx++)
+       {
+               gl.activeTexture(GL_TEXTURE0 + (glw::GLenum)textureSourceIdx);
+               gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), m_textureSourceList[textureSourceIdx]->getHandle());
+               glw::GLuint samplerUniformLocationID = gl.getUniformLocation(m_shaderProgramList[0]->getHandle(), m_shaderProgramList[0]->getUniformAtLocation(textureSourceIdx).name.c_str());
+               TCU_CHECK(samplerUniformLocationID != (glw::GLuint)-1);
+               gl.uniform1i(samplerUniformLocationID, (glw::GLenum)textureSourceIdx);
+       }
+
+       for (int samplerIdx = 0; samplerIdx < (int)m_samplerList.size(); samplerIdx++)
+       {
+               if (m_samplerList[samplerIdx]->getIsActive() == true)
+               {
+                       m_samplerList[samplerIdx]->bindToTexture();
+               }
+       }
+
+       gl.drawArrays(GL_TRIANGLES, 0, 6);
+
+       for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++)
+       {
+               gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), 0);
+       }
+       gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+       gl.bindVertexArray(0);
+       gl.bindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void SRGBTestCase::uploadTextures (void)
+{
+       for (std::size_t idx = 0; idx < m_textureSourceList.size(); idx++)
+       {
+               m_textureSourceList[idx]->upload();
+               m_textureSourceList[idx]->setParameters();
+       }
+}
+
+void SRGBTestCase::initFrameBuffer (void)
+{
+       const glw::Functions&   gl              = m_context.getRenderContext().getFunctions();
+       int                                             width   = m_context.getRenderContext().getRenderTarget().getWidth();
+       int                                             height  = m_context.getRenderContext().getRenderTarget().getHeight();
+
+       if (m_resultOutputTotal == 0)
+       {
+               throw std::invalid_argument("SRGBTestExecutor must have at least 1 rendered result");
+       }
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
+
+       DE_ASSERT(m_renderBufferList.empty());
+       for (int outputIdx = 0; outputIdx < m_resultOutputTotal; outputIdx++)
+       {
+               glw::GLuint renderBuffer = -1;
+               m_renderBufferList.push_back(renderBuffer);
+       }
+
+       for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
+       {
+               gl.genRenderbuffers(1, &m_renderBufferList[renderBufferIdx]);
+               gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderBufferList[renderBufferIdx]);
+               gl.renderbufferStorage(GL_RENDERBUFFER, glu::getInternalFormat(m_resultTextureFormat), width, height);
+               gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx, GL_RENDERBUFFER, m_renderBufferList[renderBufferIdx]);
+               GLU_EXPECT_NO_ERROR(gl.getError(), "Create and setup renderbuffer object");
+       }
+       TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+
+       std::vector<glw::GLenum> renderBufferTargets(m_renderBufferList.size());
+       for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
+       {
+               renderBufferTargets[renderBufferIdx] = GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx;
+       }
+       gl.drawBuffers((glw::GLsizei)renderBufferTargets.size(), &renderBufferTargets[0]);
+       GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer()");
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+}
+
+void SRGBTestCase::initVertexData (void)
+{
+       const glw::Functions&   gl                              = m_context.getRenderContext().getFunctions();
+
+       static const glw::GLfloat squareVertexData[] =
+       {
+               // position                             // texcoord
+               -1.0f, -1.0f, 0.0f,             0.0f, 0.0f, // bottom left corner
+                1.0f, -1.0f, 0.0f,             1.0f, 0.0f, // bottom right corner
+                1.0f,  1.0f, 0.0f,             1.0f, 1.0f, // Top right corner
+
+               -1.0f,  1.0f, 0.0f,             0.0f, 1.0f, // top left corner
+                1.0f,  1.0f, 0.0f,             1.0f, 1.0f, // Top right corner
+               -1.0f, -1.0f, 0.0f,             0.0f, 0.0f  // bottom left corner
+       };
+
+       DE_ASSERT(m_vaoID == 0);
+       gl.genVertexArrays(1, &m_vaoID);
+       gl.bindVertexArray(m_vaoID);
+
+       gl.genBuffers(1, &m_vertexDataID);
+       gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexDataID);
+       gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizei)sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
+
+       gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)0);
+       gl.enableVertexAttribArray(0);
+       gl.vertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)(3 * sizeof(GL_FLOAT)));
+       gl.enableVertexAttribArray(1);
+
+       gl.bindVertexArray(0);
+       gl.bindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+class TextureDecodeSkippedCase : public SRGBTestCase
+{
+public:
+                       TextureDecodeSkippedCase        (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+                               : SRGBTestCase                  (context, name, description, internalFormat) {}
+
+                       ~TextureDecodeSkippedCase       (void) {}
+
+       void    setupTest                                       (void);
+       bool    verifyResult                            (void);
+};
+
+void TextureDecodeSkippedCase::setupTest (void)
+{
+       // TEST STEPS:
+       //      - create and set texture to DECODE_SKIP_EXT
+       //      - store texture on GPU
+       //      - in fragment shader, sample the texture using texture*() and render texel values to a color attachment in the FBO
+       //      - on the host, read back the pixel values into a tcu::TextureLevel
+       //      - analyse the texel values, expecting them in sRGB format i.e. linear space decoding was skipped
+
+       FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_SKIP_DECODE);
+
+       this->addShaderProgram(shaderParameters);
+       this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
+
+       this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
+}
+
+bool TextureDecodeSkippedCase::verifyResult (void)
+{
+       tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
+       const int                               resultColorIdx  = 0;
+       std::vector<tcu::Vec4>  pixelResultList;
+       tcu::Vec4                               pixelConverted;
+       tcu::Vec4                               pixelReference;
+       tcu::Vec4                               pixelExpected;
+
+       this->readResultTextures();
+       this->storeResultPixels(pixelResultList);
+
+       pixelConverted = tcu::sRGBToLinear(pixelResultList[resultColorIdx]);
+       pixelReference = this->formatReferenceColor(getColorReferenceLinear());
+       pixelExpected = this->formatReferenceColor(getColorReferenceSRGB());
+
+       this->formatReferenceColor(pixelReference);
+       this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
+
+       // result color 0 should be sRGB. Compare with linear reference color
+       if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) )
+       {
+               log << tcu::TestLog::Message << std::string("sRGB as expected") << tcu::TestLog::EndMessage;
+               return true;
+       }
+       else
+       {
+               log << tcu::TestLog::Message << std::string("not sRGB as expected") << tcu::TestLog::EndMessage;
+               return false;
+       }
+}
+
+class TextureDecodeEnabledCase : public SRGBTestCase
+{
+public:
+               TextureDecodeEnabledCase        (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+                       : SRGBTestCase                  (context, name, description, internalFormat) {}
+
+               ~TextureDecodeEnabledCase       (void) {}
+
+               void    setupTest                       (void);
+               bool    verifyResult            (void);
+};
+
+void TextureDecodeEnabledCase::setupTest (void)
+{
+       // TEST STEPS:
+       //      - create and set texture to DECODE_EXT
+       //      - store texture on GPU
+       //      - in fragment shader, sample the texture using texture*() and render texel values to a color attachment in the FBO
+       //      - on the host, read back the pixel values into a tcu::TextureLevel
+       //      - analyse the texel values, expecting them in lRGB format i.e. linear space decoding was enabled
+
+       FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_DECODE);
+
+       this->addShaderProgram(shaderParameters);
+
+       this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
+
+       this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
+}
+
+bool TextureDecodeEnabledCase::verifyResult (void)
+{
+       tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
+       const int                               resultColorIdx  = 0;
+       std::vector<tcu::Vec4>  pixelResultList;
+       tcu::Vec4                               pixelConverted;
+       tcu::Vec4                               pixelReference;
+       tcu::Vec4                               pixelExpected;
+
+       this->readResultTextures();
+       this->storeResultPixels(pixelResultList);
+
+       pixelConverted = tcu::linearToSRGB(pixelResultList[resultColorIdx]);
+       pixelReference = this->formatReferenceColor(getColorReferenceSRGB());
+       pixelExpected = this->formatReferenceColor(getColorReferenceLinear());
+
+       this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
+
+       // result color 0 should be SRGB. Compare with sRGB reference color
+       if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) )
+       {
+               log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage;
+               return true;
+       }
+       else
+       {
+               log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage;
+               return false;
+       }
+}
+
+class TexelFetchDecodeSkippedcase : public SRGBTestCase
+{
+public:
+                       TexelFetchDecodeSkippedcase             (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+                               : SRGBTestCase                          (context, name, description, internalFormat) {}
+
+                       ~TexelFetchDecodeSkippedcase    (void) {}
+
+       void    setupTest                                               (void);
+       bool    verifyResult                                    (void);
+};
+
+void TexelFetchDecodeSkippedcase::setupTest (void)
+{
+       // TEST STEPS:
+       //      - create and set texture to DECODE_SKIP_EXT
+       //      - store texture on GPU
+       //      - in fragment shader, sample the texture using texelFetch*() and render texel values to a color attachment in the FBO
+       //      - on the host, read back the pixel values into a tcu::TextureLevel
+       //      - analyse the texel values, expecting them in lRGB format i.e. linear space decoding is always enabled with texelFetch*()
+
+       FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_SKIP_DECODE);
+
+       this->addShaderProgram(shaderParameters);
+
+       this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
+
+       this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXEL_FETCH);
+}
+
+bool TexelFetchDecodeSkippedcase::verifyResult (void)
+{
+       tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
+       const int                               resultColorIdx  = 0;
+       std::vector<tcu::Vec4>  pixelResultList;
+       tcu::Vec4                               pixelReference;
+       tcu::Vec4                               pixelExpected;
+
+       this->readResultTextures();
+       this->storeResultPixels(pixelResultList);
+
+       pixelReference = pixelExpected = this->formatReferenceColor(getColorReferenceLinear());
+
+       this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
+
+       // result color 0 should be linear due to automatic conversion via texelFetch*(). Compare with linear reference color
+       if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelResultList[0] - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelResultList[0], pixelReference))) )
+       {
+               log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage;
+               return true;
+       }
+       else
+       {
+               log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage;
+               return false;
+       }
+}
+
+class GPUConversionDecodeEnabledCase : public SRGBTestCase
+{
+public:
+                       GPUConversionDecodeEnabledCase  (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+                               : SRGBTestCase                          (context, name, description, internalFormat) {}
+
+                       ~GPUConversionDecodeEnabledCase (void) {}
+
+       void    setupTest                                               (void);
+       bool    verifyResult                                    (void);
+};
+
+void GPUConversionDecodeEnabledCase::setupTest (void)
+{
+       // TEST STEPS:
+       //      - create and set texture_a to DECODE_SKIP_EXT and texture_b to default
+       //      - store textures on GPU
+       //      - in fragment shader, sample both textures using texture*() and manually perform sRGB to lRGB conversion on texture_b
+       //      - in fragment shader, compare converted texture_b with texture_a
+       //      - render green image for pass or red for fail
+
+       ComparisonFunction comparisonFunction("srgbToLinearCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionSRGBToLinearCheck());
+
+       FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &comparisonFunction, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_SKIP_DECODE);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_DECODE_DEFAULT);
+
+       this->addShaderProgram(shaderParameters);
+
+       this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
+
+       this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
+}
+
+bool GPUConversionDecodeEnabledCase::verifyResult (void)
+{
+       tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
+       const int                               resultColorIdx  = 0;
+       std::vector<tcu::Vec4>  pixelResultList;
+
+       this->readResultTextures();
+       this->storeResultPixels(pixelResultList);
+       this->logColor(std::string("Expected color: "), resultColorIdx, getColorGreenPass());
+
+       // result color returned from GPU is either green (pass) or fail (red)
+       if ( tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], getColorGreenPass())) )
+       {
+               log << tcu::TestLog::Message << std::string("returned pass color from GPU") << tcu::TestLog::EndMessage;
+               return true;
+       }
+       else
+       {
+               log << tcu::TestLog::Message << std::string("returned fail color from GPU") << tcu::TestLog::EndMessage;
+               return false;
+       }
+}
+
+class DecodeToggledCase : public SRGBTestCase
+{
+public:
+                       DecodeToggledCase       (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+                               : SRGBTestCase  (context, name, description, internalFormat) {}
+
+                       ~DecodeToggledCase      (void) {}
+
+       void    render                          (void);
+       void    setupTest                       (void);
+       bool    verifyResult            (void);
+};
+
+void DecodeToggledCase::render (void)
+{
+       // override the base SRGBTestCase render function with the purpose of switching between shader programs,
+       // toggling texture sRGB decode state between draw calls
+       const glw::Functions& gl = m_context.getRenderContext().getFunctions();
+
+       gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
+       gl.bindVertexArray(m_vaoID);
+
+       for (std::size_t programIdx = 0; programIdx < m_shaderProgramList.size(); programIdx++)
+       {
+               gl.useProgram(m_shaderProgramList[programIdx]->getHandle());
+
+               this->toggleDecode(m_shaderProgramList[programIdx]->getUniformDataList());
+
+               for (int textureSourceIdx = 0; textureSourceIdx < (int)m_textureSourceList.size(); textureSourceIdx++)
+               {
+                       gl.activeTexture(GL_TEXTURE0 + (glw::GLenum)textureSourceIdx);
+                       gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), m_textureSourceList[textureSourceIdx]->getHandle());
+                       glw::GLuint samplerUniformLocationID = gl.getUniformLocation(m_shaderProgramList[programIdx]->getHandle(), m_shaderProgramList[programIdx]->getUniformAtLocation(textureSourceIdx).name.c_str());
+                       TCU_CHECK(samplerUniformLocationID != (glw::GLuint) - 1);
+                       gl.uniform1i(samplerUniformLocationID, (glw::GLenum)textureSourceIdx);
+               }
+
+               for (int samplerIdx = 0; samplerIdx < (int)m_samplerList.size(); samplerIdx++)
+               {
+                       if (m_samplerList[samplerIdx]->getIsActive() == true)
+                       {
+                               m_samplerList[samplerIdx]->bindToTexture();
+                       }
+               }
+
+               if (m_shaderProgramList[programIdx]->getBlendRequired() == true)
+               {
+                       gl.enable(GL_BLEND);
+                       gl.blendEquation(GL_MAX);
+                       gl.blendFunc(GL_ONE, GL_ONE);
+               }
+               else
+               {
+                       gl.disable(GL_BLEND);
+               }
+
+               gl.drawArrays(GL_TRIANGLES, 0, 6);
+
+               // reset sRGB decode state on textures
+               this->toggleDecode(m_shaderProgramList[programIdx]->getUniformDataList());
+       }
+
+       for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++)
+       {
+               gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), 0);
+       }
+       gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
+       gl.bindVertexArray(0);
+       gl.bindBuffer(GL_ARRAY_BUFFER, 0);
+}
+
+void DecodeToggledCase::setupTest (void)
+{
+       // TEST STEPS:
+       //      - create and set texture_a to DECODE_SKIP_EXT and texture_b to DECODE_EXT
+       //      - create and use two seperate shader programs, program_a and program_b, each using different fragment shaders
+       //      - store texture_a and texture_b on GPU
+       // FIRST PASS:
+       //      - use program_a
+       //      - in fragment shader, sample both textures using texture*() and manually perform sRGB to lRGB conversion on texture_a
+       //      - in fragment shader, test converted texture_a value with texture_b
+       //      - render green image for pass or red for fail
+       //      - store result in a color attachement 0
+       // TOGGLE STAGE
+       //      - during rendering, toggle texture_a from DECODE_SKIP_EXT to DECODE_EXT
+       // SECOND PASS:
+       //      - use program_b
+       //      - in fragment shader, sample both textures using texture*() and manually perform equality check. Both should be linear
+       //      - blend first pass result with second pass. Anything but a green result equals fail
+
+       ComparisonFunction srgbToLinearFunction("srgbToLinearCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionSRGBToLinearCheck());
+       ComparisonFunction colorsEqualFunction("colorsEqualCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionEqualCheck());
+
+       FragmentShaderParameters shaderParametersA(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &srgbToLinearFunction, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
+       FragmentShaderParameters shaderParametersB(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &colorsEqualFunction, BLENDING_REQUIRED, TOGGLING_REQUIRED);
+
+       // need to specify which texture uniform to toggle DECODE_EXT/SKIP_DECODE_EXT
+       shaderParametersB.uniformsToToggle.push_back("uTexture0");
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_SKIP_DECODE);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_DECODE);
+
+       this->addShaderProgram(shaderParametersA);
+       this->addShaderProgram(shaderParametersB);
+
+       this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
+       this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
+}
+
+bool DecodeToggledCase::verifyResult (void)
+{
+       tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
+       const int                               resultColorIdx  = 0;
+       std::vector<tcu::Vec4>  pixelResultList;
+
+       this->readResultTextures();
+       this->storeResultPixels(pixelResultList);
+       this->logColor(std::string("Expected color: "), resultColorIdx, getColorGreenPass());
+
+       //      result color is either green (pass) or fail (red)
+       if ( tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], getColorGreenPass())) )
+       {
+               log << tcu::TestLog::Message << std::string("returned pass color from GPU") << tcu::TestLog::EndMessage;
+               return true;
+       }
+       else
+       {
+               log << tcu::TestLog::Message << std::string("returned fail color from GPU") << tcu::TestLog::EndMessage;
+               return false;
+       }
+}
+
+class DecodeMultipleTexturesCase : public SRGBTestCase
+{
+public:
+                       DecodeMultipleTexturesCase      (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+                               : SRGBTestCase                  (context, name, description, internalFormat) {}
+
+                       ~DecodeMultipleTexturesCase     (void) {}
+
+       void    setupTest                                       (void);
+       bool    verifyResult                            (void);
+};
+
+void DecodeMultipleTexturesCase::setupTest (void)
+{
+       // TEST STEPS:
+       //      - create and set texture_a to DECODE_SKIP_EXT and texture_b to DECODE_EXT
+       //      - upload textures to the GPU and bind to seperate uniform variables
+       //      - sample both textures using texture*()
+       //      - read texel values back to the CPU
+       //      - compare the texel values, both should be different from each other
+
+       FragmentShaderParameters shaderParameters(SHADEROUTPUTS_TWO, SHADERUNIFORMS_TWO, NULL,  BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_SKIP_DECODE);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_DECODE);
+
+       this->addShaderProgram(shaderParameters);
+
+       this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
+       this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
+}
+
+bool DecodeMultipleTexturesCase::verifyResult (void)
+{
+       tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
+       const int                               resultColorIdx  = 0;
+       std::vector<tcu::Vec4>  pixelResultList;
+       tcu::Vec4                               pixelExpected0;
+       tcu::Vec4                               pixelExpected1;
+
+       this->readResultTextures();
+       this->storeResultPixels(pixelResultList);
+
+       pixelExpected0 = this->formatReferenceColor(getColorReferenceSRGB());
+       pixelExpected1 = this->formatReferenceColor(getColorReferenceLinear());
+
+       this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected0);
+       this->logColor(std::string("Expected color: "), resultColorIdx +1, pixelExpected1);
+
+       //      check if the two textures have different values i.e. uTexture0 = sRGB and uTexture1 = linear
+       if ( !(tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], pixelResultList[resultColorIdx +1]))) )
+       {
+               log << tcu::TestLog::Message << std::string("texel values are different") << tcu::TestLog::EndMessage;
+               return true;
+       }
+       else
+       {
+               log << tcu::TestLog::Message << std::string("texel values are equal") << tcu::TestLog::EndMessage;
+               return false;
+       }
+}
+
+class DecodeSamplerCase : public SRGBTestCase
+{
+public:
+                       DecodeSamplerCase       (Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
+                               : SRGBTestCase  (context, name, description, internalFormat) {}
+
+                       ~DecodeSamplerCase      (void) {}
+
+       void    setupTest                       (void);
+       bool    verifyResult            (void);
+};
+
+void DecodeSamplerCase::setupTest (void)
+{
+       // TEST STEPS:
+       //      - create and set texture_a to DECODE_SKIP_EXT
+       //      - upload texture to the GPU and bind to sampler
+       //      - sample texture using texture*()
+       //      - read texel values back to the CPU
+       //      - compare the texel values, should be in sampler format (linear)
+
+       FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
+
+       this->addTexture(       TEXTURETYPE_2D,
+                                               TestDimensions::WIDTH,
+                                               TestDimensions::HEIGHT,
+                                               getColorReferenceLinear(),
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_SKIP_DECODE);
+
+       this->addSampler(       tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::MIRRORED_REPEAT_GL,
+                                               tcu::Sampler::LINEAR,
+                                               tcu::Sampler::LINEAR,
+                                               SRGBDECODE_DECODE);
+
+       this->addShaderProgram(shaderParameters);
+
+       this->bindSamplerToTexture(0, 0, GL_TEXTURE0);
+       this->activateSampler(0, true);
+
+       this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
+       this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
+}
+
+bool DecodeSamplerCase::verifyResult (void)
+{
+       tcu::TestLog&                   log                             = m_context.getTestContext().getLog();
+       const int                               resultColorIdx  = 0;
+       std::vector<tcu::Vec4>  pixelResultList;
+       tcu::Vec4                               pixelConverted;
+       tcu::Vec4                               pixelReference;
+       tcu::Vec4                               pixelExpected;
+
+       this->readResultTextures();
+       this->storeResultPixels(pixelResultList);
+
+       pixelConverted = tcu::linearToSRGB(pixelResultList[resultColorIdx]);
+       pixelReference = this->formatReferenceColor(getColorReferenceSRGB());
+       pixelExpected = this->formatReferenceColor(getColorReferenceLinear());
+
+       this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
+
+       //      texture was rendered using a sampler object with setting DECODE_EXT, therefore, results should be linear
+       if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) )
+       {
+               log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage;
+               return true;
+       }
+       else
+       {
+               log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage;
+               return false;
+       }
+}
+
+} // anonymous
+
+SRGBDecodeTests::SRGBDecodeTests       (Context& context)
+       : TestCaseGroup                                 (context, "skip_decode", "sRGB skip decode tests")
+{
+}
+
+SRGBDecodeTests::~SRGBDecodeTests (void)
+{
+}
+
+void SRGBDecodeTests::init (void)
+{
+       const TestGroupConfig testGroupConfigList[] =
+       {
+               TestGroupConfig("srgba8",       "srgb decode tests using srgba internal format",        tcu::TextureFormat(tcu::TextureFormat::sRGBA, tcu::TextureFormat::UNORM_INT8)),
+               TestGroupConfig("sr8",          "srgb decode tests using sr8 internal format",          tcu::TextureFormat(tcu::TextureFormat::sR, tcu::TextureFormat::UNORM_INT8))
+       };
+
+       // create groups for all desired internal formats, adding test cases to each
+       for (std::size_t idx = 0; idx < DE_LENGTH_OF_ARRAY(testGroupConfigList); idx++)
+       {
+               tcu::TestCaseGroup* const testGroup = new tcu::TestCaseGroup(m_testCtx, testGroupConfigList[idx].name, testGroupConfigList[idx].description);
+               tcu::TestNode::addChild(testGroup);
+
+               testGroup->addChild(new TextureDecodeSkippedCase                (m_context, "skipped",                  "testing for sRGB color values with sRGB texture decoding skipped",             testGroupConfigList[idx].internalFormat));
+               testGroup->addChild(new TextureDecodeEnabledCase                (m_context, "enabled",                  "testing for linear color values with sRGB texture decoding enabled",   testGroupConfigList[idx].internalFormat));
+               testGroup->addChild(new TexelFetchDecodeSkippedcase             (m_context, "texel_fetch",              "testing for linear color values with sRGB texture decoding skipped",   testGroupConfigList[idx].internalFormat));
+               testGroup->addChild(new GPUConversionDecodeEnabledCase  (m_context, "conversion_gpu",   "sampling linear values and performing conversion on the gpu",                  testGroupConfigList[idx].internalFormat));
+               testGroup->addChild(new DecodeToggledCase                               (m_context, "toggled",                  "toggle the sRGB decoding between draw calls",                                                  testGroupConfigList[idx].internalFormat));
+               testGroup->addChild(new DecodeMultipleTexturesCase              (m_context, "multiple_textures","upload multiple textures with different sRGB decode values and sample",testGroupConfigList[idx].internalFormat));
+               testGroup->addChild(new DecodeSamplerCase                               (m_context, "using_sampler",    "testing that sampler object takes priority over texture state",                testGroupConfigList[idx].internalFormat));
+       }
+}
+
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fSRGBDecodeTests.hpp b/modules/gles31/functional/es31fSRGBDecodeTests.hpp
new file mode 100644 (file)
index 0000000..8be5da7
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef _ES31FSRGBDECODETESTS_HPP
+#define _ES31FSRGBDECODETESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 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 sRGB decode tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "tes31TestCase.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+
+class SRGBDecodeTests : public TestCaseGroup
+{
+public:
+                                                SRGBDecodeTests        (Context& context);
+                                               ~SRGBDecodeTests        (void);
+
+private:
+       void                            init                            (void);
+
+                                               SRGBDecodeTests         (const SRGBDecodeTests& other);
+       SRGBDecodeTests&        operator=                       (const SRGBDecodeTests& other);
+};
+
+} // Functional
+} // gles31
+} // deqp
+
+
+#endif // _ES31FSRGBDECODETESTS_HPP
\ No newline at end of file
index d84b6cb..c07181f 100644 (file)
@@ -3101,7 +3101,7 @@ std::string ConcurrentSSBOAtomicCounterMixedCase::genSSBOComputeSource (void) co
                << "void main ()\n"
                << "{\n"
                << "    // flip high bits\n"
-               << "    highp uint mask = uint(1) << (16u + (gl_GlobalInvocationID.x % 16u));\n"
+               << "    highp uint mask = uint(1) << (24u + (gl_GlobalInvocationID.x % 8u));\n"
                << "    sb_work.dummy = atomicXor(sb_work.targetValue, mask);\n"
                << "}";
 
index e367fd3..cabb96f 100644 (file)
@@ -7230,7 +7230,7 @@ void TessellationTests::init (void)
                queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_texture_image_units",                   "Test MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS",                 GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS,             16));
                queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_output_components",                                "Test MAX_TESS_CONTROL_OUTPUT_COMPONENTS",                              GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS,                  64));
                queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_patch_components",                                                 "Test MAX_TESS_PATCH_COMPONENTS",                                               GL_MAX_TESS_PATCH_COMPONENTS,                                   120));
-               queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_total_output_components",                  "Test MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS",                GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS,    4096));
+               queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_total_output_components",                  "Test MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS",                GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS,    2048));
                queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_output_components",                             "Test MAX_TESS_EVALUATION_OUTPUT_COMPONENTS",                   GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS,               64));
                queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_control_uniform_blocks",                                   "Test MAX_TESS_CONTROL_UNIFORM_BLOCKS",                                 GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS,                             12));
                queryGroup->addChild(new LimitQueryCase(m_context, "max_tess_evaluation_uniform_blocks",                                "Test MAX_TESS_EVALUATION_UNIFORM_BLOCKS",                              GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS,                  12));
index 3901ec1..791d8c9 100644 (file)
@@ -232,6 +232,12 @@ static const FormatExtEntry s_esExtFormats[] =
                (deUint32)(DEPTH_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID),
                GLS_ARRAY_RANGE(s_oesPackedDepthStencilTexFormats)
        },
+       // The ANGLE extension incorporates GL_OES_depth_texture/GL_OES_packed_depth_stencil.
+       {
+               "GL_ANGLE_depth_texture",
+               (deUint32)(REQUIRED_RENDERABLE | DEPTH_RENDERABLE | TEXTURE_VALID),
+               GLS_ARRAY_RANGE(s_oesDepthTextureFormats),
+       },
        // \todo [2013-12-10 lauri] Find out if OES_texture_half_float is really a
        // requirement on ES3 also. Or is color_buffer_half_float applicatble at
        // all on ES3, since there's also EXT_color_buffer_float?
index de28b32..162ab3a 100644 (file)
@@ -207,7 +207,7 @@ NYC_EGL_PKG                                         = Package(module = EGL_MODULE, configurations = [
                                          rotation              = "unspecified",
                                          surfacetype   = "window",
                                          filters               = NYC_EGL_COMMON_FILTERS,
-                                     runtime           = "24m"),
+                                     runtime           = "11m"),
        ])
 
 NYC_GLES2_COMMON_FILTERS                       = [
@@ -220,7 +220,7 @@ NYC_GLES2_PKG                                       = Package(module = GLES2_MODULE, configurations = [
                                          rotation              = "unspecified",
                                          surfacetype   = "window",
                                          filters               = NYC_GLES2_COMMON_FILTERS,
-                                         runtime               = "40m"),
+                                         runtime               = "30m"),
        ])
 
 NYC_GLES3_COMMON_FILTERS               = [
@@ -233,32 +233,32 @@ NYC_GLES3_PKG                                     = Package(module = GLES3_MODULE, configurations = [
                                          rotation              = "unspecified",
                                          surfacetype   = "window",
                                          filters               = NYC_GLES3_COMMON_FILTERS,
-                                         runtime               = "1h15m"),
+                                         runtime               = "1h50min"),
                # Rotations
                Configuration(name                      = "rotate-portrait",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "0",
                                          surfacetype   = "window",
                                          filters               = NYC_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "5m"),
                Configuration(name                      = "rotate-landscape",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "90",
                                          surfacetype   = "window",
                                          filters               = NYC_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "5m"),
                Configuration(name                      = "rotate-reverse-portrait",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "180",
                                          surfacetype   = "window",
                                          filters               = NYC_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "5m"),
                Configuration(name                      = "rotate-reverse-landscape",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "270",
                                          surfacetype   = "window",
                                          filters               = NYC_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "5m"),
 
                # MSAA
                Configuration(name                      = "multisample",
@@ -287,7 +287,7 @@ NYC_GLES31_PKG                                      = Package(module = GLES31_MODULE, configurations = [
                                          rotation              = "unspecified",
                                          surfacetype   = "window",
                                          filters               = NYC_GLES31_COMMON_FILTERS,
-                                         runtime               = "7h30m"),
+                                         runtime               = "4h40m"),
 
                # Rotations
                Configuration(name                      = "rotate-portrait",
@@ -338,14 +338,15 @@ NYC_VULKAN_FILTERS                                = [
 NYC_VULKAN_PKG                                 = Package(module = VULKAN_MODULE, configurations = [
                Configuration(name                      = "master",
                                          filters               = NYC_VULKAN_FILTERS,
-                                         runtime               = "3h45m"),
+                                         runtime               = "1h11m"),
        ])
 
 # Master
 
 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",
@@ -354,7 +355,7 @@ MASTER_EGL_PKG                                      = Package(module = EGL_MODULE, configurations = [
                                          surfacetype   = "window",
                                          required              = True,
                                          filters               = MASTER_EGL_COMMON_FILTERS,
-                                     runtime           = "24m"),
+                                     runtime           = "23m"),
        ])
 
 MASTER_GLES2_COMMON_FILTERS            = [
@@ -370,7 +371,7 @@ MASTER_GLES2_PKG                            = Package(module = GLES2_MODULE, configurations = [
                                          surfacetype   = "window",
                                          required              = True,
                                          filters               = MASTER_GLES2_COMMON_FILTERS,
-                                         runtime               = "40m"),
+                                         runtime               = "46m"),
        ])
 
 MASTER_GLES3_COMMON_FILTERS            = [
@@ -388,32 +389,32 @@ MASTER_GLES3_PKG                          = Package(module = GLES3_MODULE, configurations = [
                                          surfacetype   = "window",
                                          required              = True,
                                          filters               = MASTER_GLES3_COMMON_FILTERS,
-                                         runtime               = "1h15m"),
+                                         runtime               = "1h50m"),
                # Rotations
                Configuration(name                      = "rotate-portrait",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "0",
                                          surfacetype   = "window",
                                          filters               = MASTER_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "1m"),
                Configuration(name                      = "rotate-landscape",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "90",
                                          surfacetype   = "window",
                                          filters               = MASTER_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "1m"),
                Configuration(name                      = "rotate-reverse-portrait",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "180",
                                          surfacetype   = "window",
                                          filters               = MASTER_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "1m"),
                Configuration(name                      = "rotate-reverse-landscape",
                                          glconfig              = "rgba8888d24s8ms0",
                                          rotation              = "270",
                                          surfacetype   = "window",
                                          filters               = MASTER_GLES3_COMMON_FILTERS + [include("gles3-rotation.txt")],
-                                         runtime               = "7m"),
+                                         runtime               = "1m"),
 
                # MSAA
                Configuration(name                      = "multisample",
@@ -422,7 +423,7 @@ MASTER_GLES3_PKG                            = Package(module = GLES3_MODULE, configurations = [
                                          surfacetype   = "window",
                                          filters               = MASTER_GLES3_COMMON_FILTERS + [include("gles3-multisample.txt"),
                                                                                                                                         exclude("gles3-multisample-issues.txt")],
-                                         runtime               = "10m"),
+                                         runtime               = "1m"),
 
                # Pixel format
                Configuration(name                      = "565-no-depth-no-stencil",
@@ -431,7 +432,7 @@ MASTER_GLES3_PKG                            = Package(module = GLES3_MODULE, configurations = [
                                          surfacetype   = "window",
                                          filters               = MASTER_GLES3_COMMON_FILTERS + [include("gles3-pixelformat.txt"),
                                                                                                                                         exclude("gles3-pixelformat-issues.txt")],
-                                         runtime               = "10m"),
+                                         runtime               = "1m"),
        ])
 
 MASTER_GLES31_COMMON_FILTERS   = [
@@ -449,7 +450,7 @@ MASTER_GLES31_PKG                           = Package(module = GLES31_MODULE, configurations = [
                                          surfacetype   = "window",
                                          required              = True,
                                          filters               = MASTER_GLES31_COMMON_FILTERS,
-                                         runtime               = "7h30m"),
+                                         runtime               = "1h40m"),
 
                # Rotations
                Configuration(name                      = "rotate-portrait",
@@ -503,7 +504,7 @@ MASTER_VULKAN_FILTERS                       = [
 MASTER_VULKAN_PKG                              = Package(module = VULKAN_MODULE, configurations = [
                Configuration(name                      = "master",
                                          filters               = MASTER_VULKAN_FILTERS,
-                                         runtime               = "3h45m"),
+                                         runtime               = "2h29m"),
        ])
 
 MUSTPASS_LISTS                         = [
index 7554f2b..c8761ce 100644 (file)
@@ -39,8 +39,8 @@ EGL_WRAPPER_DIR               = os.path.normpath(os.path.join(EGL_DIR, "wrapper"))
 
 EGL_SOURCE                     = khr_util.registry_cache.RegistrySource(
                                                "egl.xml",
-                                               32725,
-                                               "3464385212ae9b816d121c77bc4191ed3dfb32ce7bfca1a02b42fcefa3ec2354")
+                                               33315,
+                                               "19f3b517f0dede56a6a94b820d08149ef5e1726f58202f47d69fa27f6f483bd2")
 
 VERSION                                = '1.5'
 
@@ -65,7 +65,8 @@ EXTENSIONS                    = [
        "EGL_EXT_buffer_age",
        "EGL_KHR_partial_update",
        "EGL_KHR_swap_buffers_with_damage",
-       "EGL_KHR_mutable_render_buffer"
+       "EGL_KHR_mutable_render_buffer",
+       "EGL_EXT_pixel_format_float"
 ]
 PROTECTS                       = [
        "KHRONOS_SUPPORT_INT64"
index 4372932..57627b6 100644 (file)
@@ -106,7 +106,8 @@ ENUM_GROUPS = [
                "TRANSPARENT_TYPE",
                "TRANSPARENT_RED_VALUE",
                "TRANSPARENT_GREEN_VALUE",
-               "TRANSPARENT_BLUE_VALUE"
+               "TRANSPARENT_BLUE_VALUE",
+               "COLOR_COMPONENT_TYPE_EXT"
                ]),
        ("SurfaceAttrib", [
                "CONFIG_ID",
@@ -141,6 +142,7 @@ ENUM_GROUPS = [
                "YUV_PLANE_BPP_8_EXT",
                "YUV_PLANE_BPP_10_EXT",
                ]),
+       ("ColorComponentType",  ["COLOR_COMPONENT_TYPE_FIXED_EXT", "COLOR_COMPONENT_TYPE_FLOAT_EXT"]),
        ("SurfaceTarget",               ["READ", "DRAW"]),
 
        # ConfigAttrib values
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):
index 376553e..1c248b0 100644 (file)
@@ -48,6 +48,7 @@ EXTENSIONS                    = [
        'GL_EXT_geometry_point_size',
        'GL_EXT_tessellation_shader',
        'GL_EXT_geometry_shader',
+       'GL_EXT_robustness',
        'GL_EXT_texture_buffer',
        'GL_EXT_texture_snorm',
        'GL_EXT_primitive_bounding_box',