Merge in new OpenGL ES 3.2 test code
authorPyry Haulos <phaulos@google.com>
Mon, 22 Feb 2016 18:44:18 +0000 (10:44 -0800)
committerPyry Haulos <phaulos@google.com>
Mon, 22 Feb 2016 18:44:18 +0000 (10:44 -0800)
Change-Id: I8667c03f0d1eb4b212bc33b54296336633fb39da

15 files changed:
Android.mk
modules/gles31/functional/CMakeLists.txt
modules/gles31/functional/es31fDebugTests.cpp
modules/gles31/functional/es31fMultisampleShaderRenderCase.cpp
modules/gles31/functional/es31fNegativeBufferApiTests.cpp
modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeShaderDirectiveTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeShaderFunctionTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeTextureApiTests.cpp
modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp
modules/gles31/functional/es31fOpaqueTypeIndexingTests.cpp
modules/gles31/functional/es31fSampleVariableTests.cpp
modules/gles31/functional/es31fShaderBuiltinConstantTests.cpp
modules/gles31/functional/es31fShaderMultisampleInterpolationStateQueryTests.cpp

index c3820ac..d91b150 100644 (file)
@@ -571,6 +571,8 @@ LOCAL_SRC_FILES := \
        modules/gles31/functional/es31fNegativeBufferApiTests.cpp \
        modules/gles31/functional/es31fNegativeFragmentApiTests.cpp \
        modules/gles31/functional/es31fNegativeShaderApiTests.cpp \
+       modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp \
+       modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp \
        modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.cpp \
        modules/gles31/functional/es31fNegativeStateApiTests.cpp \
        modules/gles31/functional/es31fNegativeTestShared.cpp \
index 00073ad..68b98ef 100644 (file)
@@ -149,6 +149,10 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fNegativeAtomicCounterTests.hpp
        es31fNegativeShaderImageLoadStoreTests.cpp
        es31fNegativeShaderImageLoadStoreTests.hpp
+       es31fNegativeShaderFunctionTests.cpp
+       es31fNegativeShaderFunctionTests.hpp
+       es31fNegativeShaderDirectiveTests.cpp
+       es31fNegativeShaderDirectiveTests.hpp
        es31fTextureGatherTests.cpp
        es31fTextureGatherTests.hpp
        es31fTextureFormatTests.cpp
index f9c87d4..dc18706 100644 (file)
@@ -32,6 +32,8 @@
 #include "es31fNegativeStateApiTests.hpp"
 #include "es31fNegativeAtomicCounterTests.hpp"
 #include "es31fNegativeShaderImageLoadStoreTests.hpp"
+#include "es31fNegativeShaderFunctionTests.hpp"
+#include "es31fNegativeShaderDirectiveTests.hpp"
 
 #include "deUniquePtr.hpp"
 #include "deRandom.hpp"
@@ -2921,6 +2923,8 @@ void DebugTests::init (void)
        const vector<FunctionContainer> stateFuncs                                      = wrapCoreFunctions(NegativeTestShared::getNegativeStateApiTestFunctions());
        const vector<FunctionContainer> atomicCounterFuncs                      = wrapCoreFunctions(NegativeTestShared::getNegativeAtomicCounterTestFunctions());
        const vector<FunctionContainer> shaderImageLoadStoreFuncs       = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageLoadStoreTestFunctions());
+       const vector<FunctionContainer> shaderFunctionFuncs                     = wrapCoreFunctions(NegativeTestShared::getNegativeShaderFunctionTestFunctions());
+       const vector<FunctionContainer> shaderDirectiveFuncs            = wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions());
        const vector<FunctionContainer> externalFuncs                           = getUserMessageFuncs();
 
        {
@@ -3020,6 +3024,8 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "state",                                          "Negative GL State API Cases",                                          stateFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "atomic_counter",                         "Negative Atomic Counter API Cases",                            atomicCounterFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_image_load_store",        "Negative Shader Image Load and Store API Cases",       shaderImageLoadStoreFuncs));
+                       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));
                }
 
                {
@@ -3035,6 +3041,8 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "state",                                       "Negative GL State API Cases",                                          stateFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "atomic_counter",                      "Negative Atomic Counter API Cases",                            atomicCounterFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_image_load_store",     "Negative Shader Image Load and Store API Cases",       shaderImageLoadStoreFuncs));
+                       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));
                }
 
                {
@@ -3050,6 +3058,8 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "state",                                          "Negative GL State API Cases",                                          stateFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "atomic_counter",                         "Negative Atomic Counter API Cases",                            atomicCounterFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_image_load_store",        "Negative Shader Image Load and Store API Cases",       shaderImageLoadStoreFuncs));
+                       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));
                }
        }
 
index 3b16c1b..1a17e00 100644 (file)
@@ -25,6 +25,7 @@
 #include "tcuRenderTarget.hpp"
 #include "tcuSurface.hpp"
 #include "tcuTestLog.hpp"
+#include "tcuStringTemplate.hpp"
 #include "gluShaderProgram.hpp"
 #include "gluRenderContext.hpp"
 #include "gluPixelTransfer.hpp"
@@ -40,10 +41,12 @@ namespace Functional
 {
 namespace MultisampleShaderRenderUtil
 {
+using std::map;
+using std::string;
 namespace
 {
 
-static const char* const s_vertexSource =      "#version 310 es\n"
+static const char* const s_vertexSource =      "${GLSL_VERSION_DECL}\n"
                                                                                        "in highp vec4 a_position;\n"
                                                                                        "out highp vec4 v_position;\n"
                                                                                        "void main (void)\n"
@@ -95,6 +98,9 @@ void MultisampleRenderCase::init (void)
 {
        const glw::Functions&   gl                                      = m_context.getRenderContext().getFunctions();
        deInt32                                 queriedSampleCount      = -1;
+       const bool                              isES32                          = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>             args;
+       args["GLSL_VERSION_DECL"]                                       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
 
        // requirements
 
@@ -203,7 +209,9 @@ void MultisampleRenderCase::init (void)
                }
 
                // texture sampler shader
-               m_textureSamplerProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(s_vertexSource) << glu::FragmentSource(genMSSamplerSource(queriedSampleCount)));
+               m_textureSamplerProgram = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
+                       << glu::VertexSource(tcu::StringTemplate(s_vertexSource).specialize(args))
+                       << glu::FragmentSource(genMSSamplerSource(queriedSampleCount)));
                if (!m_textureSamplerProgram->isOk())
                {
                        m_testCtx.getLog() << tcu::TestLog::Section("SamplerShader", "Sampler shader") << *m_textureSamplerProgram << tcu::TestLog::EndSection;
@@ -450,7 +458,9 @@ void MultisampleRenderCase::drawOneIteration (void)
                delete m_program;
                m_program = DE_NULL;
 
-               m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources() << glu::VertexSource(genVertexSource(m_numTargetSamples)) << glu::FragmentSource(genFragmentSource(m_numTargetSamples)));
+               m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::ProgramSources()
+                       << glu::VertexSource(genVertexSource(m_numTargetSamples))
+                       << glu::FragmentSource(genFragmentSource(m_numTargetSamples)));
                m_testCtx.getLog() << tcu::TestLog::Section("RenderShader", "Render shader") << *m_program << tcu::TestLog::EndSection;
                if (!m_program->isOk())
                        throw tcu::TestError("could not build program");
@@ -660,8 +670,12 @@ void MultisampleRenderCase::drawOneIteration (void)
 
 std::string    MultisampleRenderCase::genVertexSource (int numTargetSamples) const
 {
+       const bool                              isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>             args;
+       args["GLSL_VERSION_DECL"]               = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+
        DE_UNREF(numTargetSamples);
-       return std::string(s_vertexSource);
+       return std::string(tcu::StringTemplate(s_vertexSource).specialize(args));
 }
 
 std::string MultisampleRenderCase::genMSSamplerSource (int numTargetSamples) const
@@ -676,10 +690,13 @@ std::string       MultisampleRenderCase::genMSTextureResolverSource (int numTargetSamp
 {
        // default behavior: average
 
-       const bool                      isSingleSampleTarget = (m_numRequestedSamples == 0);
-       std::ostringstream      buf;
+       const bool                              isES32                                  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>             args;
+       args["GLSL_VERSION_DECL"]                                               = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       const bool                              isSingleSampleTarget    = (m_numRequestedSamples == 0);
+       std::ostringstream              buf;
 
-       buf <<  "#version 310 es\n"
+       buf <<  "${GLSL_VERSION_DECL}\n"
                        "in mediump vec4 v_position;\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n"
                        "uniform mediump " << ((isSingleSampleTarget) ? ("sampler2D") : ("sampler2DMS")) << " u_sampler;\n"
@@ -702,17 +719,20 @@ std::string       MultisampleRenderCase::genMSTextureResolverSource (int numTargetSamp
        buf <<  "       fragColor = vec4(colorSum.xyz, 1.0);\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 std::string MultisampleRenderCase::genMSTextureLayerFetchSource (int numTargetSamples) const
 {
        DE_UNREF(numTargetSamples);
 
-       const bool                      isSingleSampleTarget = (m_numRequestedSamples == 0);
-       std::ostringstream      buf;
+       const bool                              isES32                                  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>             args;
+       args["GLSL_VERSION_DECL"]                                               = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       const bool                              isSingleSampleTarget    = (m_numRequestedSamples == 0);
+       std::ostringstream              buf;
 
-       buf <<  "#version 310 es\n"
+       buf <<  "${GLSL_VERSION_DECL}\n"
                        "in mediump vec4 v_position;\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n"
                        "uniform mediump " << ((isSingleSampleTarget) ? ("sampler2D") : ("sampler2DMS")) << " u_sampler;\n"
@@ -726,7 +746,7 @@ std::string MultisampleRenderCase::genMSTextureLayerFetchSource (int numTargetSa
                        "       fragColor = vec4(color.rgb, 1.0);\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool MultisampleRenderCase::verifySampleBuffers (const std::vector<tcu::Surface>& resultBuffers)
index da2e8a5..3d9871e 100644 (file)
@@ -24,7 +24,6 @@
 #include "es31fNegativeBufferApiTests.hpp"
 
 #include "gluCallLogWrapper.hpp"
-#include "gluContextInfo.hpp"
 
 #include "glwDefs.hpp"
 #include "glwEnums.hpp"
@@ -167,7 +166,8 @@ void clear (NegativeTestContext& ctx)
 
 void read_pixels (NegativeTestContext& ctx)
 {
-       std::vector<GLubyte> ubyteData(4);
+       std::vector<GLubyte>    ubyteData       (4);
+       GLuint                                  fbo                     = 0x1234;
 
        ctx.beginSection("GL_INVALID_OPERATION is generated if the combination of format and type is unsupported.");
        ctx.glReadPixels(0, 0, 1, 1, GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT_4_4_4_4, &ubyteData[0]);
@@ -184,7 +184,6 @@ void read_pixels (NegativeTestContext& ctx)
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
-       GLuint fbo = 0x1234;
        ctx.glGenFramebuffers(1, &fbo);
        ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -195,12 +194,50 @@ void read_pixels (NegativeTestContext& ctx)
        ctx.glDeleteFramebuffers(1, &fbo);
 }
 
+void readn_pixels (NegativeTestContext& ctx)
+{
+       std::vector<GLubyte>    ubyteData       (4);
+       GLuint                                  fbo                     = 0x1234;
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if the combination of format and type is unsupported.");
+       ctx.glReadnPixels(0, 0, 1, 1, GL_LUMINANCE_ALPHA, GL_UNSIGNED_SHORT_4_4_4_4, (int) ubyteData.size(), &ubyteData[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if either width or height is negative.");
+       ctx.glReadnPixels(0, 0, -1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (int) ubyteData.size(), &ubyteData[0]);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glReadnPixels(0, 0, 1, -1, GL_RGBA, GL_UNSIGNED_BYTE, (int) ubyteData.size(), &ubyteData[0]);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glReadnPixels(0, 0, -1, -1, GL_RGBA, GL_UNSIGNED_BYTE, (int) ubyteData.size(), &ubyteData[0]);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
+
+       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.endSection();
+
+       ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the currently bound framebuffer is not framebuffer complete.");
+       ctx.glGenFramebuffers(1, &fbo);
+       ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+       ctx.glReadnPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (int) ubyteData.size(), &ubyteData[0]);
+       ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
+       ctx.endSection();
+
+       ctx.glDeleteFramebuffers(1, &fbo);
+}
+
 void read_pixels_format_mismatch (NegativeTestContext& ctx)
 {
-       std::vector<GLubyte> ubyteData(4);
-       std::vector<GLushort> ushortData(4);
+       std::vector<GLubyte>    ubyteData       (4);
+       std::vector<GLushort>   ushortData      (4);
+       std::vector<GLfloat>    floatData       (4);
+       GLint                                   readFormat      = 0x1234;
+       GLint                                   readType        = 0x1234;
 
-       ctx.beginSection("Unsupported combinations of format and type will generate an INVALID_OPERATION error.");
+       ctx.beginSection("Unsupported combinations of format and type will generate an GL_INVALID_OPERATION error.");
        ctx.glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_SHORT_5_6_5, &ushortData[0]);
        ctx.expectError(GL_INVALID_OPERATION);
        ctx.glReadPixels(0, 0, 1, 1, GL_ALPHA, GL_UNSIGNED_SHORT_5_6_5, &ushortData[0]);
@@ -213,13 +250,13 @@ 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.");
        ctx.glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &ubyteData[0]);
        ctx.expectError(GL_NO_ERROR);
-       GLint readFormat = 0x1234;
-       GLint readType = 0x1234;
        ctx.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);
        ctx.glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
        ctx.glReadPixels(0, 0, 1, 1, readFormat, readType, &ubyteData[0]);
@@ -265,6 +302,14 @@ void read_pixels_fbo_format_mismatch (NegativeTestContext& ctx)
        ctx.glReadPixels                        (0, 0, 1, 1, GL_RGBA, GL_FLOAT, &floatData[0]);
        ctx.expectError                         (GL_INVALID_OPERATION);
 
+       ctx.glTexImage2D                        (GL_TEXTURE_2D, 0, GL_RGBA32F, 32, 32, 0, GL_RGBA, GL_FLOAT, NULL);
+       ctx.expectError                         (GL_NO_ERROR);
+       ctx.glFramebufferTexture2D      (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+       ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+       ctx.expectError                         (GL_NO_ERROR);
+       ctx.glReadPixels                        (0, 0, 1, 1, GL_RGBA, GL_INT, &floatData[0]);
+       ctx.expectError                         (GL_INVALID_OPERATION);
+
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_OPERATION is generated if GL_READ_FRAMEBUFFER_BINDING is non-zero, the read framebuffer is complete, and the value of GL_SAMPLE_BUFFERS for the read framebuffer is greater than zero.");
@@ -308,30 +353,37 @@ void read_pixels_fbo_format_mismatch (NegativeTestContext& ctx)
 
 void bind_buffer_range (NegativeTestContext& ctx)
 {
-       deUint32 bufU = 0x1234;
+       deUint32        bufAC           = 0x1234;
+       deUint32        bufU            = 0x1234;
+       deUint32        bufTF           = 0x1234;
+       int                     maxTFSize       = 0x1234;
+       int                     maxUSize        = 0x1234;
+       int                     uAlignment      = 0x1234;
+
        ctx.glGenBuffers(1, &bufU);
        ctx.glBindBuffer(GL_UNIFORM_BUFFER, bufU);
        ctx.glBufferData(GL_UNIFORM_BUFFER, 16, NULL, GL_STREAM_DRAW);
 
-       deUint32 bufTF = 0x1234;
        ctx.glGenBuffers(1, &bufTF);
        ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufTF);
        ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_STREAM_DRAW);
 
-       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_TRANSFORM_FEEDBACK_BUFFER or GL_UNIFORM_BUFFER.");
+       ctx.glGenBuffers(1, &bufAC);
+       ctx.glBindBuffer(GL_ATOMIC_COUNTER_BUFFER, bufAC);
+       ctx.glBufferData(GL_ATOMIC_COUNTER_BUFFER, 16, NULL, GL_STREAM_DRAW);
+
+       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_ATOMIC_COUNTER_BUFFER, GL_SHADER_STORAGE_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER or GL_UNIFORM_BUFFER.");
        ctx.glBindBufferRange(GL_ARRAY_BUFFER, 0, bufU, 0, 4);
        ctx.expectError(GL_INVALID_ENUM);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_TRANSFORM_FEEDBACK_BUFFER and index is greater than or equal to GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.");
-       int maxTFSize = 0x1234;
        ctx.glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxTFSize);
        ctx.glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, maxTFSize, bufTF, 0, 4);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_UNIFORM_BUFFER and index is greater than or equal to GL_MAX_UNIFORM_BUFFER_BINDINGS.");
-       int maxUSize = 0x1234;
        ctx.glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUSize);
        ctx.glBindBufferRange(GL_UNIFORM_BUFFER, maxUSize, bufU, 0, 4);
        ctx.expectError(GL_INVALID_VALUE);
@@ -344,6 +396,11 @@ void bind_buffer_range (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_VALUE is generated if offset is less than zero.");
+       ctx.glBindBufferRange(GL_UNIFORM_BUFFER, 0, bufU, -1, 0);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
+
        ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_TRANSFORM_FEEDBACK_BUFFER and size or offset are not multiples of 4.");
        ctx.glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, bufTF, 4, 5);
        ctx.expectError(GL_INVALID_VALUE);
@@ -354,30 +411,63 @@ void bind_buffer_range (NegativeTestContext& ctx)
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_UNIFORM_BUFFER and offset is not a multiple of GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT.");
-       int alignment = 0x1234;
-       ctx.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &alignment);
-       ctx.glBindBufferRange(GL_UNIFORM_BUFFER, 0, bufU, alignment+1, 4);
+       ctx.glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uAlignment);
+       ctx.glBindBufferRange(GL_UNIFORM_BUFFER, 0, bufU, uAlignment+1, 4);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               int maxACize    = 0x1234;
+               int maxSSize    = 0x1234;
+               int ssAlignment = 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.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.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();
+       }
+
        ctx.glDeleteBuffers(1, &bufU);
        ctx.glDeleteBuffers(1, &bufTF);
+       ctx.glDeleteBuffers(1, &bufAC);
 }
 
 void bind_buffer_base (NegativeTestContext& ctx)
 {
-       deUint32 bufU = 0x1234;
+       deUint32        bufU            = 0x1234;
+       deUint32        bufTF           = 0x1234;
+       int                     maxUSize        = 0x1234;
+       int                     maxTFSize       = 0x1234;
+
        ctx.glGenBuffers(1, &bufU);
        ctx.glBindBuffer(GL_UNIFORM_BUFFER, bufU);
        ctx.glBufferData(GL_UNIFORM_BUFFER, 16, NULL, GL_STREAM_DRAW);
 
-       deUint32 bufTF = 0x1234;
        ctx.glGenBuffers(1, &bufTF);
        ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, bufTF);
        ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 16, NULL, GL_STREAM_DRAW);
        ctx.expectError(GL_NO_ERROR);
 
-       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_TRANSFORM_FEEDBACK_BUFFER or GL_UNIFORM_BUFFER.");
+       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_ATOMIC_COUNTER_BUFFER, GL_SHADER_STORAGE_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER or GL_UNIFORM_BUFFER.");
        ctx.glBindBufferBase(-1, 0, bufU);
        ctx.expectError(GL_INVALID_ENUM);
        ctx.glBindBufferBase(GL_ARRAY_BUFFER, 0, bufU);
@@ -385,28 +475,45 @@ void bind_buffer_base (NegativeTestContext& ctx)
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_UNIFORM_BUFFER and index is greater than or equal to GL_MAX_UNIFORM_BUFFER_BINDINGS.");
-       int maxUSize = 0x1234;
        ctx.glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUSize);
        ctx.glBindBufferBase(GL_UNIFORM_BUFFER, maxUSize, bufU);
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_TRANSFORM_FEEDBACK_BUFFER andindex is greater than or equal to GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.");
-       int maxTFSize = 0x1234;
        ctx.glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxTFSize);
        ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, maxTFSize, bufTF);
        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);
 }
 
 void clear_bufferiv (NegativeTestContext& ctx)
 {
-       std::vector<int>                data(32*32);
-       deUint32                                fbo = 0x1234;
-       deUint32                                texture = 0x1234;
+       std::vector<int>        data                    (32*32);
+       deUint32                        fbo                             = 0x1234;
+       deUint32                        texture                 = 0x1234;
+       int                                     maxDrawBuffers  = 0x1234;
 
        ctx.glGenTextures                       (1, &texture);
        ctx.glBindTexture                       (GL_TEXTURE_2D, texture);
@@ -418,40 +525,45 @@ void clear_bufferiv (NegativeTestContext& ctx)
        ctx.expectError                         (GL_NO_ERROR);
 
        ctx.beginSection("GL_INVALID_ENUM is generated if buffer is not an accepted value.");
-       ctx.glClearBufferiv(-1, 0, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferiv(GL_FRAMEBUFFER, 0, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
+       ctx.glClearBufferiv                     (-1, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.glClearBufferiv                     (GL_FRAMEBUFFER, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR, GL_FRONT, GL_BACK, GL_LEFT, GL_RIGHT, or GL_FRONT_AND_BACK and drawBuffer is greater than or equal to GL_MAX_DRAW_BUFFERS.");
-       int maxDrawBuffers = 0x1234;
-       ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
-       ctx.glClearBufferiv(GL_COLOR, maxDrawBuffers, &data[0]);
-       ctx.expectError(GL_INVALID_VALUE);
+       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is GL_DEPTH or GL_DEPTH_STENCIL.");
+       ctx.glClearBufferiv                     (GL_DEPTH, 1, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.glClearBufferiv                     (GL_DEPTH_STENCIL, 1, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is GL_DEPTH or GL_DEPTH_STENCIL.");
-       ctx.glClearBufferiv(GL_DEPTH, 1, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferiv(GL_DEPTH_STENCIL, 1, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
+       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR or GL_STENCIL and drawBuffer is greater than or equal to GL_MAX_DRAW_BUFFERS.");
+       ctx.glGetIntegerv                       (GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
+       ctx.glClearBufferiv                     (GL_COLOR, maxDrawBuffers, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR or GL_STENCIL and drawBuffer is negative.");
+       ctx.glClearBufferiv                     (GL_COLOR, -1, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_STENCIL and drawBuffer is not zero.");
-       ctx.glClearBufferiv(GL_STENCIL, 1, &data[0]);
-       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glClearBufferiv                     (GL_STENCIL, 1, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
        ctx.endSection();
 
-       ctx.glDeleteFramebuffers(1, &fbo);
-       ctx.glDeleteTextures(1, &texture);
+       ctx.glDeleteFramebuffers        (1, &fbo);
+       ctx.glDeleteTextures            (1, &texture);
 }
 
 void clear_bufferuiv (NegativeTestContext& ctx)
 {
-       std::vector<deUint32>   data(32*32);
-       deUint32                                fbo = 0x1234;
-       deUint32                                texture = 0x1234;
+       std::vector<deUint32>   data                    (32*32);
+       deUint32                                fbo                             = 0x1234;
+       deUint32                                texture                 = 0x1234;
+       int                                             maxDrawBuffers  = 0x1234;
 
        ctx.glGenTextures                       (1, &texture);
        ctx.glBindTexture                       (GL_TEXTURE_2D, texture);
@@ -462,38 +574,43 @@ void clear_bufferuiv (NegativeTestContext& ctx)
        ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
        ctx.expectError                         (GL_NO_ERROR);
 
-       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is not an accepted value.");
-       ctx.glClearBufferuiv(-1, 0, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferuiv(GL_FRAMEBUFFER, 0, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
+       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is not GL_COLOR.");
+       ctx.glClearBufferuiv            (-1, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.glClearBufferuiv            (GL_FRAMEBUFFER, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR, GL_FRONT, GL_BACK, GL_LEFT, GL_RIGHT, or GL_FRONT_AND_BACK and drawBuffer is greater than or equal to GL_MAX_DRAW_BUFFERS.");
-       int maxDrawBuffers = 0x1234;
-       ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
-       ctx.glClearBufferuiv(GL_COLOR, maxDrawBuffers, &data[0]);
-       ctx.expectError(GL_INVALID_VALUE);
+       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is GL_DEPTH, GL_STENCIL, or GL_DEPTH_STENCIL.");
+       ctx.glClearBufferuiv            (GL_DEPTH, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.glClearBufferuiv            (GL_STENCIL, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.glClearBufferuiv            (GL_DEPTH_STENCIL, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is GL_DEPTH, GL_STENCIL or GL_DEPTH_STENCIL.");
-       ctx.glClearBufferuiv(GL_DEPTH, 1, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferuiv(GL_STENCIL, 1, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferuiv(GL_DEPTH_STENCIL, 1, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
+       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR and drawBuffer is greater than or equal to GL_MAX_DRAW_BUFFERS.");
+       ctx.glGetIntegerv                       (GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
+       ctx.glClearBufferuiv            (GL_COLOR, maxDrawBuffers, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
        ctx.endSection();
 
-       ctx.glDeleteFramebuffers(1, &fbo);
-       ctx.glDeleteTextures(1, &texture);
+       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR and drawBuffer is negative.");
+       ctx.glClearBufferuiv            (GL_COLOR, -1, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
+       ctx.endSection();
+
+       ctx.glDeleteFramebuffers        (1, &fbo);
+       ctx.glDeleteTextures            (1, &texture);
 }
 
 void clear_bufferfv (NegativeTestContext& ctx)
 {
-       std::vector<float>              data(32*32);
-       deUint32                                fbo = 0x1234;
-       deUint32                                texture = 0x1234;
+       std::vector<float>      data                    (32*32);
+       deUint32                        fbo                             = 0x1234;
+       deUint32                        texture                 = 0x1234;
+       int                             maxDrawBuffers  = 0x1234;
 
        ctx.glGenTextures                       (1, &texture);
        ctx.glBindTexture                       (GL_TEXTURE_2D, texture);
@@ -504,64 +621,65 @@ void clear_bufferfv (NegativeTestContext& ctx)
        ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
        ctx.expectError                         (GL_NO_ERROR);
 
-       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is not an accepted value.");
-       ctx.glClearBufferfv(-1, 0, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferfv(GL_FRAMEBUFFER, 0, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
+       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is not GL_COLOR or GL_DEPTH.");
+       ctx.glClearBufferfv                     (-1, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.glClearBufferfv                     (GL_FRAMEBUFFER, 0, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR, GL_FRONT, GL_BACK, GL_LEFT, GL_RIGHT, or GL_FRONT_AND_BACK and drawBuffer is greater than or equal to GL_MAX_DRAW_BUFFERS.");
-       int maxDrawBuffers = 0x1234;
-       ctx.glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
-       ctx.glClearBufferfv(GL_COLOR, maxDrawBuffers, &data[0]);
-       ctx.expectError(GL_INVALID_VALUE);
+       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is GL_STENCIL or GL_DEPTH_STENCIL.");
+       ctx.glClearBufferfv                     (GL_STENCIL, 1, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.glClearBufferfv                     (GL_DEPTH_STENCIL, 1, &data[0]);
+       ctx.expectError                         (GL_INVALID_ENUM);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is GL_STENCIL or GL_DEPTH_STENCIL.");
-       ctx.glClearBufferfv(GL_STENCIL, 1, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferfv(GL_DEPTH_STENCIL, 1, &data[0]);
-       ctx.expectError(GL_INVALID_ENUM);
+       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR and drawBuffer is greater than or equal to GL_MAX_DRAW_BUFFERS.");
+       ctx.glGetIntegerv                       (GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
+       ctx.glClearBufferfv                     (GL_COLOR, maxDrawBuffers, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_COLOR and drawBuffer is negative.");
+       ctx.glClearBufferfv                     (GL_COLOR, -1, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_DEPTH and drawBuffer is not zero.");
-       ctx.glClearBufferfv(GL_DEPTH, 1, &data[0]);
-       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glClearBufferfv                     (GL_DEPTH, 1, &data[0]);
+       ctx.expectError                         (GL_INVALID_VALUE);
        ctx.endSection();
 
-       ctx.glDeleteFramebuffers(1, &fbo);
-       ctx.glDeleteTextures(1, &texture);
+       ctx.glDeleteFramebuffers        (1, &fbo);
+       ctx.glDeleteTextures            (1, &texture);
 }
 
 void clear_bufferfi (NegativeTestContext& ctx)
 {
-       ctx.beginSection("GL_INVALID_ENUM is generated if buffer is not an accepted value.");
-       ctx.glClearBufferfi(-1, 0, 1.0f, 1);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferfi(GL_FRAMEBUFFER, 0, 1.0f, 1);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.endSection();
-
        ctx.beginSection("GL_INVALID_ENUM is generated if buffer is not GL_DEPTH_STENCIL.");
-       ctx.glClearBufferfi(GL_DEPTH, 0, 1.0f, 1);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferfi(GL_STENCIL, 0, 1.0f, 1);
-       ctx.expectError(GL_INVALID_ENUM);
-       ctx.glClearBufferfi(GL_COLOR, 0, 1.0f, 1);
-       ctx.expectError(GL_INVALID_ENUM);
+       ctx.glClearBufferfi             (-1, 0, 1.0f, 1);
+       ctx.expectError                 (GL_INVALID_ENUM);
+       ctx.glClearBufferfi             (GL_FRAMEBUFFER, 0, 1.0f, 1);
+       ctx.expectError                 (GL_INVALID_ENUM);
+       ctx.glClearBufferfi             (GL_DEPTH, 0, 1.0f, 1);
+       ctx.expectError                 (GL_INVALID_ENUM);
+       ctx.glClearBufferfi             (GL_STENCIL, 0, 1.0f, 1);
+       ctx.expectError                 (GL_INVALID_ENUM);
+       ctx.glClearBufferfi             (GL_COLOR, 0, 1.0f, 1);
+       ctx.expectError                 (GL_INVALID_ENUM);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if buffer is GL_DEPTH_STENCIL and drawBuffer is not zero.");
-       ctx.glClearBufferfi(GL_DEPTH_STENCIL, 1, 1.0f, 1);
-       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glClearBufferfi             (GL_DEPTH_STENCIL, 1, 1.0f, 1);
+       ctx.expectError                 (GL_INVALID_VALUE);
        ctx.endSection();
 }
 
 void copy_buffer_sub_data (NegativeTestContext& ctx)
 {
        deUint32                                buf[2];
-       std::vector<float>              data(32*32);
+       std::vector<float>              data    (32*32);
 
        ctx.glGenBuffers                        (2, buf);
        ctx.glBindBuffer                        (GL_COPY_READ_BUFFER, buf[0]);
@@ -638,16 +756,23 @@ void copy_buffer_sub_data (NegativeTestContext& ctx)
 
 void draw_buffers (NegativeTestContext& ctx)
 {
-       deUint32                                fbo = 0x1234;
-       deUint32                                texture = 0x1234;
-       int                                             maxDrawBuffers = 0x1234;
+       deUint32                                fbo                                     = 0x1234;
+       deUint32                                texture                                 = 0x1234;
+       int                                             maxDrawBuffers                  = 0x1234;
+       int                                             maxColorAttachments             = -1;
+       ctx.glGetIntegerv               (GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
        ctx.glGetIntegerv               (GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
-       std::vector<deUint32>   values(maxDrawBuffers+1);
+       std::vector<deUint32>   values                                  (maxDrawBuffers+1);
+       std::vector<deUint32>   attachments                             (4);
+       std::vector<GLfloat>    data                                    (32*32);
        values[0]                               = GL_NONE;
        values[1]                               = GL_BACK;
        values[2]                               = GL_COLOR_ATTACHMENT0;
        values[3]                               = GL_DEPTH_ATTACHMENT;
-       std::vector<GLfloat>    data(32*32);
+       attachments[0]                  = (glw::GLenum) (GL_COLOR_ATTACHMENT0 + maxColorAttachments);
+       attachments[1]                  = GL_COLOR_ATTACHMENT0;
+       attachments[2]                  = GL_COLOR_ATTACHMENT1;
+       attachments[3]                  = GL_NONE;
 
        ctx.glGenTextures                       (1, &texture);
        ctx.glBindTexture                       (GL_TEXTURE_2D, texture);
@@ -663,6 +788,14 @@ void draw_buffers (NegativeTestContext& ctx)
        ctx.expectError                         (GL_INVALID_ENUM);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_OPERATION is generated if the GL is bound to a draw framebuffer and DrawBuffers is supplied with BACK or COLOR_ATTACHMENTm where m is greater than or equal to the value of MAX_COLOR_ATTACHMENTS.");
+       ctx.glBindFramebuffer           (GL_FRAMEBUFFER, fbo);
+       ctx.glDrawBuffers                       (1, &values[1]);
+       ctx.expectError                         (GL_INVALID_OPERATION);
+       ctx.glDrawBuffers                       (4, &attachments[0]);
+       ctx.expectError                         (GL_INVALID_OPERATION);
+       ctx.endSection();
+
        ctx.beginSection("GL_INVALID_OPERATION is generated if the GL is bound to the default framebuffer and n is not 1.");
        ctx.glBindFramebuffer           (GL_FRAMEBUFFER, 0);
        ctx.glDrawBuffers                       (2, &values[0]);
@@ -679,6 +812,9 @@ void draw_buffers (NegativeTestContext& ctx)
        ctx.glBindFramebuffer           (GL_FRAMEBUFFER, fbo);
        ctx.glDrawBuffers                       (1, &values[1]);
        ctx.expectError                         (GL_INVALID_OPERATION);
+       ctx.glDrawBuffers                       (4, &attachments[0]);
+       ctx.expectError                         (GL_INVALID_OPERATION);
+
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if n is less than 0 or greater than GL_MAX_DRAW_BUFFERS.");
@@ -694,8 +830,8 @@ void draw_buffers (NegativeTestContext& ctx)
 
 void flush_mapped_buffer_range (NegativeTestContext& ctx)
 {
-       deUint32                                buf = 0x1234;
-       std::vector<GLfloat>    data(32);
+       deUint32                                buf             = 0x1234;
+       std::vector<GLfloat>    data    (32);
 
        ctx.glGenBuffers                        (1, &buf);
        ctx.glBindBuffer                        (GL_ARRAY_BUFFER, buf);
@@ -703,6 +839,11 @@ void flush_mapped_buffer_range (NegativeTestContext& ctx)
        ctx.glMapBufferRange            (GL_ARRAY_BUFFER, 0, 16, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
        ctx.expectError                         (GL_NO_ERROR);
 
+       ctx.beginSection("GL_INVALID_ENUM is generated if target is not one of the accepted values.");
+       ctx.glFlushMappedBufferRange(-1, 0, 16);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.endSection();
+
        ctx.beginSection("GL_INVALID_VALUE is generated if offset or length is negative, or if offset + length exceeds the size of the mapping.");
        ctx.glFlushMappedBufferRange(GL_ARRAY_BUFFER, -1, 1);
        ctx.expectError                         (GL_INVALID_VALUE);
@@ -738,8 +879,8 @@ void flush_mapped_buffer_range (NegativeTestContext& ctx)
 
 void map_buffer_range (NegativeTestContext& ctx)
 {
-       deUint32                                buf = 0x1234;
-       std::vector<GLfloat>    data(32);
+       deUint32                                buf             = 0x1234;
+       std::vector<GLfloat>    data    (32);
 
        ctx.glGenBuffers                        (1, &buf);
        ctx.glBindBuffer                        (GL_ARRAY_BUFFER, buf);
@@ -786,8 +927,8 @@ void map_buffer_range (NegativeTestContext& ctx)
        ctx.expectError                         (GL_INVALID_OPERATION);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_OPERATION is generated if ");
-       ctx.glMapBufferRange            (GL_ARRAY_BUFFER, 0, 16, GL_MAP_INVALIDATE_RANGE_BIT);
+       ctx.beginSection("GL_INVALID_OPERATION is generated if length is 0");
+       ctx.glMapBufferRange            (GL_ARRAY_BUFFER, 0, 0, GL_MAP_READ_BIT);
        ctx.expectError                         (GL_INVALID_OPERATION);
        ctx.endSection();
 
@@ -883,8 +1024,8 @@ void read_buffer (NegativeTestContext& ctx)
 
 void unmap_buffer (NegativeTestContext& ctx)
 {
-       deUint32                                buf = 0x1234;
-       std::vector<GLfloat>    data(32);
+       deUint32                                buf             = 0x1234;
+       std::vector<GLfloat>    data    (32);
 
        ctx.glGenBuffers                        (1, &buf);
        ctx.glBindBuffer                        (GL_ARRAY_BUFFER, buf);
@@ -902,7 +1043,7 @@ void unmap_buffer (NegativeTestContext& ctx)
 
 void bind_framebuffer (NegativeTestContext& ctx)
 {
-       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_FRAMEBUFFER.");
+       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, or GL_FRAMEBUFFER.");
        ctx.glBindFramebuffer(-1, 0);
        ctx.expectError(GL_INVALID_ENUM);
        ctx.glBindFramebuffer(GL_RENDERBUFFER, 0);
@@ -922,7 +1063,7 @@ void bind_renderbuffer (NegativeTestContext& ctx)
 
 void check_framebuffer_status (NegativeTestContext& ctx)
 {
-       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_FRAMEBUFFER.");
+       ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER, or GL_FRAMEBUFFER..");
        ctx.glCheckFramebufferStatus(-1);
        ctx.expectError(GL_INVALID_ENUM);
        ctx.glCheckFramebufferStatus(GL_RENDERBUFFER);
@@ -975,6 +1116,11 @@ void framebuffer_renderbuffer (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_ENUM);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_ENUM is generated if attachment is not one of the accepted tokens.");
+       ctx.glFramebufferRenderbuffer(GL_FRAMEBUFFER, -1, GL_RENDERBUFFER, 0);
+       ctx.expectError(GL_INVALID_ENUM);
+       ctx.endSection();
+
        ctx.beginSection("GL_INVALID_ENUM is generated if renderbuffertarget is not GL_RENDERBUFFER.");
        ctx.glBindRenderbuffer(GL_RENDERBUFFER, rbo);
        ctx.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -1, rbo);
@@ -997,13 +1143,61 @@ void framebuffer_renderbuffer (NegativeTestContext& ctx)
        ctx.glDeleteFramebuffers(1, &fbo);
 }
 
+void framebuffer_texture (NegativeTestContext& ctx)
+{
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               GLuint fbo = 0x1234;
+               GLuint texture[] = {0x1234, 0x1234};
+
+               ctx.glGenFramebuffers(1, &fbo);
+               ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+               ctx.glGenTextures(2, texture);
+               ctx.glBindTexture(GL_TEXTURE_2D, texture[0]);
+               ctx.glBindTexture(GL_TEXTURE_BUFFER, texture[1]);
+               ctx.expectError(GL_NO_ERROR);
+
+               ctx.beginSection("GL_INVALID_ENUM is generated if target is not one of the accepted tokens.");
+               ctx.glFramebufferTexture(-1, GL_COLOR_ATTACHMENT0, texture[0], 0);
+               ctx.expectError(GL_INVALID_ENUM);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_ENUM is generated if attachment is not one of the accepted tokens.");
+               ctx.glFramebufferTexture(GL_FRAMEBUFFER, -1, texture[0], 0);
+               ctx.expectError(GL_INVALID_ENUM);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if texture is neither 0 nor the name of an existing texture object.");
+               ctx.glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -1, 0);
+               ctx.expectError(GL_INVALID_VALUE);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if zero is bound to target.");
+               ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
+               ctx.glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 0, 0);
+               ctx.expectError(GL_INVALID_OPERATION);
+               ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated by if texture is a buffer texture.");
+               ctx.glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture[1], 0);
+               ctx.expectError(GL_INVALID_OPERATION);
+               ctx.endSection();
+
+               ctx.glDeleteFramebuffers(1, &fbo);
+               ctx.glDeleteBuffers(2, texture);
+       }
+}
+
 void framebuffer_texture2d (NegativeTestContext& ctx)
 {
-       GLuint fbo = 0x1234;
-       GLuint tex2D = 0x1234;
-       GLuint texCube = 0x1234;
-       GLint maxTexSize = 0x1234;
-       GLint maxTexCubeSize = 0x1234;
+       GLuint  fbo                             = 0x1234;
+       GLuint  tex2D                   = 0x1234;
+       GLuint  texCube                 = 0x1234;
+       GLuint  tex2DMS                 = 0x1234;
+       GLint   maxTexSize              = 0x1234;
+       GLint   maxTexCubeSize  = 0x1234;
+       int             maxSize                 = 0x1234;
 
        ctx.glGenFramebuffers(1, &fbo);
        ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
@@ -1011,6 +1205,8 @@ void framebuffer_texture2d (NegativeTestContext& ctx)
        ctx.glBindTexture(GL_TEXTURE_2D, tex2D);
        ctx.glGenTextures(1, &texCube);
        ctx.glBindTexture(GL_TEXTURE_CUBE_MAP, texCube);
+       ctx.glGenTextures(1, &tex2DMS);
+       ctx.glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, tex2DMS);
        ctx.glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
        ctx.glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxTexCubeSize);
        ctx.expectError(GL_NO_ERROR);
@@ -1025,8 +1221,12 @@ void framebuffer_texture2d (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_ENUM);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_ENUM is generated if attachment is not an accepted token.");
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, -1, GL_TEXTURE_2D, tex2D, 0);
+       ctx.expectError(GL_INVALID_ENUM);
+       ctx.endSection();
+
        ctx.beginSection("GL_INVALID_VALUE is generated if level is less than 0 or larger than log_2 of maximum texture size.");
-       int maxSize = 0x1234;
        ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, -1);
        ctx.expectError(GL_INVALID_VALUE);
        maxSize = deLog2Floor32(maxTexSize) + 1;
@@ -1037,6 +1237,19 @@ void framebuffer_texture2d (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_VALUE);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_VALUE is generated if level is larger than maximum texture size.");
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, maxTexSize + 1);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2D, -1);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, texCube, maxTexCubeSize + 1);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, texCube, -1);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex2D, 1);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
+
        ctx.beginSection("GL_INVALID_OPERATION is generated if texture is neither 0 nor the name of an existing texture object.");
        ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, -1, 0);
        ctx.expectError(GL_INVALID_OPERATION);
@@ -1045,11 +1258,15 @@ void framebuffer_texture2d (NegativeTestContext& ctx)
        ctx.beginSection("GL_INVALID_OPERATION is generated if textarget and texture are not compatible.");
        ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X, tex2D, 0);
        ctx.expectError(GL_INVALID_OPERATION);
-       ctx.glDeleteTextures(1, &tex2D);
-
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, tex2D, 0);
+       ctx.expectError(GL_INVALID_OPERATION);
        ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texCube, 0);
        ctx.expectError(GL_INVALID_OPERATION);
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2DMS, 0);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.glDeleteTextures(1, &tex2D);
        ctx.glDeleteTextures(1, &texCube);
+       ctx.glDeleteTextures(1, &tex2DMS);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_OPERATION is generated if zero is bound to target.");
@@ -1058,12 +1275,27 @@ void framebuffer_texture2d (NegativeTestContext& ctx)
        ctx.expectError(GL_INVALID_OPERATION);
        ctx.endSection();
 
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               GLuint texBuf = 0x1234;
+               ctx.beginSection("GL_INVALID_OPERATION error is generated if texture is the name of a buffer texture.");
+               ctx.glGenTextures(1, &texBuf);
+               ctx.glBindTexture(GL_TEXTURE_BUFFER, texBuf);
+               ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+               ctx.expectError(GL_NO_ERROR);
+               ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texBuf, 0);
+               ctx.expectError(GL_INVALID_OPERATION);
+               ctx.endSection();
+       }
+
        ctx.glDeleteFramebuffers(1, &fbo);
 }
 
 void renderbuffer_storage (NegativeTestContext& ctx)
 {
-       deUint32                                        rbo = 0x1234;
+       deUint32        rbo             = 0x1234;
+       GLint           maxSize = 0x1234;
+
        ctx.glGenRenderbuffers          (1, &rbo);
        ctx.glBindRenderbuffer          (GL_RENDERBUFFER, rbo);
 
@@ -1078,13 +1310,13 @@ void renderbuffer_storage (NegativeTestContext& ctx)
        ctx.glRenderbufferStorage       (GL_RENDERBUFFER, -1, 1, 1);
        ctx.expectError                         (GL_INVALID_ENUM);
 
-       if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_half_float")) // GL_EXT_color_buffer_half_float disables error
+       if (!ctx.isExtensionSupported("GL_EXT_color_buffer_half_float")) // GL_EXT_color_buffer_half_float disables error
        {
                ctx.glRenderbufferStorage       (GL_RENDERBUFFER, GL_RGB16F, 1, 1);
                ctx.expectError                         (GL_INVALID_ENUM);
        }
 
-       if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_render_snorm")) // GL_EXT_render_snorm disables error
+       if (!ctx.isExtensionSupported("GL_EXT_render_snorm")) // GL_EXT_render_snorm disables error
        {
                ctx.glRenderbufferStorage       (GL_RENDERBUFFER, GL_RGBA8_SNORM, 1, 1);
                ctx.expectError                         (GL_INVALID_ENUM);
@@ -1102,7 +1334,6 @@ void renderbuffer_storage (NegativeTestContext& ctx)
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if width or height is greater than GL_MAX_RENDERBUFFER_SIZE.");
-       GLint maxSize = 0x1234;
        ctx.glGetIntegerv                       (GL_MAX_RENDERBUFFER_SIZE, &maxSize);
        ctx.glRenderbufferStorage       (GL_RENDERBUFFER, GL_RGBA4, 1, maxSize+1);
        ctx.expectError                         (GL_INVALID_VALUE);
@@ -1120,7 +1351,9 @@ void blit_framebuffer (NegativeTestContext& ctx)
        deUint32                                        fbo[2];
        deUint32                                        rbo[2];
        deUint32                                        texture[2];
+       deUint32                                        blankFrameBuffer;
 
+       ctx.glGenFramebuffers           (1, &blankFrameBuffer);
        ctx.glGenFramebuffers           (2, fbo);
        ctx.glGenTextures                       (2, texture);
        ctx.glGenRenderbuffers          (2, rbo);
@@ -1146,6 +1379,16 @@ void blit_framebuffer (NegativeTestContext& ctx)
        ctx.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
        ctx.expectError                         (GL_NO_ERROR);
 
+       ctx.beginSection("GL_INVALID_VALUE is generated if mask contains any bits other than GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT, or GL_STENCIL_BUFFER_BIT.");
+       ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, 1, GL_NEAREST);
+       ctx.expectError                         (GL_INVALID_VALUE);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_ENUM is generated if filter is not GL_LINEAR or GL_NEAREST.");
+       ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, GL_COLOR_BUFFER_BIT, 0);
+       ctx.expectError                         (GL_INVALID_ENUM);
+       ctx.endSection();
+
        ctx.beginSection("GL_INVALID_OPERATION is generated if mask contains any of the GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT and filter is not GL_NEAREST.");
        ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_LINEAR);
        ctx.expectError                         (GL_INVALID_OPERATION);
@@ -1201,8 +1444,52 @@ void blit_framebuffer (NegativeTestContext& ctx)
        ctx.expectError                         (GL_INVALID_OPERATION);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_FRAMEBUFFER_OPERATION is generated if the read or draw framebuffer is not framebuffer complete.");
+       ctx.glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+       ctx.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+       ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, 0, GL_NEAREST);
+       ctx.expectError                         (GL_NO_ERROR);
+       ctx.getLog() << TestLog::Message << "// incomplete read framebuffer" << TestLog::EndMessage;
+       ctx.glBindFramebuffer           (GL_READ_FRAMEBUFFER, blankFrameBuffer);
+       ctx.glBindFramebuffer           (GL_DRAW_FRAMEBUFFER, fbo[1]);
+       TCU_CHECK(ctx.glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE);
+       TCU_CHECK(ctx.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+       ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, 0, GL_NEAREST);
+       ctx.expectError                         (GL_INVALID_FRAMEBUFFER_OPERATION);
+       ctx.getLog() << TestLog::Message << "// incomplete draw framebuffer" << TestLog::EndMessage;
+       ctx.glBindFramebuffer           (GL_READ_FRAMEBUFFER, fbo[1]);
+       ctx.glBindFramebuffer           (GL_DRAW_FRAMEBUFFER, blankFrameBuffer);
+       TCU_CHECK(ctx.glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
+       TCU_CHECK(ctx.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE);
+       ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, 0, GL_NEAREST);
+       ctx.expectError                         (GL_INVALID_FRAMEBUFFER_OPERATION);
+       ctx.getLog() << TestLog::Message << "// incomplete read and draw framebuffer" << TestLog::EndMessage;
+       ctx.glBindFramebuffer           (GL_READ_FRAMEBUFFER, blankFrameBuffer);
+       ctx.glBindFramebuffer           (GL_DRAW_FRAMEBUFFER, blankFrameBuffer);
+       TCU_CHECK(ctx.glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE);
+       TCU_CHECK(ctx.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE);
+       ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, 0, GL_NEAREST);
+       ctx.expectError                         (GL_INVALID_FRAMEBUFFER_OPERATION);
+       // restore
+       ctx.glBindFramebuffer           (GL_READ_FRAMEBUFFER, fbo[0]);
+       ctx.glCheckFramebufferStatus(GL_READ_FRAMEBUFFER);
+       ctx.glBindFramebuffer           (GL_DRAW_FRAMEBUFFER, fbo[1]);
+       ctx.glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if the source and destination buffers are identical.");
+       ctx.glBindFramebuffer           (GL_DRAW_FRAMEBUFFER, fbo[0]);
+       ctx.expectError                         (GL_NO_ERROR);
+       ctx.glBlitFramebuffer           (0, 0, 16, 16, 0, 0, 16, 16, 0, GL_NEAREST);
+       ctx.expectError                         (GL_INVALID_OPERATION);
+       // restore
+       ctx.glBindFramebuffer           (GL_DRAW_FRAMEBUFFER, fbo[1]);
+       ctx.endSection();
+
        ctx.glBindFramebuffer           (GL_FRAMEBUFFER, 0);
+       ctx.glBindRenderbuffer          (GL_RENDERBUFFER, 0);
        ctx.glDeleteFramebuffers        (2, fbo);
+       ctx.glDeleteFramebuffers        (1, &blankFrameBuffer);
        ctx.glDeleteTextures            (2, texture);
        ctx.glDeleteRenderbuffers       (2, rbo);
 }
@@ -1226,7 +1513,7 @@ void blit_framebuffer_multisample (NegativeTestContext& ctx)
 
        ctx.expectError                                         (GL_NO_ERROR);
 
-       if (!ctx.getContextInfo().isExtensionSupported("GL_NV_framebuffer_multisample"))
+       if (!ctx.isExtensionSupported("GL_NV_framebuffer_multisample"))
        {
                ctx.beginSection("GL_INVALID_OPERATION is generated if the value of GL_SAMPLE_BUFFERS for the draw buffer is greater than zero.");
                ctx.glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 32, 32);
@@ -1257,10 +1544,22 @@ void blit_framebuffer_multisample (NegativeTestContext& ctx)
 
 void framebuffer_texture_layer (NegativeTestContext& ctx)
 {
-       deUint32                                                fbo = 0x1234;
-       deUint32                                                tex3D;
-       deUint32                                                tex2DArray;
-       deUint32                                                tex2D;
+       deUint32                                                fbo                                     = 0x1234;
+       deUint32                                                tex3D                           = 0x1234;
+       deUint32                                                tex2DArray                      = 0x1234;
+       deUint32                                                tex2D                           = 0x1234;
+       deUint32                                                tex2DMSArray            = 0x1234;
+       deUint32                                                texCube                         = 0x1234;
+       deUint32                                                texBuffer                       = 0x1234;
+       int                                                             max3DTexSize            = 0x1234;
+       int                                                             maxTexSize                      = 0x1234;
+       int                                                             maxArrayTexLayers       = 0x1234;
+       int                                                             maxCubeTexSize          = 0x1234;
+       int                                                     log2Max3DTexSize        = 0x1234;
+       int                                                     log2MaxTexSize          = 0x1234;
+
+       ctx.glGetIntegerv                               (GL_MAX_3D_TEXTURE_SIZE, &max3DTexSize);
+       ctx.glGetIntegerv                               (GL_MAX_TEXTURE_SIZE, &maxTexSize);
 
        ctx.glGenFramebuffers                   (1, &fbo);
        ctx.glGenTextures                               (1, &tex3D);
@@ -1291,7 +1590,7 @@ void framebuffer_texture_layer (NegativeTestContext& ctx)
        ctx.expectError                                 (GL_INVALID_ENUM);
        ctx.endSection();
 
-       ctx.beginSection("GL_INVALID_OPERATION is generated if texture is non-zero and not the name of a 3D texture or 2D array texture.");
+       ctx.beginSection("GL_INVALID_OPERATION is generated if texture is non-zero and not the name of a 3D texture or 2D array texture, 2D multisample array texture or cube map array texture.");
        ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -1, 0, 0);
        ctx.expectError                                 (GL_INVALID_OPERATION);
        ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2D, 0, 0);
@@ -1304,14 +1603,11 @@ void framebuffer_texture_layer (NegativeTestContext& ctx)
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if texture is not zero and layer is greater than GL_MAX_3D_TEXTURE_SIZE-1 for a 3D texture.");
-       int                                                     max3DTexSize = 0x1234;
-       ctx.glGetIntegerv                               (GL_MAX_3D_TEXTURE_SIZE, &max3DTexSize);
        ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, 0, max3DTexSize);
        ctx.expectError                                 (GL_INVALID_VALUE);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if texture is not zero and layer is greater than GL_MAX_ARRAY_TEXTURE_LAYERS-1 for a 2D array texture.");
-       int                                                     maxArrayTexLayers = 0x1234;
        ctx.glGetIntegerv                               (GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTexLayers);
        ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, 0, maxArrayTexLayers);
        ctx.expectError                                 (GL_INVALID_VALUE);
@@ -1321,8 +1617,58 @@ void framebuffer_texture_layer (NegativeTestContext& ctx)
        ctx.glBindFramebuffer                   (GL_FRAMEBUFFER, 0);
        ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, 0, 1);
        ctx.expectError                                 (GL_INVALID_OPERATION);
+       ctx.glBindFramebuffer                   (GL_FRAMEBUFFER, fbo);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if texture is a 3D texture and level is less than 0 or greater than log2 of the value of GL_MAX_3D_TEXTURE_SIZE.");
+       log2Max3DTexSize        = deLog2Floor32(max3DTexSize);
+       ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, -1, max3DTexSize - 1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex3D, log2Max3DTexSize + 1, max3DTexSize - 1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_VALUE is generated if texture is a 2D array texture and layer is less than 0 or greater than log2 of the value of GL_MAX_TEXTURE_SIZE.");
+       log2MaxTexSize          = deLog2Floor32(maxTexSize);
+       ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, -1, maxArrayTexLayers - 1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DArray, log2MaxTexSize + 1, maxArrayTexLayers - 1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.endSection();
+
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               ctx.glGetIntegerv                               (GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTexSize);
+               ctx.glGenTextures                               (1, &tex2DMSArray);
+               ctx.glGenTextures                               (1, &texCube);
+               ctx.glGenTextures                               (1, &texBuffer);
+               ctx.glBindTexture                               (GL_TEXTURE_2D_MULTISAMPLE_ARRAY, tex2DMSArray);
+               ctx.glBindTexture                               (GL_TEXTURE_CUBE_MAP, texCube);
+               ctx.glBindTexture                               (GL_TEXTURE_BUFFER, texBuffer);
+               ctx.expectError                                 (GL_NO_ERROR);
+
+               ctx.beginSection("GL_INVALID_VALUE is generated if texture is a 2D multisample array texture and layer not 0.");
+               ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DMSArray, -1, 0);
+               ctx.expectError                                 (GL_INVALID_VALUE);
+               ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2DMSArray, 1, 0);
+               ctx.expectError                                 (GL_INVALID_VALUE);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_VALUE is generated if texture is a cube map array texture and layer is larger than the value of MAX_CUBE_MAP_TEXTURE_SIZE-1 minus one.");
+               ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texCube, 0, maxCubeTexSize);
+               ctx.expectError                                 (GL_INVALID_VALUE);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if texture is the name of a buffer texture.");
+               ctx.glFramebufferTextureLayer   (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texBuffer, 0, 0);
+               ctx.expectError                                 (GL_INVALID_OPERATION);
+               ctx.endSection();
+
+               ctx.glDeleteTextures                    (1, &tex2DMSArray);
+               ctx.glDeleteTextures                    (1, &texCube);
+               ctx.glDeleteTextures                    (1, &texBuffer);
+       }
+
        ctx.glDeleteTextures            (1, &tex3D);
        ctx.glDeleteTextures            (1, &tex2DArray);
        ctx.glDeleteTextures            (1, &tex2D);
@@ -1331,13 +1677,15 @@ void framebuffer_texture_layer (NegativeTestContext& ctx)
 
 void invalidate_framebuffer (NegativeTestContext& ctx)
 {
-       deUint32                                        fbo = 0x1234;
-       deUint32                                        texture = 0x1234;
-       deUint32                                        attachments[2];
-       int                                                     maxColorAttachments = 0x1234;
+       deUint32        attachments[3];
+       deUint32        fbo                             = 0x1234;
+       deUint32        texture                         = 0x1234;
+       int                     maxColorAttachments = 0x1234;
+
        ctx.glGetIntegerv                               (GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
-       attachments[0]                          = GL_COLOR_ATTACHMENT0;
-       attachments[1]                          = GL_COLOR_ATTACHMENT0 + maxColorAttachments;
+       attachments[0]                                  = GL_COLOR_ATTACHMENT0;
+       attachments[1]                                  = GL_COLOR_ATTACHMENT0 + maxColorAttachments;
+       attachments[2]                                  = GL_DEPTH_STENCIL_ATTACHMENT;
 
        ctx.glGenFramebuffers                   (1, &fbo);
        ctx.glGenTextures                               (1, &texture);
@@ -1360,19 +1708,33 @@ void invalidate_framebuffer (NegativeTestContext& ctx)
        ctx.expectError                                 (GL_INVALID_OPERATION);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_VALUE is generated if numAttachments is negative.");
+       ctx.glInvalidateFramebuffer             (GL_FRAMEBUFFER, -1, &attachments[0]);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_ENUM is generated if the default framebuffer is bound to target and any elements of attachments are not one of the accepted attachments.");
+       ctx.glBindFramebuffer                   (GL_FRAMEBUFFER, 0);
+       ctx.glInvalidateFramebuffer             (GL_FRAMEBUFFER, 1, &attachments[2]);
+       ctx.expectError                                 (GL_INVALID_ENUM);
+       ctx.endSection();
+
+
        ctx.glDeleteTextures            (1, &texture);
        ctx.glDeleteFramebuffers        (1, &fbo);
 }
 
 void invalidate_sub_framebuffer (NegativeTestContext& ctx)
 {
-       deUint32                                        fbo = 0x1234;
-       deUint32                                        texture = 0x1234;
-       deUint32                                        attachments[2];
-       int                                                     maxColorAttachments = 0x1234;
+       deUint32        attachments[3];
+       deUint32        fbo                                     = 0x1234;
+       deUint32        texture                         = 0x1234;
+       int                     maxColorAttachments     = 0x1234;
+
        ctx.glGetIntegerv                               (GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
-       attachments[0]                          = GL_COLOR_ATTACHMENT0;
-       attachments[1]                          = GL_COLOR_ATTACHMENT0 + maxColorAttachments;
+       attachments[0]                                  = GL_COLOR_ATTACHMENT0;
+       attachments[1]                                  = GL_COLOR_ATTACHMENT0 + maxColorAttachments;
+       attachments[2]                                  = GL_DEPTH_STENCIL_ATTACHMENT;
 
        ctx.glGenFramebuffers                   (1, &fbo);
        ctx.glGenTextures                               (1, &texture);
@@ -1395,15 +1757,39 @@ void invalidate_sub_framebuffer (NegativeTestContext& ctx)
        ctx.expectError                                 (GL_INVALID_OPERATION);
        ctx.endSection();
 
+       ctx.beginSection("GL_INVALID_VALUE is generated if numAttachments, width, or heigh is negative.");
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, -1, &attachments[0], 0, 0, 16, 16);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, -1, &attachments[0], 0, 0, -1, 16);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, -1, &attachments[0], 0, 0, 16, -1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, -1, &attachments[0], 0, 0, -1, -1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, 1, &attachments[0], 0, 0, -1, 16);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, 1, &attachments[0], 0, 0, 16, -1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, 1, &attachments[0], 0, 0, -1, -1);
+       ctx.expectError                                 (GL_INVALID_VALUE);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_ENUM is generated if the default framebuffer is bound to target and any elements of attachments are not one of the accepted attachments.");
+       ctx.glBindFramebuffer                   (GL_FRAMEBUFFER, 0);
+       ctx.glInvalidateSubFramebuffer  (GL_FRAMEBUFFER, 1, &attachments[2], 0, 0, 16, 16);
+       ctx.expectError                                 (GL_INVALID_ENUM);
+       ctx.endSection();
+
        ctx.glDeleteTextures            (1, &texture);
        ctx.glDeleteFramebuffers        (1, &fbo);
 }
 
 void renderbuffer_storage_multisample (NegativeTestContext& ctx)
 {
-       deUint32                                                        rbo = 0x1234;
-       int                                                                     maxSamplesSupportedRGBA4 = -1;
-       int                                                                     maxSamplesSupportedRGBA8UI = -1;
+       deUint32        rbo                                                     = 0x1234;
+       int                     maxSamplesSupportedRGBA4        = -1;
+       int                     maxSamplesSupportedRGBA8UI      = -1;
+       GLint           maxSize                                         = 0x1234;
 
        ctx.glGetInternalformativ                               (GL_RENDERBUFFER, GL_RGBA4, GL_SAMPLES, 1, &maxSamplesSupportedRGBA4);
        ctx.glGetInternalformativ                               (GL_RENDERBUFFER, GL_RGBA8UI, GL_SAMPLES, 1, &maxSamplesSupportedRGBA8UI);
@@ -1427,13 +1813,13 @@ void renderbuffer_storage_multisample (NegativeTestContext& ctx)
        ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, 2, -1, 1, 1);
        ctx.expectError                                                 (GL_INVALID_ENUM);
 
-       if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_color_buffer_half_float")) // GL_EXT_color_buffer_half_float disables error
+       if (!ctx.isExtensionSupported("GL_EXT_color_buffer_half_float")) // GL_EXT_color_buffer_half_float disables error
        {
                ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, 2, GL_RGB16F, 1, 1);
                ctx.expectError                                                 (GL_INVALID_ENUM);
        }
 
-       if (!ctx.getContextInfo().isExtensionSupported("GL_EXT_render_snorm")) // GL_EXT_render_snorm disables error
+       if (!ctx.isExtensionSupported("GL_EXT_render_snorm")) // GL_EXT_render_snorm disables error
        {
                ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, 2, GL_RGBA8_SNORM, 1, 1);
                ctx.expectError                                                 (GL_INVALID_ENUM);
@@ -1453,10 +1839,17 @@ void renderbuffer_storage_multisample (NegativeTestContext& ctx)
        ctx.expectError                                                 (GL_INVALID_VALUE);
        ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, 2, GL_RGBA4, -1, -1);
        ctx.expectError                                                 (GL_INVALID_VALUE);
+       ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, -1, GL_RGBA4, 1, 1);
+       ctx.expectError                                                 (GL_INVALID_VALUE);
+       ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, -1, GL_RGBA4, -1, 1);
+       ctx.expectError                                                 (GL_INVALID_VALUE);
+       ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, -1, GL_RGBA4, 1, -1);
+       ctx.expectError                                                 (GL_INVALID_VALUE);
+       ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, -1, GL_RGBA4, -1, -1);
+       ctx.expectError                                                 (GL_INVALID_VALUE);
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_VALUE is generated if width or height is greater than GL_MAX_RENDERBUFFER_SIZE.");
-       GLint maxSize = 0x1234;
        ctx.glGetIntegerv                                               (GL_MAX_RENDERBUFFER_SIZE, &maxSize);
        ctx.glRenderbufferStorageMultisample    (GL_RENDERBUFFER, 4, GL_RGBA4, 1, maxSize+1);
        ctx.expectError                                                 (GL_INVALID_VALUE);
@@ -1469,48 +1862,171 @@ void renderbuffer_storage_multisample (NegativeTestContext& ctx)
        ctx.glDeleteRenderbuffers(1, &rbo);
 }
 
+void copy_image_sub_data (NegativeTestContext& ctx)
+{
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               deUint32                                        texture[5];
+               deUint32                                        rbo = 0x1234;
+
+               ctx.glGenTextures                       (5, texture);
+               ctx.glGenRenderbuffers          (1, &rbo);
+               ctx.glBindRenderbuffer          (GL_RENDERBUFFER, rbo);
+
+               ctx.glBindTexture                       (GL_TEXTURE_2D, texture[0]);
+               ctx.glTexParameteri                     (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+               ctx.glTexParameteri                     (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+               ctx.glTexImage2D                        (GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+               ctx.glRenderbufferStorage       (GL_RENDERBUFFER, GL_RGBA8, 32, 32);
+               ctx.glBindTexture                       (GL_TEXTURE_2D, texture[1]);
+               ctx.glTexParameteri                     (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+               ctx.glTexParameteri                     (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+               ctx.glTexImage2D                        (GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+               ctx.expectError                         (GL_NO_ERROR);
+
+               ctx.glBindTexture                       (GL_TEXTURE_3D, texture[2]);
+               ctx.glTexParameteri                     (GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+               ctx.glTexParameteri                     (GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+               ctx.glTexImage3D                        (GL_TEXTURE_3D, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+               ctx.expectError                         (GL_NO_ERROR);
+
+               ctx.glBindTexture                       (GL_TEXTURE_3D, texture[3]);
+               ctx.glTexImage3D                        (GL_TEXTURE_3D, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+               ctx.expectError                         (GL_NO_ERROR);
+
+               ctx.glBindTexture                       (GL_TEXTURE_2D, texture[4]);
+               ctx.glTexParameteri                     (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+               ctx.glTexParameteri                     (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+               ctx.glTexImage2D                        (GL_TEXTURE_2D, 0, GL_RGBA32F, 32, 32, 0, GL_RGBA, GL_FLOAT, NULL);
+               ctx.expectError                         (GL_NO_ERROR);
+
+               ctx.beginSection("GL_INVALID_VALUE is generated if srcWidth, srcHeight, or srcDepth is negative.");
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, -1, 1, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 1, -1, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 1, 1, -1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, -1, -1, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, -1, 1, -1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 1, -1, -1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, -1, -1, -1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_VALUE is generated if srcLevel and dstLevel are not valid levels for the corresponding images.");
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 1, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 1, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 1, 0, 0, 0, texture[1], GL_TEXTURE_2D, 1, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, -1, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, -1, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, -1, 0, 0, 0, texture[1], GL_TEXTURE_2D, -1, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (rbo, GL_RENDERBUFFER, -1, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (rbo, GL_RENDERBUFFER, 1, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, rbo, GL_RENDERBUFFER, -1, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, rbo, GL_RENDERBUFFER, 1, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_ENUM is generated if either target does not match the type of the object.");
+               // \note: This could be either:
+               //              1. GL_INVALID_ENUM is generated if either target does not match the type of the object.
+               //              2. GL_INVALID_VALUE is generated if either name does not correspond to a valid renderbuffer or texture object according to the corresponding target parameter.
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_ENUM);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[2], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_ENUM);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_3D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_ENUM);
+               ctx.glCopyImageSubData          (texture[2], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_ENUM);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if either object is a texture and the texture is not complete.");
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[3], GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_OPERATION);
+               ctx.glCopyImageSubData          (texture[3], GL_TEXTURE_3D, 0, 0, 0, 0, texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_OPERATION);
+               ctx.glCopyImageSubData          (texture[3], GL_TEXTURE_3D, 0, 0, 0, 0, texture[3], GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_OPERATION);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_VALUE is generated if the dimensions of either subregion exceeds the boundaries of the corresponding image object.");
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 33, 0, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[1], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 33, 1);
+               ctx.expectError                         (GL_INVALID_VALUE);
+               ctx.endSection();
+
+               ctx.beginSection("GL_INVALID_OPERATION error is generated if the source and destination internal formats are not compatible.");
+               ctx.glCopyImageSubData          (texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, texture[4], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_OPERATION);
+               ctx.glCopyImageSubData          (texture[4], GL_TEXTURE_2D, 0, 0, 0, 0, texture[0], GL_TEXTURE_2D, 0, 0, 0, 0, 0, 0, 1);
+               ctx.expectError                         (GL_INVALID_OPERATION);
+               ctx.endSection();
+
+               ctx.glDeleteTextures            (5, texture);
+               ctx.glDeleteRenderbuffers       (1, &rbo);
+       }
+}
+
 std::vector<FunctionContainer> getNegativeBufferApiTestFunctions ()
 {
-       FunctionContainer funcs[] =
+       const FunctionContainer funcs[] =
        {
-               {bind_buffer,                                           "bind_buffer",                                          "Invalid glBindBuffer() usage"                                    },
-               {delete_buffers,                                        "delete_buffers",                                       "Invalid glDeleteBuffers() usage"                                 },
-               {gen_buffers,                                           "gen_buffers",                                          "Invalid glGenBuffers() usage"                                    },
-               {buffer_data,                                           "buffer_data",                                          "Invalid glBufferData() usage"                                    },
-               {buffer_sub_data,                                       "buffer_sub_data",                                      "Invalid glBufferSubData() usage"                                 },
-               {buffer_sub_data_size_offset,           "buffer_sub_data_size_offset",          "Invalid glBufferSubData() usage"                                 },
-               {clear,                                                         "clear",                                                        "Invalid glClear() usage"                                                 },
-               {read_pixels,                                           "read_pixels",                                          "Invalid glReadPixels() usage"                                    },
-               {read_pixels_format_mismatch,           "read_pixels_format_mismatch",          "Invalid glReadPixels() usage"                                    },
-               {read_pixels_fbo_format_mismatch,       "read_pixels_fbo_format_mismatch",      "Invalid glReadPixels() usage"                                    },
-               {bind_buffer_range,                                     "bind_buffer_range",                            "Invalid glBindBufferRange() usage"                               },
-               {bind_buffer_base,                                      "bind_buffer_base",                                     "Invalid glBindBufferBase() usage"                                },
-               {clear_bufferiv,                                        "clear_bufferiv",                                       "Invalid glClearBufferiv() usage"                                 },
-               {clear_bufferuiv,                                       "clear_bufferuiv",                                      "Invalid glClearBufferuiv() usage"                                },
-               {clear_bufferfv,                                        "clear_bufferfv",                                       "Invalid glClearBufferfv() usage"                                 },
-               {clear_bufferfi,                                        "clear_bufferfi",                                       "Invalid glClearBufferfi() usage"                                 },
-               {copy_buffer_sub_data,                          "copy_buffer_sub_data",                         "Invalid glCopyBufferSubData() usage"                     },
-               {draw_buffers,                                          "draw_buffers",                                         "Invalid glDrawBuffers() usage"                                   },
-               {flush_mapped_buffer_range,                     "flush_mapped_buffer_range",            "Invalid glFlushMappedBufferRange() usage"                },
-               {map_buffer_range,                                      "map_buffer_range",                                     "Invalid glMapBufferRange() usage"                                },
-               {read_buffer,                                           "read_buffer",                                          "Invalid glReadBuffer() usage"                                    },
-               {unmap_buffer,                                          "unmap_buffer",                                         "Invalid glUnmapBuffer() usage"                                   },
-               {bind_framebuffer,                                      "bind_framebuffer",                                     "Invalid glBindFramebuffer() usage"                               },
-               {bind_renderbuffer,                                     "bind_renderbuffer",                            "Invalid glBindRenderbuffer() usage"                      },
-               {check_framebuffer_status,                      "check_framebuffer_status",                     "Invalid glCheckFramebufferStatus() usage"                },
-               {gen_framebuffers,                                      "gen_framebuffers",                                     "Invalid glGenFramebuffers() usage"                               },
-               {gen_renderbuffers,                                     "gen_renderbuffers",                            "Invalid glGenRenderbuffers() usage"                      },
-               {delete_framebuffers,                           "delete_framebuffers",                          "Invalid glDeleteFramebuffers() usage"                    },
-               {delete_renderbuffers,                          "delete_renderbuffers",                         "Invalid glDeleteRenderbuffers() usage"                   },
-               {framebuffer_renderbuffer,                      "framebuffer_renderbuffer",                     "Invalid glFramebufferRenderbuffer() usage"               },
-               {framebuffer_texture2d,                         "framebuffer_texture2d",                        "Invalid glFramebufferTexture2D() usage"                  },
-               {renderbuffer_storage,                          "renderbuffer_storage",                         "Invalid glRenderbufferStorage() usage"                   },
-               {blit_framebuffer,                                      "blit_framebuffer",                                     "Invalid glBlitFramebuffer() usage"                               },
-               {blit_framebuffer_multisample,          "blit_framebuffer_multisample",         "Invalid glBlitFramebuffer() usage"                               },
-               {framebuffer_texture_layer,                     "framebuffer_texture_layer",            "Invalid glFramebufferTextureLayer() usage"               },
-               {invalidate_framebuffer,                        "invalidate_framebuffer",                       "Invalid glInvalidateFramebuffer() usage"                 },
-               {invalidate_sub_framebuffer,            "invalidate_sub_framebuffer",           "Invalid glInvalidateSubFramebuffer() usage"      },
-               {renderbuffer_storage_multisample,      "renderbuffer_storage_multisample",     "Invalid glRenderbufferStorageMultisample() usage"},
+               {bind_buffer,                                           "bind_buffer",                                          "Invalid glBindBuffer() usage"                                          },
+               {delete_buffers,                                        "delete_buffers",                                       "Invalid glDeleteBuffers() usage"                                       },
+               {gen_buffers,                                           "gen_buffers",                                          "Invalid glGenBuffers() usage"                                          },
+               {buffer_data,                                           "buffer_data",                                          "Invalid glBufferData() usage"                                          },
+               {buffer_sub_data,                                       "buffer_sub_data",                                      "Invalid glBufferSubData() usage"                                       },
+               {buffer_sub_data_size_offset,           "buffer_sub_data_size_offset",          "Invalid glBufferSubData() usage"                                       },
+               {clear,                                                         "clear",                                                        "Invalid glClear() usage"                                                       },
+               {read_pixels,                                           "read_pixels",                                          "Invalid glReadPixels() usage"                                          },
+               {readn_pixels,                                          "readn_pixels",                                         "Invalid glReadPixels() usage"                                          },
+               {read_pixels_format_mismatch,           "read_pixels_format_mismatch",          "Invalid glReadPixels() usage"                                          },
+               {read_pixels_fbo_format_mismatch,       "read_pixels_fbo_format_mismatch",      "Invalid glReadPixels() usage"                                          },
+               {bind_buffer_range,                                     "bind_buffer_range",                            "Invalid glBindBufferRange() usage"                                     },
+               {bind_buffer_base,                                      "bind_buffer_base",                                     "Invalid glBindBufferBase() usage"                                      },
+               {clear_bufferiv,                                        "clear_bufferiv",                                       "Invalid glClearBufferiv() usage"                                       },
+               {clear_bufferuiv,                                       "clear_bufferuiv",                                      "Invalid glClearBufferuiv() usage"                                      },
+               {clear_bufferfv,                                        "clear_bufferfv",                                       "Invalid glClearBufferfv() usage"                                       },
+               {clear_bufferfi,                                        "clear_bufferfi",                                       "Invalid glClearBufferfi() usage"                                       },
+               {copy_buffer_sub_data,                          "copy_buffer_sub_data",                         "Invalid glCopyBufferSubData() usage"                           },
+               {draw_buffers,                                          "draw_buffers",                                         "Invalid glDrawBuffers() usage"                                         },
+               {flush_mapped_buffer_range,                     "flush_mapped_buffer_range",            "Invalid glFlushMappedBufferRange() usage"                      },
+               {map_buffer_range,                                      "map_buffer_range",                                     "Invalid glMapBufferRange() usage"                                      },
+               {read_buffer,                                           "read_buffer",                                          "Invalid glReadBuffer() usage"                                          },
+               {unmap_buffer,                                          "unmap_buffer",                                         "Invalid glUnmapBuffer() usage"                                         },
+               {bind_framebuffer,                                      "bind_framebuffer",                                     "Invalid glBindFramebuffer() usage"                                     },
+               {bind_renderbuffer,                                     "bind_renderbuffer",                            "Invalid glBindRenderbuffer() usage"                            },
+               {check_framebuffer_status,                      "check_framebuffer_status",                     "Invalid glCheckFramebufferStatus() usage"                      },
+               {gen_framebuffers,                                      "gen_framebuffers",                                     "Invalid glGenFramebuffers() usage"                                     },
+               {gen_renderbuffers,                                     "gen_renderbuffers",                            "Invalid glGenRenderbuffers() usage"                            },
+               {delete_framebuffers,                           "delete_framebuffers",                          "Invalid glDeleteFramebuffers() usage"                          },
+               {delete_renderbuffers,                          "delete_renderbuffers",                         "Invalid glDeleteRenderbuffers() usage"                         },
+               {framebuffer_renderbuffer,                      "framebuffer_renderbuffer",                     "Invalid glFramebufferRenderbuffer() usage"                     },
+               {framebuffer_texture,                           "framebuffer_texture",                          "Invalid glFramebufferTexture() usage"                          },
+               {framebuffer_texture2d,                         "framebuffer_texture2d",                        "Invalid glFramebufferTexture2D() usage"                        },
+               {renderbuffer_storage,                          "renderbuffer_storage",                         "Invalid glRenderbufferStorage() usage"                         },
+               {blit_framebuffer,                                      "blit_framebuffer",                                     "Invalid glBlitFramebuffer() usage"                                     },
+               {blit_framebuffer_multisample,          "blit_framebuffer_multisample",         "Invalid glBlitFramebuffer() usage"                                     },
+               {framebuffer_texture_layer,                     "framebuffer_texture_layer",            "Invalid glFramebufferTextureLayer() usage"                     },
+               {invalidate_framebuffer,                        "invalidate_framebuffer",                       "Invalid glInvalidateFramebuffer() usage"                       },
+               {invalidate_sub_framebuffer,            "invalidate_sub_framebuffer",           "Invalid glInvalidateSubFramebuffer() usage"            },
+               {renderbuffer_storage_multisample,      "renderbuffer_storage_multisample",     "Invalid glRenderbufferStorageMultisample() usage"      },
+               {copy_image_sub_data,                           "copy_image_sub_data",                          "Invalid glCopyImageSubData() usage"                            },
        };
 
        return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
diff --git a/modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp b/modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp
new file mode 100644 (file)
index 0000000..09ae12a
--- /dev/null
@@ -0,0 +1,496 @@
+/*-------------------------------------------------------------------------
+ * 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 Directive Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeShaderDirectiveTests.hpp"
+
+#include "gluShaderProgram.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+enum ExpectResult
+{
+       EXPECT_RESULT_PASS = 0,
+       EXPECT_RESULT_FAIL,
+
+       EXPECT_RESULT_LAST
+};
+
+void verifyProgram(NegativeTestContext& ctx, glu::ProgramSources sources, ExpectResult expect)
+{
+       DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST);
+
+       tcu::TestLog&                           log             = ctx.getLog();
+       const glu::ShaderProgram        program         (ctx.getRenderContext(), sources);
+       bool                                            testFailed      = false;
+       std::string                                     message;
+
+       log << program;
+
+       if (expect == EXPECT_RESULT_PASS)
+       {
+               testFailed = !program.getProgramInfo().linkOk;
+               message = "Program did not link.";
+       }
+       else
+       {
+               testFailed = program.getProgramInfo().linkOk;
+               message = "Program was not expected to link.";
+       }
+
+       if (testFailed)
+       {
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+               ctx.fail(message);
+       }
+}
+
+void verifyShader(NegativeTestContext& ctx, glu::ShaderType shaderType, std::string shaderSource, ExpectResult expect)
+{
+       DE_ASSERT(expect >= EXPECT_RESULT_PASS && expect < EXPECT_RESULT_LAST);
+
+       tcu::TestLog&           log                     = ctx.getLog();
+       bool                            testFailed      = false;
+       const char* const       source          = shaderSource.c_str();
+       const int                       length          = (int) shaderSource.size();
+       glu::Shader                     shader          (ctx.getRenderContext(), shaderType);
+       std::string                     message;
+
+       shader.setSources(1, &source, &length);
+       shader.compile();
+
+       log << shader;
+
+       if (expect == EXPECT_RESULT_PASS)
+       {
+               testFailed = !shader.getCompileStatus();
+               message = "Shader did not compile.";
+       }
+       else
+       {
+               testFailed = shader.getCompileStatus();
+               message = "Shader was not expected to compile.";
+       }
+
+       if (testFailed)
+       {
+               log << tcu::TestLog::Message << message << tcu::TestLog::EndMessage;
+               ctx.fail(message);
+       }
+}
+
+void primitive_bounding_box (NegativeTestContext& ctx)
+{
+       ctx.beginSection("GL_EXT_primitive_bounding_box features require enabling the extension in 310 es shaders.");
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "       gl_BoundingBoxEXT[0] = vec4(0.0, 0.0, 0.0, 0.0);\n"
+                                       "       gl_BoundingBoxEXT[1] = vec4(1.0, 1.0, 1.0, 1.0);\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_TESSELLATION_CONTROL, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+
+       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);
+               ctx.endSection();
+       }
+}
+
+void blend_equation_advanced (NegativeTestContext& ctx)
+{
+       static const char* const s_qualifiers[] =
+       {
+               "blend_support_multiply",
+               "blend_support_screen",
+               "blend_support_overlay",
+               "blend_support_darken",
+               "blend_support_lighten",
+               "blend_support_colordodge",
+               "blend_support_colorburn",
+               "blend_support_hardlight",
+               "blend_support_softlight",
+               "blend_support_difference",
+               "blend_support_exclusion",
+               "blend_support_hsl_hue",
+               "blend_support_hsl_saturation",
+               "blend_support_hsl_color",
+               "blend_support_hsl_luminosity",
+       };
+
+       ctx.beginSection("GL_KHR_blend_equation_advanced features require enabling the extension in 310 es shaders.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_qualifiers); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "layout(" << s_qualifiers[ndx] << ") out;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+}
+
+void sample_variables (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError, contextSupports(ctx.getRenderContext().getType() , glu::ApiType::es(3, 2)), "Test requires a context version 3.2 or higher.");
+
+       static const char* const s_tests[] =
+       {
+               "int sampleId = gl_SampleID;",
+               "vec2 samplePos = gl_SamplePosition;",
+               "int sampleMaskIn0 = gl_SampleMaskIn[0];",
+               "int sampleMask0 = gl_SampleMask[0];",
+               "int numSamples = gl_NumSamples;",
+       };
+
+       ctx.beginSection("GL_OES_sample_variables features require enabling the extension in 310 es shaders.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_tests); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "precision mediump float;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "       " << s_tests[ndx] << "\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+}
+
+void shader_image_atomic (NegativeTestContext& ctx)
+{
+       static const char* const s_tests[] =
+       {
+               "imageAtomicAdd(u_image, ivec2(1, 1), 1u);",
+               "imageAtomicMin(u_image, ivec2(1, 1), 1u);",
+               "imageAtomicMax(u_image, ivec2(1, 1), 1u);",
+               "imageAtomicAnd(u_image, ivec2(1, 1), 1u);",
+               "imageAtomicOr(u_image, ivec2(1, 1), 1u);",
+               "imageAtomicXor(u_image, ivec2(1, 1), 1u);",
+               "imageAtomicExchange(u_image, ivec2(1, 1), 1u);",
+               "imageAtomicCompSwap(u_image, ivec2(1, 1), 1u, 1u);",
+       };
+
+       ctx.beginSection("GL_OES_shader_image_atomic features require enabling the extension in 310 es shaders.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_tests); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "layout(binding=0, r32ui) coherent uniform highp uimage2D u_image;\n"
+                                       "precision mediump float;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "       " << s_tests[ndx] << "\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+}
+
+void shader_multisample_interpolation (NegativeTestContext& ctx)
+{
+       static const char* const s_sampleTests[] =
+       {
+               "sample in highp float v_var;",
+               "sample out highp float v_var;"
+       };
+
+       static const char* const s_interpolateAtTests[] =
+       {
+               "interpolateAtCentroid(interpolant);",
+               "interpolateAtSample(interpolant, 1);",
+               "interpolateAtOffset(interpolant, vec2(1.0, 0.0));"
+       };
+
+       ctx.beginSection("GL_OES_shader_multisample_interpolation features require enabling the extension in 310 es shaders.");
+       ctx.beginSection("Test sample in/out qualifiers.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_sampleTests); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "       " << s_sampleTests[ndx] << "\n"
+                                       "precision mediump float;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+
+       ctx.beginSection("Test interpolateAt* functions.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_sampleTests); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "in mediump float interpolant;\n"
+                                       "precision mediump float;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "       " << s_interpolateAtTests[ndx] << "\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+       ctx.endSection();
+}
+
+void texture_storage_multisample_2d_array (NegativeTestContext& ctx)
+{
+       static const char* const s_samplerTypeTests[] =
+       {
+               "uniform mediump sampler2DMSArray u_sampler;",
+               "uniform mediump isampler2DMSArray u_sampler;",
+               "uniform mediump usampler2DMSArray u_sampler;",
+       };
+
+       ctx.beginSection("GL_OES_texture_storage_multisample_2d_array features require enabling the extension in 310 es shaders.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerTypeTests); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "       " << s_samplerTypeTests[ndx] << "\n"
+                                       "precision mediump float;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+}
+
+void geometry_shader (NegativeTestContext& ctx)
+{
+       const std::string       simpleVtxFrag   =       "#version 310 es\n"
+                                                                                       "void main()\n"
+                                                                                       "{\n"
+                                                                                       "}\n";
+       const std::string       geometry                =       "#version 310 es\n"
+                                                                                       "layout(points, invocations = 1) in;\n"
+                                                                                       "layout(points, max_vertices = 3) out;\n"
+                                                                                       "precision mediump float;\n"
+                                                                                       "void main()\n"
+                                                                                       "{\n"
+                                                                                       "       EmitVertex();\n"
+                                                                                       "       EndPrimitive();\n"
+                                                                                       "}\n";
+       ctx.beginSection("GL_EXT_geometry_shader features require enabling the extension in 310 es shaders.");
+       verifyProgram(ctx, glu::ProgramSources() << glu::VertexSource(simpleVtxFrag) << glu::GeometrySource(geometry) << glu::FragmentSource(simpleVtxFrag), EXPECT_RESULT_FAIL);
+       ctx.endSection();
+}
+
+void gpu_shader_5 (NegativeTestContext& ctx)
+{
+       ctx.beginSection("GL_EXT_gpu_shader5 features require enabling the extension in 310 es shaders.");
+       ctx.beginSection("Testing the precise qualifier.");
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "       int low = 0;\n"
+                                       "       int high = 10;\n"
+                                       "       precise int middle = low + ((high - low) / 2);\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+
+       ctx.beginSection("Testing fused multiply-add.");
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "in mediump float v_var;"
+                                       "void main()\n"
+                                       "{\n"
+                                       "       float fmaResult = fma(v_var, v_var, v_var);"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+
+       ctx.beginSection("Testing textureGatherOffsets.");
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "uniform mediump sampler2D u_tex;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "       highp vec2 coords = vec2(0.0, 1.0);\n"
+                                       "       const ivec2 offsets[4] = ivec2[](ivec2(0,0), ivec2(1, 0), ivec2(0, 1), ivec2(1, 1));\n"
+                                       "       textureGatherOffsets(u_tex, coords, offsets);\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+
+       ctx.endSection();
+}
+
+void shader_io_blocks (NegativeTestContext& ctx)
+{
+       ctx.beginSection("GL_EXT_shader_io_blocks features require enabling the extension in 310 es shaders.");
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "in Data\n"
+                                       "{\n"
+                                       "       mediump vec3 a;\n"
+                                       "} data;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+}
+
+void tessellation_shader (NegativeTestContext& ctx)
+{
+       const std::string       simpleVtxFrag   =       "#version 310 es\n"
+                                                                                       "void main()\n"
+                                                                                       "{\n"
+                                                                                       "}\n";
+       const std::string       tessControl             =       "#version 310 es\n"
+                                                                                       "layout(vertices = 3) out;\n"
+                                                                                       "void main()\n"
+                                                                                       "{\n"
+                                                                                       "}\n";
+       const std::string       tessEvaluation  =       "#version 310 es\n"
+                                                                                       "layout(triangles, equal_spacing, cw) in;\n"
+                                                                                       "void main()\n"
+                                                                                       "{\n"
+                                                                                       "}\n";
+       ctx.beginSection("GL_EXT_tessellation_shader features require enabling the extension in 310 es shaders.");
+       glu::ProgramSources sources;
+       sources << glu::VertexSource(simpleVtxFrag)
+                       << glu::TessellationControlSource(tessControl)
+                       << glu::TessellationEvaluationSource(tessEvaluation)
+                       << glu::FragmentSource(simpleVtxFrag);
+       verifyProgram(ctx, sources, EXPECT_RESULT_FAIL);
+       ctx.endSection();
+}
+
+void texture_buffer (NegativeTestContext& ctx)
+{
+       static const char* const s_samplerBufferTypes[] =
+       {
+               "uniform mediump samplerBuffer",
+           "uniform mediump isamplerBuffer",
+           "uniform mediump usamplerBuffer",
+           "layout(rgba32f) uniform mediump writeonly imageBuffer",
+           "layout(rgba32i) uniform mediump writeonly iimageBuffer",
+           "layout(rgba32ui) uniform mediump writeonly uimageBuffer"
+       };
+
+       ctx.beginSection("GL_EXT_texture_buffer features require enabling the extension in 310 es shaders.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerBufferTypes); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "" << s_samplerBufferTypes[ndx] << " u_buffer;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+}
+
+
+void texture_cube_map_array (NegativeTestContext& ctx)
+{
+       static const char* const s_samplerCubeArrayTypes[] =
+       {
+           "uniform mediump samplerCubeArray",
+           "uniform mediump isamplerCubeArray",
+           "uniform mediump usamplerCubeArray",
+           "uniform mediump samplerCubeArrayShadow",
+           "layout(rgba32f) uniform mediump writeonly imageCubeArray",
+           "layout(rgba32i) uniform mediump writeonly iimageCubeArray",
+           "layout(rgba32ui) uniform mediump writeonly uimageCubeArray"
+       };
+
+       ctx.beginSection("GL_EXT_texture_cube_map_array features require enabling the extension in 310 es shaders.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_samplerCubeArrayTypes); ++ndx)
+       {
+               std::ostringstream source;
+               source <<       "#version 310 es\n"
+                                       "" << s_samplerCubeArrayTypes[ndx] << " u_cube;\n"
+                                       "void main()\n"
+                                       "{\n"
+                                       "}\n";
+               verifyShader(ctx, glu::SHADERTYPE_FRAGMENT, source.str(), EXPECT_RESULT_FAIL);
+       }
+       ctx.endSection();
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeShaderDirectiveTestFunctions (void)
+{
+       const FunctionContainer funcs[] =
+       {
+               {primitive_bounding_box,                                "primitive_bounding_box",                               "GL_EXT_primitive_bounding_box required in 310 es shaders to use AEP features. Version 320 es shaders do not require suffixes." },
+               {blend_equation_advanced,                               "blend_equation_advanced",                              "GL_KHR_blend_equation_advanced is required in 310 es shaders to use AEP features"                                                                                              },
+               {sample_variables,                                              "sample_variables",                                             "GL_OES_sample_variables is required in 310 es shaders to use AEP features"                                                                                                             },
+               {shader_image_atomic,                                   "shader_image_atomic",                                  "GL_OES_shader_image_atomic is required in 310 es shaders to use AEP features"                                                                                                  },
+               {shader_multisample_interpolation,              "shader_multisample_interpolation",             "GL_OES_shader_multisample_interpolation is required in 310 es shaders to use AEP features"                                                                             },
+               {texture_storage_multisample_2d_array,  "texture_storage_multisample_2d_array", "GL_OES_texture_storage_multisample_2d_array is required in 310 es shaders to use AEP features"                                                                 },
+               {geometry_shader,                                               "geometry_shader",                                              "GL_EXT_geometry_shader is required in 310 es shaders to use AEP features"                                                                                                              },
+               {gpu_shader_5,                                                  "gpu_shader_5",                                                 "GL_EXT_gpu_shader5 is required in 310 es shaders to use AEP features"                                                                                                                  },
+               {shader_io_blocks,                                              "shader_io_blocks",                                             "GL_EXT_shader_io_blocks is required in 310 es shaders to use AEP features"                                                                                                             },
+               {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"                                                                                               },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeShaderDirectiveTests.hpp b/modules/gles31/functional/es31fNegativeShaderDirectiveTests.hpp
new file mode 100644 (file)
index 0000000..d961ef3
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVESHADERDIRECTIVETESTS_HPP
+#define _ES31FNEGATIVESHADERDIRECTIVETESTS_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 Directive Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeShaderDirectiveTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVESHADERDIRECTIVETESTS_HPP
diff --git a/modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp b/modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp
new file mode 100644 (file)
index 0000000..e84e2a2
--- /dev/null
@@ -0,0 +1,4476 @@
+/*-------------------------------------------------------------------------
+ * 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 Function Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeShaderFunctionTests.hpp"
+
+#include "gluShaderProgram.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+enum ShaderFunction
+{
+       SHADER_FUNCTION_BITFIELD_REVERSE = 0,
+       SHADER_FUNCTION_BIT_COUNT,
+       SHADER_FUNCTION_FIND_MSB,
+       SHADER_FUNCTION_FIND_LSB,
+       SHADER_FUNCTION_UADD_CARRY,
+       SHADER_FUNCTION_USUB_BORROW,
+       SHADER_FUNCTION_UMUL_EXTENDED,
+       SHADER_FUNCTION_IMUL_EXTENDED,
+       SHADER_FUNCTION_FREXP,
+       SHADER_FUNCTION_LDEXP,
+       SHADER_FUNCTION_PACK_UNORM_4X8,
+       SHADER_FUNCTION_PACK_SNORM_4X8,
+       SHADER_FUNCTION_UNPACK_SNORM_4X8,
+       SHADER_FUNCTION_UNPACK_UNORM_4X8,
+       SHADER_FUNCTION_EMIT_VERTEX,
+       SHADER_FUNCTION_END_PRIMITIVE,
+       SHADER_FUNCTION_ATOMIC_ADD,
+       SHADER_FUNCTION_ATOMIC_MIN,
+       SHADER_FUNCTION_ATOMIC_MAX,
+       SHADER_FUNCTION_ATOMIC_AND,
+       SHADER_FUNCTION_ATOMIC_OR,
+       SHADER_FUNCTION_ATOMIC_XOR,
+       SHADER_FUNCTION_ATOMIC_EXCHANGE,
+       SHADER_FUNCTION_ATOMIC_COMP_SWAP,
+       SHADER_FUNCTION_INTERPOLATED_AT_CENTROID,
+       SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE,
+       SHADER_FUNCTION_INTERPOLATED_AT_OFFSET,
+
+       SHADER_FUNCTION_LAST
+};
+
+enum FunctionTextureModes
+{
+       FUNCTION_TEXTURE_MODE_NO_BIAS_NO_COMPARE = 0,
+       FUNCTION_TEXTURE_MODE_BIAS_OR_COMPARE,
+
+       FUNCTION_TEXTURE_MODE_LAST
+};
+
+enum FunctionTextureGatherOffsetModes
+{
+       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP = 0,
+       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,
+
+       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_LAST
+};
+
+struct TextureGatherOffsetsTestSpec
+{
+       FunctionTextureGatherOffsetModes        mode;
+       glu::DataType                                           samplerDataType;
+       glu::DataType                                           pDataType;
+       glu::DataType                                           offsetsDataType;
+       glu::DataType                                           fourthArgument;
+       bool                                                            offsetIsConst;
+       int                                                                     offsetArraySize;
+};
+
+static const glu::DataType s_floatTypes[] =
+{
+       glu::TYPE_FLOAT,
+       glu::TYPE_FLOAT_VEC2,
+       glu::TYPE_FLOAT_VEC3,
+       glu::TYPE_FLOAT_VEC4
+};
+
+static const glu::DataType s_intTypes[] =
+{
+       glu::TYPE_INT,
+       glu::TYPE_INT_VEC2,
+       glu::TYPE_INT_VEC3,
+       glu::TYPE_INT_VEC4
+};
+
+static const glu::DataType s_uintTypes[] =
+{
+       glu::TYPE_UINT,
+       glu::TYPE_UINT_VEC2,
+       glu::TYPE_UINT_VEC3,
+       glu::TYPE_UINT_VEC4
+};
+
+static const glu::DataType s_nonScalarIntTypes[] =
+{
+       glu::TYPE_FLOAT,
+       glu::TYPE_FLOAT_VEC2,
+       glu::TYPE_FLOAT_VEC3,
+       glu::TYPE_FLOAT_VEC4,
+       glu::TYPE_INT_VEC2,
+       glu::TYPE_INT_VEC3,
+       glu::TYPE_INT_VEC4,
+       glu::TYPE_UINT,
+       glu::TYPE_UINT_VEC2,
+       glu::TYPE_UINT_VEC3,
+       glu::TYPE_UINT_VEC4
+};
+
+static const glu::ShaderType s_shaders[] =
+{
+       glu::SHADERTYPE_VERTEX,
+       glu::SHADERTYPE_FRAGMENT,
+       glu::SHADERTYPE_GEOMETRY,
+       glu::SHADERTYPE_TESSELLATION_CONTROL,
+       glu::SHADERTYPE_TESSELLATION_EVALUATION,
+       glu::SHADERTYPE_COMPUTE
+};
+
+static const glu::DataType s_samplerTypes[] =
+{
+       glu::TYPE_SAMPLER_2D,
+       glu::TYPE_INT_SAMPLER_2D,
+       glu::TYPE_UINT_SAMPLER_2D,
+       glu::TYPE_SAMPLER_3D,
+       glu::TYPE_INT_SAMPLER_3D,
+       glu::TYPE_UINT_SAMPLER_3D,
+       glu::TYPE_SAMPLER_CUBE,
+       glu::TYPE_INT_SAMPLER_CUBE,
+       glu::TYPE_UINT_SAMPLER_CUBE,
+       glu::TYPE_SAMPLER_2D_ARRAY,
+       glu::TYPE_INT_SAMPLER_2D_ARRAY,
+       glu::TYPE_UINT_SAMPLER_2D_ARRAY,
+       glu::TYPE_SAMPLER_CUBE_SHADOW,
+       glu::TYPE_SAMPLER_2D_SHADOW,
+       glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,
+       glu::TYPE_SAMPLER_CUBE_ARRAY,
+       glu::TYPE_INT_SAMPLER_CUBE_ARRAY,
+       glu::TYPE_UINT_SAMPLER_CUBE_ARRAY,
+       glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW,
+
+       glu::TYPE_SAMPLER_2D_MULTISAMPLE,
+       glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE,
+       glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE,
+
+       glu::TYPE_SAMPLER_BUFFER,
+       glu::TYPE_INT_SAMPLER_BUFFER,
+       glu::TYPE_UINT_SAMPLER_BUFFER,
+
+       glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY,
+       glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+       glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+};
+
+void verifyShader (NegativeTestContext& ctx, glu::ShaderType shaderType, std::string shaderSource)
+{
+       tcu::TestLog&   log     = ctx.getLog();
+       const char*             source  = shaderSource.c_str();
+       const int               length  = (int) shaderSource.size();
+       glu::Shader             shader  (ctx.getRenderContext(), shaderType);
+
+       shader.setSources(1, &source, &length);
+       shader.compile();
+
+       log << shader;
+       if (shader.getCompileStatus())
+       {
+               log << tcu::TestLog::Message << "Expected shader to fail, but compilation passed." << tcu::TestLog::EndMessage;
+               ctx.fail("Shader was not expected to compile.\n");
+       }
+}
+
+std::string declareAndInitializeShaderVariable (glu::DataType dataType, std::string varName)
+{
+       std::ostringstream variable;
+       variable << getDataTypeName(dataType) << " " << varName << " = " << getDataTypeName(dataType);
+       switch (dataType)
+       {
+               case glu::TYPE_FLOAT:           variable << "(1.0);\n";                                 break;
+               case glu::TYPE_FLOAT_VEC2:      variable << "(1.0, 1.0);\n";                    break;
+               case glu::TYPE_FLOAT_VEC3:      variable << "(1.0, 1.0, 1.0);\n";               break;
+               case glu::TYPE_FLOAT_VEC4:      variable << "(1.0, 1.0, 1.0, 1.0);\n";  break;
+               case glu::TYPE_INT:                     variable << "(1);\n";                                   break;
+               case glu::TYPE_INT_VEC2:        variable << "(1, 1);\n";                                break;
+               case glu::TYPE_INT_VEC3:        variable << "(1, 1, 1);\n";                             break;
+               case glu::TYPE_INT_VEC4:        variable << "(1, 1, 1, 1);\n";                  break;
+               case glu::TYPE_UINT:            variable << "(1u);\n";                                  break;
+               case glu::TYPE_UINT_VEC2:       variable << "(1u, 1u);\n";                              break;
+               case glu::TYPE_UINT_VEC3:       variable << "(1u, 1u, 1u);\n";                  break;
+               case glu::TYPE_UINT_VEC4:       variable << "(1u, 1u, 1u, 1u);\n";              break;
+               default:
+                       DE_FATAL("Unsupported data type.");
+       }
+       return variable.str();
+}
+
+std::string declareShaderUniform (glu::DataType dataType, std::string varName)
+{
+       std::ostringstream variable;
+       variable << getPrecisionName(glu::PRECISION_HIGHP) << " uniform " << getDataTypeName(dataType) << " " << varName << ";\n";
+       return variable.str();
+}
+
+std::string declareShaderInput (glu::DataType dataType, std::string varName)
+{
+       std::ostringstream variable;
+       variable << "in " << getPrecisionName(glu::PRECISION_HIGHP) << " " << getDataTypeName(dataType) << " " << varName << ";\n";
+       return variable.str();
+}
+
+std::string declareBuffer (glu::DataType dataType, std::string varName)
+{
+       std::ostringstream variable;
+       variable        << "buffer SSBO {\n"
+                               << "    " << getDataTypeName(dataType) << " " << varName << ";\n"
+                               << "};\n";
+       return variable.str();
+}
+
+std::string declareShaderArrayVariable (glu::DataType dataType, std::string varName, const int arraySize)
+{
+       std::ostringstream source;
+       source << getDataTypeName(dataType) << " " << varName << "[" << arraySize << "]" << " = " << getDataTypeName(dataType) << "[](";
+
+       for (int ndx = 0; ndx < arraySize; ++ndx)
+               source << getDataTypeName(dataType) << "(" << 0 << ", " << 0 << ")" << ((ndx < arraySize -1) ? ", " : "");
+
+       source << ");";
+       return source.str();
+}
+
+std::string getShaderExtensionDeclaration (std::string extension)
+{
+       if (extension.empty())
+               return std::string("");
+       else
+       {
+               std::ostringstream source;
+               source << "#extension " << extension << " : enable\n";
+               return source.str();
+       }
+}
+
+std::string getDataTypeExtension (glu::DataType dataType)
+{
+       std::ostringstream source;
+       switch (dataType)
+       {
+               case glu::TYPE_SAMPLER_CUBE_ARRAY:
+               case glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW:
+               case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
+               case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
+                       source << "GL_EXT_texture_cube_map_array";
+                       break;
+
+               case glu::TYPE_SAMPLER_BUFFER:
+               case glu::TYPE_INT_SAMPLER_BUFFER:
+               case glu::TYPE_UINT_SAMPLER_BUFFER:
+                       source << "GL_EXT_texture_buffer";
+                       break;
+
+               case glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY:
+               case glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+               case glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+                       source << "GL_OES_texture_storage_multisample_2d_array";
+                       break;
+
+               default:
+                       break;
+       }
+
+       return source.str();
+}
+
+std::string getShaderInitialization (NegativeTestContext& ctx, glu::ShaderType shaderType)
+{
+       std::ostringstream source;
+
+       if (!contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               switch (shaderType)
+               {
+                       case glu::SHADERTYPE_GEOMETRY:
+                               source << "#extension GL_EXT_geometry_shader : enable\n";
+                               break;
+
+                       case glu::SHADERTYPE_TESSELLATION_CONTROL:
+                               source << "#extension GL_EXT_tessellation_shader : enable\n";
+                               break;
+
+                       case glu::SHADERTYPE_TESSELLATION_EVALUATION:
+                               source << "#extension GL_EXT_tessellation_shader : enable\n";
+                               break;
+
+                       default:
+                               break;
+               }
+       }
+
+       switch (shaderType)
+       {
+               case glu::SHADERTYPE_GEOMETRY:
+                       source << "layout(max_vertices = 5) out;\n";
+                       break;
+
+               case glu::SHADERTYPE_TESSELLATION_CONTROL:
+                       source << "layout(vertices = 3) out;\n";
+                       break;
+
+               case glu::SHADERTYPE_TESSELLATION_EVALUATION:
+                       source << "layout(triangles, equal_spacing, cw) in;\n";
+                       break;
+
+               default:
+                       break;
+       }
+
+       return source.str();
+}
+
+std::string genShaderSourceBitfieldExtract (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType valueDataType, glu::DataType offsetDataType, glu::DataType bitsDataType)
+{
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(valueDataType, "value")
+                       << "    " << declareAndInitializeShaderVariable(offsetDataType, "offset")
+                       << "    " << declareAndInitializeShaderVariable(bitsDataType, "bits")
+                       << "    bitfieldExtract(value, offset, bits);\n"
+                       << "}\n";
+
+       return source.str();
+}
+
+void bitfield_extract_invalid_value_type (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       ctx.beginSection("bitfieldExtract: Invalid value type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               const std::string shaderSource(genShaderSourceBitfieldExtract(ctx, s_shaders[shaderNdx], s_floatTypes[dataTypeNdx], glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void bitfield_extract_invalid_offset_type (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       ctx.beginSection("bitfieldExtract: Invalid offset type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               for (int nonIntNdx = 0; nonIntNdx < DE_LENGTH_OF_ARRAY(s_nonScalarIntTypes); ++nonIntNdx)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldExtract(ctx, s_shaders[shaderNdx], s_intTypes[dataTypeNdx], s_nonScalarIntTypes[nonIntNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldExtract(ctx, s_shaders[shaderNdx], s_uintTypes[dataTypeNdx], s_nonScalarIntTypes[nonIntNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void bitfield_extract_invalid_bits_type (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       ctx.beginSection("bitfieldExtract: Invalid bits type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               for (int nonIntNdx = 0; nonIntNdx < DE_LENGTH_OF_ARRAY(s_nonScalarIntTypes); ++nonIntNdx)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldExtract(ctx, s_shaders[shaderNdx], s_intTypes[dataTypeNdx], glu::TYPE_INT, s_nonScalarIntTypes[nonIntNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldExtract(ctx, s_shaders[shaderNdx], s_uintTypes[dataTypeNdx], glu::TYPE_INT, s_nonScalarIntTypes[nonIntNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+std::string genShaderSourceBitfieldInsert (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType baseDataType, glu::DataType insertDataType, glu::DataType offsetDataType, glu::DataType bitsDataType)
+{
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(baseDataType, "base")
+                       << "    " << declareAndInitializeShaderVariable(insertDataType, "insert")
+                       << "    " << declareAndInitializeShaderVariable(offsetDataType, "offset")
+                       << "    " << declareAndInitializeShaderVariable(bitsDataType, "bits")
+                       << "    bitfieldInsert(base, insert, offset, bits);\n"
+                       << "}\n";
+
+       return source.str();
+}
+
+void bitfield_insert_invalid_base_type (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_floatTypes));
+
+       ctx.beginSection("bitfieldInsert: Invalid base type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_floatTypes[dataTypeNdx], s_intTypes[dataTypeNdx], glu::TYPE_INT, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], glu::TYPE_INT, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void bitfield_insert_invalid_insert_type (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_floatTypes));
+
+       ctx.beginSection("bitfieldInsert: Invalid insert type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_intTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], glu::TYPE_INT, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], glu::TYPE_INT, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_intTypes[dataTypeNdx] == s_intTypes[dataTypeNdx2])
+                                               continue;
+
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx2], glu::TYPE_INT, glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2], glu::TYPE_INT, glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void bitfield_insert_invalid_offset_type (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       ctx.beginSection("bitfieldInsert: Invalid offset type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_nonScalarIntTypes); ++dataTypeNdx2)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_nonScalarIntTypes[dataTypeNdx2], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_nonScalarIntTypes[dataTypeNdx2], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void bitfield_insert_invalid_bits_type (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_intTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       ctx.beginSection("bitfieldInsert: Invalid bits type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_nonScalarIntTypes); ++dataTypeNdx2)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], glu::TYPE_INT, s_nonScalarIntTypes[dataTypeNdx2]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceBitfieldInsert(ctx, s_shaders[shaderNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], glu::TYPE_INT, s_nonScalarIntTypes[dataTypeNdx2]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// bitfieldReverse, bitCount, findMSB, findLSB
+std::string genShaderSourceReverseCountFind (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType baseDataType)
+{
+       DE_ASSERT(function == SHADER_FUNCTION_BITFIELD_REVERSE ||
+               function == SHADER_FUNCTION_BIT_COUNT ||
+               function == SHADER_FUNCTION_FIND_MSB ||
+               function == SHADER_FUNCTION_FIND_LSB);
+
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(baseDataType, "value");
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_BITFIELD_REVERSE:  source << "    bitfieldReverse(value);\n";      break;
+               case SHADER_FUNCTION_BIT_COUNT:                 source << "    bitCount(value);\n";                     break;
+               case SHADER_FUNCTION_FIND_MSB:                  source << "    findMSB(value);\n";                      break;
+               case SHADER_FUNCTION_FIND_LSB:                  source << "    findLSB(value);\n";                      break;
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+
+void bitfield_reverse (NegativeTestContext& ctx)
+{
+       ctx.beginSection("bitfieldReverse: Invalid value type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               const std::string shaderSource(genShaderSourceReverseCountFind(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_BITFIELD_REVERSE, s_floatTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void bit_count (NegativeTestContext& ctx)
+{
+       ctx.beginSection("bitCount: Invalid value type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               const std::string shaderSource(genShaderSourceReverseCountFind(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_BIT_COUNT, s_floatTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void find_msb (NegativeTestContext& ctx)
+{
+       ctx.beginSection("findMSB: Invalid value type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               const std::string shaderSource(genShaderSourceReverseCountFind(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_FIND_MSB, s_floatTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void find_lsb (NegativeTestContext& ctx)
+{
+       ctx.beginSection("findLSB: Invalid value type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               const std::string shaderSource(genShaderSourceReverseCountFind(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_FIND_LSB, s_floatTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// uaddCarry, usubBorrow
+std::string genShaderSourceAddCarrySubBorrow (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType xDataType, glu::DataType yDataType, glu::DataType carryBorrowDataType)
+{
+       DE_ASSERT(function == SHADER_FUNCTION_UADD_CARRY || function == SHADER_FUNCTION_USUB_BORROW);
+
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(xDataType, "x")
+                       << "    " << declareAndInitializeShaderVariable(yDataType, "y");
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_UADD_CARRY:
+                       source  << "    " << declareAndInitializeShaderVariable(carryBorrowDataType, "carry")
+                                       << "    uaddCarry(x, y, carry);\n";
+                       break;
+
+               case SHADER_FUNCTION_USUB_BORROW:
+                       source  << "    " << declareAndInitializeShaderVariable(carryBorrowDataType, "borrow")
+                                       << "    usubBorrow(x, y, borrow);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+void uadd_carry_invalid_x (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("uaddCarry: Invalid x type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_uintTypes[dataTypeNdx2], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void uadd_carry_invalid_y (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("uaddCarry: Invalid y type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void uadd_carry_invalid_carry (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("uaddCarry: Invalid carry type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UADD_CARRY, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void usub_borrow_invalid_x (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("usubBorrow: Invalid x type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_uintTypes[dataTypeNdx2], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void usub_borrow_invalid_y (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("usubBorrow: Invalid y type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource = genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2], s_uintTypes[dataTypeNdx]);
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void usub_borrow_invalid_borrow (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("usubBorrow: Invalid borrow type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceAddCarrySubBorrow(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_USUB_BORROW, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// umulExtended, imulExtended
+std::string genShaderSourceMulExtended (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType xDataType, glu::DataType yDataType, glu::DataType msbDataType, glu::DataType lsbDataType)
+{
+       DE_ASSERT(function == SHADER_FUNCTION_UMUL_EXTENDED || function == SHADER_FUNCTION_IMUL_EXTENDED);
+
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(xDataType, "x")
+                       << "    " << declareAndInitializeShaderVariable(yDataType, "y")
+                       << "    " << declareAndInitializeShaderVariable(msbDataType, "msb")
+                       << "    " << declareAndInitializeShaderVariable(lsbDataType, "lsb");
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_UMUL_EXTENDED:     source << "    umulExtended(x, y, msb, lsb);\n";        break;
+               case SHADER_FUNCTION_IMUL_EXTENDED:     source << "    imulExtended(x, y, msb, lsb);\n";        break;
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+void umul_extended_invalid_x (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("umulExtended: Invalid x type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx2], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void umul_extended_invalid_y (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("umulExtended: Invalid y type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void umul_extended_invalid_msb (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("umulExtended: Invalid msb type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void umul_extended_invalid_lsb (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("umulExtended: Invalid lsb type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_uintTypes[dataTypeNdx2] == s_uintTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_uintTypes[dataTypeNdx2]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void imul_extended_invalid_x (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("imulExtended: Invalid x type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_floatTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_intTypes[dataTypeNdx2] == s_intTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx2], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void imul_extended_invalid_y (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("imulExtended: Invalid y type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_intTypes[dataTypeNdx2] == s_intTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx2], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void imul_extended_invalid_msb (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("imulExtended: Invalid msb type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_floatTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_intTypes[dataTypeNdx2] == s_intTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx2], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void imul_extended_invalid_lsb (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("imulExtended: Invalid lsb type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx2)
+                               {
+                                       if (s_intTypes[dataTypeNdx2] == s_intTypes[dataTypeNdx])
+                                               continue;
+
+                                       const std::string shaderSource(genShaderSourceMulExtended(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_IMUL_EXTENDED, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx2]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// frexp, ldexp
+std::string genShaderSourceFrexpLdexp (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType xDataType, glu::DataType expDataType)
+{
+       DE_ASSERT(function == SHADER_FUNCTION_FREXP || function == SHADER_FUNCTION_LDEXP);
+
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(xDataType, "x")
+                       << "    " << declareAndInitializeShaderVariable(expDataType, "exp");
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_FREXP:
+                       source << "    frexp(x, exp);\n";
+                       break;
+
+               case SHADER_FUNCTION_LDEXP:
+                       source << "    ldexp(x, exp);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+void frexp_invalid_x (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("frexp: Invalid x type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_FREXP, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_FREXP, s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void frexp_invalid_exp (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("frexp: Invalid exp type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_FREXP, s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_FREXP, s_floatTypes[dataTypeNdx], s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void ldexp_invalid_x (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("ldexp: Invalid x type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_LDEXP, s_intTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_LDEXP, s_uintTypes[dataTypeNdx], s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void ldexp_invalid_exp (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("ldexp: Invalid exp type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_LDEXP, s_floatTypes[dataTypeNdx], s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceFrexpLdexp(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_LDEXP, s_floatTypes[dataTypeNdx], s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// packUnorm4x8, packSnorm4x8, unpackSnorm4x8, unpackUnorm4x8
+std::string genShaderSourcePackUnpackNorm4x8 (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType dataType)
+{
+       DE_ASSERT(function == SHADER_FUNCTION_PACK_UNORM_4X8 ||
+               function == SHADER_FUNCTION_PACK_SNORM_4X8 ||
+               function == SHADER_FUNCTION_UNPACK_SNORM_4X8 ||
+               function == SHADER_FUNCTION_UNPACK_UNORM_4X8);
+
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n";
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_PACK_UNORM_4X8:
+                       source  << "    mediump " << declareAndInitializeShaderVariable(dataType, "v")
+                                       << "    packUnorm4x8(v);\n";
+                       break;
+
+               case SHADER_FUNCTION_PACK_SNORM_4X8:
+                       source  << "    mediump " << declareAndInitializeShaderVariable(dataType, "v")
+                                       << "    packSnorm4x8(v);\n";
+                       break;
+
+               case SHADER_FUNCTION_UNPACK_SNORM_4X8:
+                       source  << "    highp " << declareAndInitializeShaderVariable(dataType, "p")
+                                       << "    unpackSnorm4x8(p);\n";
+                       break;
+
+               case SHADER_FUNCTION_UNPACK_UNORM_4X8:
+                       source  << "    highp " << declareAndInitializeShaderVariable(dataType, "p")
+                                       << "    unpackUnorm4x8(p);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+void pack_unorm_4x8 (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("packUnorm4x8: Invalid v type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               if (s_floatTypes[dataTypeNdx] == glu::TYPE_FLOAT_VEC4)
+                                       continue;
+
+                               const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_PACK_UNORM_4X8, s_floatTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_PACK_UNORM_4X8, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_PACK_UNORM_4X8, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void pack_snorm_4x8 (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("packSnorm4x8: Invalid v type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               if (s_floatTypes[dataTypeNdx] == glu::TYPE_FLOAT_VEC4)
+                                       continue;
+
+                               const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_PACK_SNORM_4X8, s_floatTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_PACK_SNORM_4X8, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_PACK_SNORM_4X8, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void unpack_snorm_4x8 (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("unpackSnorm4x8: Invalid v type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx)
+                       {
+                               if (s_uintTypes[dataTypeNdx] == glu::TYPE_UINT)
+                                       continue;
+
+                               const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UNPACK_SNORM_4X8, s_uintTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UNPACK_SNORM_4X8, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UNPACK_SNORM_4X8, s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void unpack_unorm_4x8 (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+
+       ctx.beginSection("unpackUnorm4x8: Invalid v type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_uintTypes); ++dataTypeNdx)
+                       {
+                               if (s_uintTypes[dataTypeNdx] == glu::TYPE_UINT)
+                                       continue;
+
+                               const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UNPACK_UNORM_4X8, s_uintTypes[dataTypeNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_intTypes); ++dataTypeNdx)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UNPACK_UNORM_4X8, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourcePackUnpackNorm4x8(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_UNPACK_UNORM_4X8, s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// textureSize
+std::string genShaderSourceTextureSize_sampler (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType lodDataType)
+{
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderExtensionDeclaration(getDataTypeExtension(samplerDataType))
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n";
+
+       switch (samplerDataType)
+       {
+               case glu::TYPE_SAMPLER_2D:
+               case glu::TYPE_INT_SAMPLER_2D:
+               case glu::TYPE_UINT_SAMPLER_2D:
+               case glu::TYPE_SAMPLER_3D:
+               case glu::TYPE_INT_SAMPLER_3D:
+               case glu::TYPE_UINT_SAMPLER_3D:
+               case glu::TYPE_SAMPLER_CUBE:
+               case glu::TYPE_INT_SAMPLER_CUBE:
+               case glu::TYPE_UINT_SAMPLER_CUBE:
+               case glu::TYPE_SAMPLER_2D_ARRAY:
+               case glu::TYPE_INT_SAMPLER_2D_ARRAY:
+               case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
+               case glu::TYPE_SAMPLER_CUBE_SHADOW:
+               case glu::TYPE_SAMPLER_2D_SHADOW:
+               case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
+               case glu::TYPE_SAMPLER_CUBE_ARRAY:
+               case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
+               case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
+               case glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW:
+                       source << "    textureSize(sampler);\n";
+                       break;
+
+               case glu::TYPE_SAMPLER_2D_MULTISAMPLE:
+               case glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE:
+               case glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE:
+               case glu::TYPE_SAMPLER_BUFFER:
+               case glu::TYPE_INT_SAMPLER_BUFFER:
+               case glu::TYPE_UINT_SAMPLER_BUFFER:
+               case glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY:
+               case glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+               case glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+                       source  << "    " << declareAndInitializeShaderVariable(lodDataType, "lod")
+                                       << "    textureSize(sampler, lod);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported data type.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+void texture_size_invalid_sampler (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureSize: Invalid sampler type - some overloads take two arguments while others take only one.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_samplerTypes); ++dataTypeNdx)
+                       {
+                               if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(s_samplerTypes[dataTypeNdx])))
+                               {
+                                       ctx.beginSection("Verify sampler data type: " + std::string(getDataTypeName(s_samplerTypes[dataTypeNdx])));
+                                       const std::string shaderSource(genShaderSourceTextureSize_sampler(ctx, s_shaders[shaderNdx], s_samplerTypes[dataTypeNdx], glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       ctx.endSection();
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+std::string genShaderSourceTextureSize_lod (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType lodDataType)
+{
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderExtensionDeclaration(getDataTypeExtension(samplerDataType))
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(lodDataType, "lod")
+                       << "    textureSize(sampler, lod);\n"
+                       << "}\n";
+
+       return source.str();
+}
+
+void texture_size_invalid_lod (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureSize: Invalid lod type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_samplerTypes); ++dataTypeNdx)
+                       {
+                               if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(s_samplerTypes[dataTypeNdx])))
+                               {
+                                       ctx.beginSection("Verify sampler/lod data type" + std::string(getDataTypeName(s_samplerTypes[dataTypeNdx])));
+                                       for (int dataTypeNdx2 = 0; dataTypeNdx2 < DE_LENGTH_OF_ARRAY(s_nonScalarIntTypes); ++dataTypeNdx2)
+                                       {
+                                               if (s_nonScalarIntTypes[dataTypeNdx2] == glu::TYPE_INT)
+                                                       continue;
+
+                                               const std::string shaderSource(genShaderSourceTextureSize_lod(ctx, s_shaders[shaderNdx], s_samplerTypes[dataTypeNdx], s_nonScalarIntTypes[dataTypeNdx2]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       ctx.endSection();
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// texture
+std::string genShaderSourceTexture (NegativeTestContext& ctx, glu::ShaderType shaderType, FunctionTextureModes mode, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType thirdArgumentDataType)
+{
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderExtensionDeclaration(getDataTypeExtension(samplerDataType))
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    highp " << declareAndInitializeShaderVariable(pDataType, "lod");
+
+       switch (mode)
+       {
+               case FUNCTION_TEXTURE_MODE_NO_BIAS_NO_COMPARE:
+                       source << "    texture(sampler, lod);\n";
+                       break;
+
+               case FUNCTION_TEXTURE_MODE_BIAS_OR_COMPARE:
+                       source  << "    highp " << declareAndInitializeShaderVariable(thirdArgumentDataType, "thirdArgument")
+                                       << "    texture(sampler, lod, thirdArgument);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported shader function overload.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+std::string genShaderSourceTexture (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType)
+{
+       return genShaderSourceTexture(ctx, shaderType, FUNCTION_TEXTURE_MODE_NO_BIAS_NO_COMPARE, samplerDataType, pDataType, glu::TYPE_LAST);
+}
+
+std::string genShaderSourceTexture (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType thirdArgumentDataType)
+{
+       return genShaderSourceTexture(ctx, shaderType, FUNCTION_TEXTURE_MODE_BIAS_OR_COMPARE, samplerDataType, pDataType, thirdArgumentDataType);
+}
+
+void texture_invalid_p (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       ctx.beginSection("texture: Invalid P type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               // SAMPLER_2D
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC2)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_3D
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC3)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_CUBE
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC3)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+
+                               // SAMPLER_2D_ARRAY
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC3)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_2D_SHADOW
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC3)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_CUBE_SHADOW
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC4)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_2D_ARRAY_SHADOW
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC4)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_CUBE_ARRAY
+                               if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY)))
+                               {
+                                       if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC4)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+
+                               // SAMPLER_CUBE_ARRAY_SHADOW
+                               if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW)))
+                               {
+                                       if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC4)
+                                       {
+                                               std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_invalid_bias_or_compare (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       ctx.beginSection("texture: Invalid bias/compare type.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                       {
+                               // SAMPLER_2D
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_3D
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_CUBE
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                               {
+                                       std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       shaderSource = genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]);
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       shaderSource = genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]);
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_2D_ARRAY
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                               {
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_2D_SHADOW
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT_VEC3, s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT_VEC3, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT_VEC3, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_CUBE_SHADOW
+                               if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                               {
+                                       std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, glu::TYPE_FLOAT_VEC4, s_floatTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+
+                               // SAMPLER_CUBE_ARRAY
+                               if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY)))
+                               {
+                                       if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+
+                               // SAMPLER_CUBE_ARRAY_SHADOW
+                               if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW)))
+                               {
+                                       if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, glu::TYPE_FLOAT_VEC4, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexture(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// textureLod
+std::string genShaderSourceTextureLod (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType lodDataType)
+{
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderExtensionDeclaration(getDataTypeExtension(samplerDataType))
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(pDataType, "P")
+                       << "    " << declareAndInitializeShaderVariable(lodDataType, "lod")
+                       << "    textureLod(sampler, P, lod);\n"
+                       << "}\n";
+
+       return source.str();
+}
+
+void texture_lod_invalid_p (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY)))
+       {
+               ctx.beginSection("textureLod: Invalid P type.");
+               for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+               {
+                       if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+                       {
+                               ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                               for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                               {
+                                       if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT_VEC4)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_FLOAT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               ctx.endSection();
+                       }
+               }
+               ctx.endSection();
+       }
+}
+
+void texture_lod_invalid_lod (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY)))
+       {
+               ctx.beginSection("textureLod: Invalid lod type.");
+               for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+               {
+                       if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+                       {
+                               ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                               for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                               {
+                                       if (s_floatTypes[dataTypeNdx] != glu::TYPE_FLOAT)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, s_floatTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_intTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTextureLod(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               ctx.endSection();
+                       }
+               }
+               ctx.endSection();
+       }
+}
+
+// texelFetch
+std::string genShaderSourceTexelFetch (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType sampleDataType)
+{
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderExtensionDeclaration(getDataTypeExtension(samplerDataType))
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    " << declareAndInitializeShaderVariable(pDataType, "P");
+
+       switch (samplerDataType)
+       {
+               case glu::TYPE_SAMPLER_2D_MULTISAMPLE:
+               case glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE:
+               case glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE:
+               case glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY:
+               case glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+               case glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY:
+                       source  << "    " << declareAndInitializeShaderVariable(sampleDataType, "varSample")
+                                       << "    texelFetch(sampler, P, varSample);\n";
+                       break;
+
+               case glu::TYPE_SAMPLER_BUFFER:
+               case glu::TYPE_INT_SAMPLER_BUFFER:
+               case glu::TYPE_UINT_SAMPLER_BUFFER:
+                       source << "    texelFetch(sampler, P);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported data type.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+std::string genShaderSourceTexelFetch (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType)
+{
+       return genShaderSourceTexelFetch(ctx, shaderType, samplerDataType, pDataType, glu::TYPE_LAST);
+}
+
+void texel_fetch_invalid_p (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY)))
+       {
+               ctx.beginSection("texelFetch: Invalid P type.");
+               for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+               {
+                       if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+                       {
+                               ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                               for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                               {
+                                       // SAMPLER_2D_MULTISAMPLE
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE, s_floatTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE, s_floatTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE, s_floatTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       if (s_intTypes[dataTypeNdx] != glu::TYPE_INT_VEC2)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE, s_intTypes[dataTypeNdx], glu::TYPE_INT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE, s_intTypes[dataTypeNdx], glu::TYPE_INT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE, s_intTypes[dataTypeNdx], glu::TYPE_INT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE, s_uintTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE, s_uintTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE, s_uintTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       // SAMPLER_BUFFER
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_BUFFER, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_BUFFER, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_BUFFER, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       if (s_intTypes[dataTypeNdx] != glu::TYPE_INT)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_BUFFER, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_BUFFER, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_BUFFER, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_BUFFER, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_BUFFER, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_BUFFER, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       // SAMPLER_2D_MULTISAMPLE_ARRAY
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY, s_floatTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       if (s_intTypes[dataTypeNdx] != glu::TYPE_INT_VEC3)
+                                       {
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_INT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_INT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY, s_intTypes[dataTypeNdx], glu::TYPE_INT));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY, s_uintTypes[dataTypeNdx], glu::TYPE_INT));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               ctx.endSection();
+                       }
+               }
+               ctx.endSection();
+       }
+}
+
+void texel_fetch_invalid_sample (NegativeTestContext& ctx)
+{
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_intTypes));
+       DE_ASSERT(DE_LENGTH_OF_ARRAY(s_floatTypes) == DE_LENGTH_OF_ARRAY(s_uintTypes));
+
+       if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported(getDataTypeExtension(glu::TYPE_SAMPLER_CUBE_ARRAY)))
+       {
+               ctx.beginSection("texelFetch: Invalid sample type.");
+               for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+               {
+                       if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+                       {
+                               ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                               for (int dataTypeNdx = 0; dataTypeNdx < DE_LENGTH_OF_ARRAY(s_floatTypes); ++dataTypeNdx)
+                               {
+                                       // SAMPLER_2D_MULTISAMPLE
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       // SAMPLER_2D_MULTISAMPLE_ARRAY
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_floatTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       if (s_intTypes[dataTypeNdx] != glu::TYPE_INT)
+                                       {
+                                               // SAMPLER_2D_MULTISAMPLE
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+
+                                               // SAMPLER_2D_MULTISAMPLE_ARRAY
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                               {
+                                                       const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_intTypes[dataTypeNdx]));
+                                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                               }
+                                       }
+
+                                       // SAMPLER_2D_MULTISAMPLE
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE, glu::TYPE_INT_VEC2, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+
+                                       // SAMPLER_2D_MULTISAMPLE_ARRAY
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                                       {
+                                               const std::string shaderSource(genShaderSourceTexelFetch(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_MULTISAMPLE_ARRAY, glu::TYPE_INT_VEC3, s_uintTypes[dataTypeNdx]));
+                                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                                       }
+                               }
+                               ctx.endSection();
+                       }
+               }
+               ctx.endSection();
+       }
+}
+
+// EmitVertex, EndPrimitive
+std::string genShaderSourceGeometry (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function)
+{
+       DE_ASSERT(function == SHADER_FUNCTION_EMIT_VERTEX || function == SHADER_FUNCTION_END_PRIMITIVE);
+
+       std::ostringstream source;
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n";
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_EMIT_VERTEX:
+                       source << "    EmitVertex();\n";
+                       break;
+
+               case SHADER_FUNCTION_END_PRIMITIVE:
+                       source << "    EndPrimitive();\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+void emit_vertex (NegativeTestContext& ctx)
+{
+       ctx.beginSection("EmitVertex.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       if (s_shaders[shaderNdx] == glu::SHADERTYPE_GEOMETRY)
+                               continue;
+
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       const std::string shaderSource =        genShaderSourceGeometry(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_EMIT_VERTEX);
+                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void end_primitive (NegativeTestContext& ctx)
+{
+       ctx.beginSection("EndPrimitieve.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       if (s_shaders[shaderNdx] == glu::SHADERTYPE_GEOMETRY)
+                               continue;
+
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       const std::string shaderSource =        genShaderSourceGeometry(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_END_PRIMITIVE);
+                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// textureGrad
+std::string genShaderSourceTextureGrad (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType dpdxDataType, glu::DataType dpdyDataType)
+{
+       std::ostringstream source;
+
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderExtensionDeclaration(getDataTypeExtension(samplerDataType))
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    mediump " << declareAndInitializeShaderVariable(pDataType, "P")
+                       << "    mediump " << declareAndInitializeShaderVariable(dpdxDataType, "dPdx")
+                       << "    mediump " << declareAndInitializeShaderVariable(dpdyDataType, "dPdy")
+                       << "    textureGrad(sampler, P, dPdx, dPdy);\n"
+                       << "}\n";
+
+       return source.str();
+}
+
+void texture_grad (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError, ctx.isExtensionSupported("GL_EXT_texture_cube_map_array") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)), "Test requires support for GL_EXT_texture_cube_map_array or version 3.2.");
+
+       ctx.beginSection("textureGrad.");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGrad(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// textureGather
+std::string genShaderSourceTextureGather (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType thirdArgument)
+{
+       std::ostringstream source;
+
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderExtensionDeclaration(getDataTypeExtension(samplerDataType))
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    mediump " << declareAndInitializeShaderVariable(pDataType, "P");
+
+       if (thirdArgument != glu::TYPE_LAST)
+               source  << "    mediump " << declareAndInitializeShaderVariable(thirdArgument, "arg3")
+                               << "    textureGather(sampler, P, arg3);\n";
+       else
+               source << "     textureGather(sampler, P);\n";
+
+       source << "}\n";
+
+       return source.str();
+}
+
+std::string genShaderSourceTextureGather (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType samplerDataType, glu::DataType pDataType)
+{
+       return genShaderSourceTextureGather(ctx, shaderType, samplerDataType, pDataType, glu::TYPE_LAST);
+}
+
+void texture_gather_sampler_2d (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGrad - sampler2D");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_sampler_2d_array (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGrad - sampler2DArray");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_sampler_cube (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGrad - samplerCube");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_sampler_2d_shadow (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGrad - sampler2DShadow");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_sampler_2d_array_shadow (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGrad - sampler2DArrayShadow");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, glu::TYPE_FLOAT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_sampler_cube_shadow (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGrad - samplerCubeShadow");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_SHADOW, glu::TYPE_FLOAT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_sampler_cube_array (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(
+               NotSupportedError,
+               contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported("GL_EXT_texture_cube_map_array"),
+               "Test requires extension GL_EXT_texture_cube_map_array or context version 3.2 or higher.");
+
+       ctx.beginSection("textureGrad - samplerCubeArray");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_INT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_UINT_SAMPLER_CUBE_ARRAY, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC4, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_sampler_cube_array_shadow (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(
+               NotSupportedError,
+               contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported("GL_EXT_texture_cube_map_array"),
+               "Test requires extension GL_EXT_texture_cube_map_array or context version 3.2 or higher.");
+
+       ctx.beginSection("textureGrad - samplerCubeArrayShadow");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, glu::TYPE_FLOAT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW, glu::TYPE_FLOAT_VEC4, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGather(ctx, s_shaders[shaderNdx], glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// textureGatherOffset
+std::string genShaderSourceTextureGatherOffset (NegativeTestContext& ctx, glu::ShaderType shaderType, FunctionTextureGatherOffsetModes mode, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType offsetDataType, glu::DataType fourthArgument)
+{
+       DE_ASSERT(mode < FUNCTION_TEXTURE_GATHER_OFFSET_MODE_LAST);
+
+       std::ostringstream source;
+
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    mediump " << declareAndInitializeShaderVariable(pDataType, "P")
+                       << "    mediump " << declareAndInitializeShaderVariable(offsetDataType, "offset");
+
+       switch (mode)
+       {
+               case FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP:
+               {
+                       if (fourthArgument != glu::TYPE_LAST)
+                               source  << "    mediump " << declareAndInitializeShaderVariable(fourthArgument, "comp")
+                                               << "    textureGatherOffset(sampler, P, offset, comp);\n";
+                       else
+                               source << "     textureGatherOffset(sampler, P, offset);\n";
+                       break;
+               }
+
+               case FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z:
+               {
+                       source  << "    mediump " << declareAndInitializeShaderVariable(fourthArgument, "refZ")
+                                       << "    textureGatherOffset(sampler, P, refZ, offset);\n";
+                       break;
+               }
+
+               default:
+                       DE_FATAL("Unsupported shader function overload.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+std::string genShaderSourceTextureGatherOffset (NegativeTestContext& ctx, glu::ShaderType shaderType, FunctionTextureGatherOffsetModes mode, glu::DataType samplerDataType, glu::DataType pDataType, glu::DataType offsetDataType)
+{
+       DE_ASSERT(mode == FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP);
+
+       return genShaderSourceTextureGatherOffset(ctx, shaderType, mode, samplerDataType, pDataType, offsetDataType, glu::TYPE_LAST);
+}
+
+void texture_gather_offset_sampler_2d (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGatherOffset - sampler2D");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_offset_sampler_2d_array (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGatherOffset - sampler2DArray");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_INT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_2D_ARRAY, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP, glu::TYPE_UINT_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_offset_sampler_2d_shadow (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGatherOffset - sampler2DShadow");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_2D_SHADOW, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void texture_gather_offset_sampler_2d_array_shadow (NegativeTestContext& ctx)
+{
+       ctx.beginSection("textureGatherOffset - sampler2DShadow");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, glu::TYPE_FLOAT, glu::TYPE_INT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT_VEC2, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_2D_ARRAY_SHADOW, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffset(ctx, s_shaders[shaderNdx], FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z, glu::TYPE_SAMPLER_3D, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT_VEC2, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// atomicAdd, atomicMin, atomicMax, atomicAnd, atomicOr, atomixXor, atomixExchange, atomicCompSwap
+std::string genShaderSourceAtomicOperations (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType memDataType, glu::DataType dataDataType, glu::DataType compareDataType)
+{
+       DE_ASSERT(SHADER_FUNCTION_ATOMIC_ADD <= function && function <= SHADER_FUNCTION_ATOMIC_COMP_SWAP);
+
+       std::ostringstream source;
+
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareBuffer(memDataType, "mem")
+                       << "void main()\n"
+                       << "{\n"
+                       << "    mediump " << declareAndInitializeShaderVariable(dataDataType, "data");
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_ATOMIC_ADD:                source << "    atomicAdd(mem, data);\n";                break;
+               case SHADER_FUNCTION_ATOMIC_MIN:                source << "    atomicMin(mem, data);\n";                break;
+               case SHADER_FUNCTION_ATOMIC_MAX:                source << "    atomicMax(mem, data);\n";                break;
+               case SHADER_FUNCTION_ATOMIC_AND:                source << "    atomicAnd(mem, data);\n";                break;
+               case SHADER_FUNCTION_ATOMIC_OR:                 source << "    atomicOr(mem, data);\n";                 break;
+               case SHADER_FUNCTION_ATOMIC_XOR:                source << "    atomicXor(mem, data);\n";                break;
+               case SHADER_FUNCTION_ATOMIC_EXCHANGE:   source << "    atomicExchange(mem, data);\n";   break;
+               case SHADER_FUNCTION_ATOMIC_COMP_SWAP:
+                       source  << "    mediump " << declareAndInitializeShaderVariable(compareDataType, "compare")
+                                       << "    atomicCompSwap(mem, compare, data);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+std::string genShaderSourceAtomicOperations (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType memDataType, glu::DataType dataDataType)
+{
+       DE_ASSERT(function != SHADER_FUNCTION_ATOMIC_COMP_SWAP);
+
+       return genShaderSourceAtomicOperations(ctx, shaderType, function, memDataType, dataDataType, glu::TYPE_LAST);
+}
+
+void atomic_add (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicAdd");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_ADD, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_ADD, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void atomic_min (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicMin");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_MIN, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_MIN, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void atomic_max (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicMax");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_MAX, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_MAX, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void atomic_and (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicAnd");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_AND, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_AND, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void atomic_or (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicOr");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_OR, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_OR, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void atomic_xor (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicXor");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_XOR, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_XOR, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void atomic_exchange (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicExchange");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_EXCHANGE, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_EXCHANGE, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void atomic_comp_swap (NegativeTestContext& ctx)
+{
+       ctx.beginSection("atomicCompSwap");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_COMP_SWAP, glu::TYPE_UINT, glu::TYPE_INT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_COMP_SWAP, glu::TYPE_INT, glu::TYPE_UINT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceAtomicOperations(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_ATOMIC_COMP_SWAP, glu::TYPE_INT, glu::TYPE_INT, glu::TYPE_UINT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// interpolatedAtCentroid, interpolatedAtSample, interpolateAtOffset,
+std::string genShaderSourceInterpolateAt (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType interpolantDataType, glu::DataType secondArgumentDataType)
+{
+       DE_ASSERT(function >= SHADER_FUNCTION_INTERPOLATED_AT_CENTROID && function <= SHADER_FUNCTION_INTERPOLATED_AT_OFFSET);
+
+       const bool                      isES32 = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       std::ostringstream      source;
+
+       source  << (isES32 ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << (isES32 ? "" : getShaderExtensionDeclaration("GL_OES_shader_multisample_interpolation"))
+                       << declareShaderInput(interpolantDataType, "interpolant")
+                       << "void main()\n"
+                       << "{\n";
+
+       switch (function)
+       {
+               case SHADER_FUNCTION_INTERPOLATED_AT_CENTROID:
+                       source << "    interpolateAtCentroid(interpolant);\n";
+                       break;
+
+               case SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE:
+                       source  << "    mediump " << declareAndInitializeShaderVariable(secondArgumentDataType, "sample")
+                                       << "    interpolateAtSample(interpolant, sample);\n";
+                       break;
+
+               case SHADER_FUNCTION_INTERPOLATED_AT_OFFSET:
+                       source  << "    mediump " << declareAndInitializeShaderVariable(secondArgumentDataType, "offset")
+                                       << "    interpolateAtOffset(interpolant, offset);\n";
+                       break;
+
+               default:
+                       DE_FATAL("Unsupported shader function.");
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+std::string genShaderSourceInterpolateAt (NegativeTestContext& ctx, glu::ShaderType shaderType, ShaderFunction function, glu::DataType interpolantDataType)
+{
+       DE_ASSERT(function == SHADER_FUNCTION_INTERPOLATED_AT_CENTROID);
+
+       return genShaderSourceInterpolateAt(ctx, shaderType, function, interpolantDataType, glu::TYPE_LAST);
+}
+
+void interpolate_at_centroid (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported("GL_OES_shader_multisample_interpolation"),
+               "This test requires a context version 3.2 or higher.");
+
+       ctx.beginSection("interpolateAtCentroid");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       if (s_shaders[shaderNdx] == glu::SHADERTYPE_FRAGMENT)
+                       {
+                               const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_CENTROID, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       else
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_CENTROID, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_CENTROID, glu::TYPE_FLOAT_VEC2));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_CENTROID, glu::TYPE_FLOAT_VEC3));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_CENTROID, glu::TYPE_FLOAT_VEC4));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void interpolate_at_sample (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported("GL_OES_shader_multisample_interpolation"),
+               "This test requires a context version 3.2 or higher.");
+
+       ctx.beginSection("interpolateAtSample");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       if (s_shaders[shaderNdx] == glu::SHADERTYPE_FRAGMENT)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_INT, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       else
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT_VEC2, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT_VEC3, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_SAMPLE, glu::TYPE_FLOAT_VEC4, glu::TYPE_INT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+void interpolate_at_offset (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported("GL_OES_shader_multisample_interpolation"),
+               "This test requires a context version 3.2 or higher.");
+
+       ctx.beginSection("interpolateAtOffset");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       if (s_shaders[shaderNdx] == glu::SHADERTYPE_FRAGMENT)
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_INT, glu::TYPE_FLOAT_VEC2));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       else
+                       {
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT, glu::TYPE_FLOAT_VEC2));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT_VEC2, glu::TYPE_FLOAT_VEC2));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT_VEC3, glu::TYPE_FLOAT_VEC2));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                               {
+                                       const std::string shaderSource(genShaderSourceInterpolateAt(ctx, s_shaders[shaderNdx], SHADER_FUNCTION_INTERPOLATED_AT_OFFSET, glu::TYPE_FLOAT_VEC4, glu::TYPE_FLOAT_VEC2));
+                                       verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                               }
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+
+// textureGatherOffsets
+std::string genShaderSourceTextureGatherOffsets (NegativeTestContext& ctx, glu::ShaderType shaderType, const TextureGatherOffsetsTestSpec& spec)
+{
+       std::ostringstream source;
+
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << declareShaderUniform(spec.samplerDataType, "sampler")
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    mediump " << declareAndInitializeShaderVariable(spec.pDataType, "P")
+                       << "    mediump " << (spec.offsetIsConst ? "const " : "") << declareShaderArrayVariable(spec.offsetsDataType, "offsets", spec.offsetArraySize) << "\n";
+
+       switch (spec.mode)
+       {
+               case FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP:
+               {
+                       if (spec.fourthArgument != glu::TYPE_LAST)
+                               source  << "    mediump " << declareAndInitializeShaderVariable(spec.fourthArgument, "comp")
+                                               << "    textureGatherOffsets(sampler, P, offsets, comp);\n";
+                       else
+                               source << "     textureGatherOffsets(sampler, P, offsets);\n";
+                       break;
+               }
+
+               case FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z:
+               {
+                       source  << "    mediump " << declareAndInitializeShaderVariable(spec.fourthArgument, "refZ")
+                                       << "    textureGatherOffsets(sampler, P, refZ, offsets);\n";
+                       break;
+               }
+
+               default:
+                       DE_FATAL("Unsupported shader function overload.");
+                       break;
+       }
+
+       source << "}\n";
+       return source.str();
+}
+
+void texture_gather_offsets (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported("GL_EXT_gpu_shader5"),
+               "This test requires a context version 3.2 or higher.");
+
+       const struct TextureGatherOffsetsTestSpec testSpecs[] =
+       {
+                       //mode                                                                          samplerDataType                                         pDataType                               offsetsDataType                 fourthArgument          offsetIsConst   offsetArraySize
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_LAST,         false,                  4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_LAST,         true,                   3,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT,                glu::TYPE_INT_VEC2,             glu::TYPE_LAST,         true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT,                  glu::TYPE_LAST,         true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_INT,          false,                  4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_INT,          true,                   3,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT,                glu::TYPE_INT_VEC2,             glu::TYPE_INT,          true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D,                           glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT,                  glu::TYPE_INT,          true,                   4,              },
+
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_LAST,         false,                  4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_LAST,         true,                   3,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT,                glu::TYPE_INT_VEC2,             glu::TYPE_LAST,         true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT,                  glu::TYPE_LAST,         true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_INT,          false,                  4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_INT,          true,                   3,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT,                glu::TYPE_INT_VEC2,             glu::TYPE_INT,          true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_COMP,       glu::TYPE_SAMPLER_2D_ARRAY,                     glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT,                  glu::TYPE_INT,          true,                   4,              },
+
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_SHADOW,            glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        false,                  4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_SHADOW,            glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        true,                   3,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_SHADOW,            glu::TYPE_FLOAT,                glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_SHADOW,            glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT,                  glu::TYPE_FLOAT,        true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_SHADOW,            glu::TYPE_FLOAT_VEC2,   glu::TYPE_INT_VEC2,             glu::TYPE_INT,          true,                   4,              },
+
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,      glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        false,                  4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,      glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        true,                   3,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,      glu::TYPE_FLOAT,                glu::TYPE_INT_VEC2,             glu::TYPE_FLOAT,        true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,      glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT,                  glu::TYPE_FLOAT,        true,                   4,              },
+               {       FUNCTION_TEXTURE_GATHER_OFFSET_MODE_REF_Z,      glu::TYPE_SAMPLER_2D_ARRAY_SHADOW,      glu::TYPE_FLOAT_VEC3,   glu::TYPE_INT_VEC2,             glu::TYPE_INT,          true,                   4,              },
+       };
+
+       ctx.beginSection("textureGatherOffsets");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       for (int specNdx = 0; specNdx < DE_LENGTH_OF_ARRAY(testSpecs); ++specNdx)
+                       {
+                               const std::string shaderSource(genShaderSourceTextureGatherOffsets(ctx, s_shaders[shaderNdx], testSpecs[specNdx]));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+// fma
+std::string genShaderSourceFma (NegativeTestContext& ctx, glu::ShaderType shaderType, glu::DataType aDataType, glu::DataType bDataType, glu::DataType cDataType)
+{
+       std::ostringstream source;
+
+       source  << (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ? glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES)) << "\n"
+                       << getShaderInitialization(ctx, shaderType)
+                       << "void main(void)\n"
+                       << "{\n"
+                       << "    mediump " << declareAndInitializeShaderVariable(aDataType, "a")
+                       << "    mediump " << declareAndInitializeShaderVariable(bDataType, "b")
+                       << "    mediump " << declareAndInitializeShaderVariable(cDataType, "c")
+                       << "    fma(a, b, c);"
+                       << "}\n";
+       return source.str();
+}
+
+void fma (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.isExtensionSupported("GL_EXT_gpu_shader5"),
+               "This test requires a context version 3.2 or higher.");
+
+       ctx.beginSection("fma");
+       for (int shaderNdx = 0; shaderNdx < DE_LENGTH_OF_ARRAY(s_shaders); ++shaderNdx)
+       {
+               if (ctx.isShaderSupported(s_shaders[shaderNdx]))
+               {
+                       ctx.beginSection("Verify shader: " + std::string(getShaderTypeName(s_shaders[shaderNdx])));
+                       {
+                               const std::string shaderSource(genShaderSourceFma(ctx, s_shaders[shaderNdx], glu::TYPE_FLOAT, glu::TYPE_FLOAT, glu::TYPE_INT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceFma(ctx, s_shaders[shaderNdx], glu::TYPE_FLOAT, glu::TYPE_INT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       {
+                               const std::string shaderSource(genShaderSourceFma(ctx, s_shaders[shaderNdx], glu::TYPE_INT, glu::TYPE_FLOAT, glu::TYPE_FLOAT));
+                               verifyShader(ctx, s_shaders[shaderNdx], shaderSource);
+                       }
+                       ctx.endSection();
+               }
+       }
+       ctx.endSection();
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeShaderFunctionTestFunctions ()
+{
+       const FunctionContainer funcs[] =
+       {
+               {bitfield_extract_invalid_value_type,                           "bitfield_extract_invalid_value_type",                          "Invalid usage of bitfieldExtract."                     },
+               {bitfield_extract_invalid_offset_type,                          "bitfield_extract_invalid_offset_type",                         "Invalid usage of bitfieldExtract."                     },
+               {bitfield_extract_invalid_bits_type,                            "bitfield_extract_invalid_bits_type",                           "Invalid usage of bitfieldExtract."                     },
+               {bitfield_insert_invalid_base_type,                                     "bitfield_insert_invalid_base_type",                            "Invalid usage of bitfieldInsert."                      },
+               {bitfield_insert_invalid_insert_type,                           "bitfield_insert_invalid_insert_type",                          "Invalid usage of bitfieldInsert."                      },
+               {bitfield_insert_invalid_offset_type,                           "bitfield_insert_invalid_offset_type",                          "Invalid usage of bitfieldInsert."                      },
+               {bitfield_insert_invalid_bits_type,                                     "bitfield_insert_invalid_bits_type",                            "Invalid usage of bitfieldInsert."                      },
+               {bitfield_reverse,                                                                      "bitfield_reverse",                                                                     "Invalid usage of bitfieldReverse."                     },
+               {bit_count,                                                                                     "bit_count",                                                                            "Invalid usage of bitCount."                            },
+               {find_msb,                                                                                      "find_msb",                                                                                     "Invalid usage of findMSB."                                     },
+               {find_lsb,                                                                                      "find_lsb",                                                                                     "Invalid usage of findLSB."                                     },
+               {uadd_carry_invalid_x,                                                          "uadd_carry_invalid_x",                                                         "Invalid usage of uaddCarry."                           },
+               {uadd_carry_invalid_y,                                                          "uadd_carry_invalid_y",                                                         "Invalid usage of uaddCarry."                           },
+               {uadd_carry_invalid_carry,                                                      "uadd_carry_invalid_carry",                                                     "Invalid usage of uaddCarry."                           },
+               {usub_borrow_invalid_x,                                                         "usub_borrow_invalid_x",                                                        "Invalid usage of usubBorrow."                          },
+               {usub_borrow_invalid_y,                                                         "usub_borrow_invalid_y",                                                        "Invalid usage of usubBorrow."                          },
+               {usub_borrow_invalid_borrow,                                            "usub_borrow_invalid_borrow",                                           "Invalid usage of usubBorrow."                          },
+               {umul_extended_invalid_x,                                                       "umul_extended_invalid_x",                                                      "Invalid usage of umulExtended."                        },
+               {umul_extended_invalid_y,                                                       "umul_extended_invalid_y",                                                      "Invalid usage of umulExtended."                        },
+               {umul_extended_invalid_msb,                                                     "umul_extended_invalid_msb",                                            "Invalid usage of umulExtended."                        },
+               {umul_extended_invalid_lsb,                                                     "umul_extended_invalid_lsb",                                            "Invalid usage of umulExtended."                        },
+               {imul_extended_invalid_x,                                                       "imul_extended_invalid_x",                                                      "Invalid usage of imulExtended."                        },
+               {imul_extended_invalid_y,                                                       "imul_extended_invalid_y",                                                      "Invalid usage of imulExtended."                        },
+               {imul_extended_invalid_msb,                                                     "imul_extended_invalid_msb",                                            "Invalid usage of imulExtended."                        },
+               {imul_extended_invalid_lsb,                                                     "imul_extended_invalid_lsb",                                            "Invalid usage of imulExtended."                        },
+               {frexp_invalid_x,                                                                       "frexp_invalid_x",                                                                      "Invalid usage of frexp."                                       },
+               {frexp_invalid_exp,                                                                     "frexp_invalid_exp",                                                            "Invalid usage of frexp."                                       },
+               {ldexp_invalid_x,                                                                       "ldexp_invalid_x",                                                                      "Invalid usage of ldexp."                                       },
+               {ldexp_invalid_exp,                                                                     "ldexp_invalid_exp",                                                            "Invalid usage of ldexp."                                       },
+               {pack_unorm_4x8,                                                                        "pack_unorm_4x8",                                                                       "Invalid usage of packUnorm4x8."                        },
+               {pack_snorm_4x8,                                                                        "pack_snorm_4x8",                                                                       "Invalid usage of packSnorm4x8."                        },
+               {unpack_snorm_4x8,                                                                      "unpack_snorm_4x8",                                                                     "Invalid usage of unpackSnorm4x8."                      },
+               {unpack_unorm_4x8,                                                                      "unpack_unorm_4x8",                                                                     "Invalid usage of unpackUnorm4x8."                      },
+               {texture_size_invalid_sampler,                                          "texture_size_invalid_sampler",                                         "Invalid usage of textureSize."                         },
+               {texture_size_invalid_lod,                                                      "texture_size_invalid_lod",                                                     "Invalid usage of textureSize."                         },
+               {texture_invalid_p,                                                                     "texture_invalid_p",                                                            "Invalid usage of texture."                                     },
+               {texture_invalid_bias_or_compare,                                       "texture_invalid_bias_or_compare",                                      "Invalid usage of texture."                                     },
+               {texture_lod_invalid_p,                                                         "texture_lod_invalid_p",                                                        "Invalid usage of textureLod."                          },
+               {texture_lod_invalid_lod,                                                       "texture_lod_invalid_lod",                                                      "Invalid usage of textureLod."                          },
+               {texel_fetch_invalid_p,                                                         "texel_fetch_invalid_p",                                                        "Invalid usage of texelFetch."                          },
+               {texel_fetch_invalid_sample,                                            "texel_fetch_invalid_sample",                                           "Invalid usage of texelFetch."                          },
+               {emit_vertex,                                                                           "emit_vertex",                                                                          "Invalid usage of EmitVertex."                          },
+               {end_primitive,                                                                         "end_primitive",                                                                        "Invalid usage of EndPrimitive."                        },
+               {texture_grad,                                                                          "texture_grad",                                                                         "Invalid usage of textureGrad."                         },
+               {texture_gather_sampler_2d,                                                     "texture_gather_sampler_2d",                                            "Invalid usage of textureGather."                       },
+               {texture_gather_sampler_2d_array,                                       "texture_gather_sampler_2d_array",                                      "Invalid usage of textureGather."                       },
+               {texture_gather_sampler_cube,                                           "texture_gather_sampler_cube",                                          "Invalid usage of textureGather."                       },
+               {texture_gather_sampler_2d_shadow,                                      "texture_gather_sampler_2d_shadow",                                     "Invalid usage of textureGather."                       },
+               {texture_gather_sampler_2d_array_shadow,                        "texture_gather_sampler_2d_array_shadow",                       "Invalid usage of textureGather."                       },
+               {texture_gather_sampler_cube_shadow,                            "texture_gather_sampler_cube_shadow",                           "Invalid usage of textureGather."                       },
+               {texture_gather_sampler_cube_array,                                     "texture_gather_sampler_cube_array",                            "Invalid usage of textureGather."                       },
+               {texture_gather_sampler_cube_array_shadow,                      "texture_gather_sampler_cube_array_shadow",                     "Invalid usage of textureGather."                       },
+               {texture_gather_offset_sampler_2d,                                      "texture_gather_offset_sampler_2d",                                     "Invalid usage of textureGatherOffset."         },
+               {texture_gather_offset_sampler_2d_array,                        "texture_gather_offset_sampler_2d_array",                       "Invalid usage of textureGatherOffset."         },
+               {texture_gather_offset_sampler_2d_shadow,                       "texture_gather_offset_sampler_2d_shadow",                      "Invalid usage of textureGatherOffset."         },
+               {texture_gather_offset_sampler_2d_array_shadow,         "texture_gather_offset_sampler_2d_array_shadow",        "Invalid usage of textureGatherOffset."         },
+               {texture_gather_offsets,                                                        "texture_gather_offsets",                                                       "Invalid usage of textureGatherOffsets."        },
+               {atomic_add,                                                                            "atomic_add",                                                                           "Invalid usage of atomicAdd."                           },
+               {atomic_min,                                                                            "atomic_min",                                                                           "Invalid usage of atomicMin."                           },
+               {atomic_max,                                                                            "atomic_max",                                                                           "Invalid usage of atomicMax."                           },
+               {atomic_and,                                                                            "atomic_and",                                                                           "Invalid usage of atomicAnd."                           },
+               {atomic_or,                                                                                     "atomic_or",                                                                            "Invalid usage of atomicOr."                            },
+               {atomic_xor,                                                                            "atomic_xor",                                                                           "Invalid usage of atomicXor."                           },
+               {atomic_exchange,                                                                       "atomic_exchange",                                                                      "Invalid usage of atomicExchange."                      },
+               {atomic_comp_swap,                                                                      "atomic_comp_swap",                                                                     "Invalid usage of atomicCompSwap."                      },
+               {interpolate_at_centroid,                                                       "interpolate_at_centroid",                                                      "Invalid usage of interpolateAtCentroid."       },
+               {interpolate_at_sample,                                                         "interpolate_at_sample",                                                        "Invalid usage of interpolateAtSample."         },
+               {interpolate_at_offset,                                                         "interpolate_at_offset",                                                        "Invalid usage of interpolateAtOffset."         },
+               {fma,                                                                                           "fma",                                                                                          "Invalid usage of fma."                                         },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeShaderFunctionTests.hpp b/modules/gles31/functional/es31fNegativeShaderFunctionTests.hpp
new file mode 100644 (file)
index 0000000..6913e7e
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVESHADERFUNCTIONTESTS_HPP
+#define _ES31FNEGATIVESHADERFUNCTIONTESTS_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 Function Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeShaderFunctionTestFunctions ();
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVESHADERFUNCTIONTESTS_HPP
index 3023757..968d0d7 100644 (file)
@@ -2344,13 +2344,6 @@ void texparameterIiv (NegativeTestContext& ctx)
        ctx.endSection();
 
        ctx.beginSection("GL_INVALID_OPERATION is generated if target is GL_TEXTURE_2D_MULTISAMPLE or GL_TEXTURE_2D_MULTISAMPLE_ARRAY and pname GL_TEXTURE_BASE_LEVEL is not 0.");
-       textureMode[0] = -1;
-       textureMode[1] = -1;
-       ctx.glTexParameterIiv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL, textureMode);
-       ctx.expectError(GL_INVALID_OPERATION);
-       ctx.glTexParameterIiv(GL_TEXTURE_2D_MULTISAMPLE_ARRAY, GL_TEXTURE_BASE_LEVEL, textureMode);
-       ctx.expectError(GL_INVALID_OPERATION);
-
        textureMode[0] = 1;
        textureMode[1] = 1;
        ctx.glTexParameterIiv(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_BASE_LEVEL, textureMode);
@@ -3405,9 +3398,14 @@ void compressedteximage3d_invalid_width_height (NegativeTestContext& ctx)
 {
        if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.getContextInfo().isExtensionSupported("GL_OES_texture_cube_map_array"))
        {
+               const int                               width           = 4;
+               const int                               height          = 6;
+               const int                               depth           = 6;
+               const int                               blockSize       = 16;
+               const int                               imageSize       = divRoundUp(width, 4) * divRoundUp(height, 4) * depth * blockSize;
+               std::vector<GLubyte>    data            (imageSize);
                ctx.beginSection("GL_INVALID_VALUE is generated if target is GL_TEXTURE_CUBE_MAP_ARRAY and width and height are not equal.");
-               // TODO: [2015-12-17 dag]: validate that we're triggering the error for the correct reasons
-               ctx.glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_COMPRESSED_RGBA_ASTC_4x4, 4, 6, 1, 0, 0, 0);
+               ctx.glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_COMPRESSED_RGBA_ASTC_4x4, width, height, depth, 0, imageSize, &data[0]);
                ctx.expectError(GL_INVALID_VALUE);
                ctx.endSection();
        }
@@ -3415,15 +3413,16 @@ void compressedteximage3d_invalid_width_height (NegativeTestContext& ctx)
 
 void compressedteximage3d_invalid_format (NegativeTestContext& ctx)
 {
-       ctx.beginSection("GL_INVALID_OPERATION is generated if target is GL_TEXTURE_3D and the internal format does not support 3D textures.");
-       ctx.glCompressedTexImage3D(GL_TEXTURE_3D, 0, GL_COMPRESSED_RGB8_ETC2, 4, 4, 1, 0, etc2DataSize(4, 4), 0);
-       ctx.expectError(GL_INVALID_OPERATION);
-       ctx.endSection();
-
        if (contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) || ctx.getContextInfo().isExtensionSupported("GL_OES_texture_cube_map_array"))
        {
+               const int                               width           = 4;
+               const int                               height          = 4;
+               const int                               depth           = 6;
+               const int                               blockSize       = 16;
+               const int                               imageSize       = divRoundUp(width, 4) * divRoundUp(height, 4) * depth * blockSize;
+               std::vector<GLubyte>    data            (imageSize);
                ctx.beginSection("GL_INVALID_OPERATION is generated if target is GL_TEXTURE_CUBE_MAP_ARRAY and the internal format does not support cube map array textures.");
-               ctx.glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_COMPRESSED_R11_EAC, 4, 4, 1, 0, 0, 0);
+               ctx.glCompressedTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, width, height, depth, 0, imageSize, &data[0]);
                ctx.expectError(GL_INVALID_OPERATION);
                ctx.endSection();
        }
@@ -3870,7 +3869,7 @@ void texstorage3d_invalid_binding (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, 0);
-               ctx.glTexStorage3D      (GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 4, 4, 4);
+               ctx.glTexStorage3D      (GL_TEXTURE_CUBE_MAP_ARRAY, 1, GL_RGBA8, 4, 4, 6);
                ctx.expectError         (GL_INVALID_OPERATION);
        }
        ctx.endSection();
@@ -3941,10 +3940,6 @@ void texstorage3d_invalid_levels (NegativeTestContext& ctx)
 
        if (isES32 || ctx.getContextInfo().isExtensionSupported("GL_OES_texture_cube_map_array"))
        {
-               ctx.glTexStorage3D      (GL_TEXTURE_CUBE_MAP_ARRAY, log2MaxSize, GL_RGBA8, 8, 2, 6);
-               ctx.expectError         (GL_INVALID_OPERATION);
-               ctx.glTexStorage3D      (GL_TEXTURE_CUBE_MAP_ARRAY, log2MaxSize, GL_RGBA8, 2, 8, 6);
-               ctx.expectError         (GL_INVALID_OPERATION);
                ctx.glTexStorage3D      (GL_TEXTURE_CUBE_MAP_ARRAY, log2MaxSize, GL_RGBA8, 2, 2, 6);
                ctx.expectError         (GL_INVALID_OPERATION);
                ctx.glTexStorage3D      (GL_TEXTURE_CUBE_MAP_ARRAY, log2MaxSize, GL_RGBA8, 8, 8, 6);
index 8fa3fc6..2dcb8e1 100644 (file)
@@ -687,7 +687,7 @@ void draw_elements_base_vertex (NegativeTestContext& ctx)
        ctx.glGenFramebuffers(1, &fbo);
        ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
-       ctx.glDrawElementsBaseVertex(GL_POINTS, -1, GL_UNSIGNED_INT, vertices, 1);
+       ctx.glDrawElementsBaseVertex(GL_POINTS, 1, GL_UNSIGNED_INT, vertices, 1);
        ctx.expectError(GL_INVALID_FRAMEBUFFER_OPERATION);
        ctx.glBindFramebuffer(GL_FRAMEBUFFER, 0);
        ctx.glDeleteFramebuffers(1, &fbo);
index f1b06b9..9440d47 100644 (file)
@@ -82,6 +82,7 @@ enum TextureType
        TEXTURE_TYPE_CUBE,
        TEXTURE_TYPE_2D_ARRAY,
        TEXTURE_TYPE_3D,
+       TEXTURE_TYPE_CUBE_ARRAY,
 
        TEXTURE_TYPE_LAST
 };
@@ -148,8 +149,14 @@ static TextureType getTextureType (glu::DataType samplerType)
                case glu::TYPE_UINT_SAMPLER_3D:
                        return TEXTURE_TYPE_3D;
 
+               case glu::TYPE_SAMPLER_CUBE_ARRAY:
+               case glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW:
+               case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
+               case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
+                       return TEXTURE_TYPE_CUBE_ARRAY;
+
                default:
-                       throw tcu::InternalError("Invalid sampler type");
+                       TCU_THROW(InternalError, "Invalid sampler type");
        }
 }
 
@@ -158,7 +165,8 @@ static bool isShadowSampler (glu::DataType samplerType)
        return samplerType == glu::TYPE_SAMPLER_1D_SHADOW               ||
                   samplerType == glu::TYPE_SAMPLER_2D_SHADOW           ||
                   samplerType == glu::TYPE_SAMPLER_2D_ARRAY_SHADOW     ||
-                  samplerType == glu::TYPE_SAMPLER_CUBE_SHADOW;
+                  samplerType == glu::TYPE_SAMPLER_CUBE_SHADOW         ||
+                  samplerType == glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW;
 }
 
 static glu::DataType getSamplerOutputType (glu::DataType samplerType)
@@ -170,12 +178,14 @@ static glu::DataType getSamplerOutputType (glu::DataType samplerType)
                case glu::TYPE_SAMPLER_CUBE:
                case glu::TYPE_SAMPLER_2D_ARRAY:
                case glu::TYPE_SAMPLER_3D:
+               case glu::TYPE_SAMPLER_CUBE_ARRAY:
                        return glu::TYPE_FLOAT_VEC4;
 
                case glu::TYPE_SAMPLER_1D_SHADOW:
                case glu::TYPE_SAMPLER_2D_SHADOW:
                case glu::TYPE_SAMPLER_CUBE_SHADOW:
                case glu::TYPE_SAMPLER_2D_ARRAY_SHADOW:
+               case glu::TYPE_SAMPLER_CUBE_ARRAY_SHADOW:
                        return glu::TYPE_FLOAT;
 
                case glu::TYPE_INT_SAMPLER_1D:
@@ -183,6 +193,7 @@ static glu::DataType getSamplerOutputType (glu::DataType samplerType)
                case glu::TYPE_INT_SAMPLER_CUBE:
                case glu::TYPE_INT_SAMPLER_2D_ARRAY:
                case glu::TYPE_INT_SAMPLER_3D:
+               case glu::TYPE_INT_SAMPLER_CUBE_ARRAY:
                        return glu::TYPE_INT_VEC4;
 
                case glu::TYPE_UINT_SAMPLER_1D:
@@ -190,10 +201,11 @@ static glu::DataType getSamplerOutputType (glu::DataType samplerType)
                case glu::TYPE_UINT_SAMPLER_CUBE:
                case glu::TYPE_UINT_SAMPLER_2D_ARRAY:
                case glu::TYPE_UINT_SAMPLER_3D:
+               case glu::TYPE_UINT_SAMPLER_CUBE_ARRAY:
                        return glu::TYPE_UINT_VEC4;
 
                default:
-                       throw tcu::InternalError("Invalid sampler type");
+                       TCU_THROW(InternalError, "Invalid sampler type");
        }
 }
 
@@ -214,7 +226,7 @@ static tcu::TextureFormat getSamplerTextureFormat (glu::DataType samplerType)
                case glu::TYPE_UINT:    return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8);
 
                default:
-                       throw tcu::InternalError("Invalid sampler type");
+                       TCU_THROW(InternalError, "Invalid sampler type");
        }
 }
 
@@ -225,16 +237,17 @@ static glu::DataType getSamplerCoordType (glu::DataType samplerType)
 
        switch (texType)
        {
-               case TEXTURE_TYPE_1D:           numCoords = 1;  break;
-               case TEXTURE_TYPE_2D:           numCoords = 2;  break;
-               case TEXTURE_TYPE_2D_ARRAY:     numCoords = 3;  break;
-               case TEXTURE_TYPE_CUBE:         numCoords = 3;  break;
-               case TEXTURE_TYPE_3D:           numCoords = 3;  break;
+               case TEXTURE_TYPE_1D:                   numCoords = 1;  break;
+               case TEXTURE_TYPE_2D:                   numCoords = 2;  break;
+               case TEXTURE_TYPE_2D_ARRAY:             numCoords = 3;  break;
+               case TEXTURE_TYPE_CUBE:                 numCoords = 3;  break;
+               case TEXTURE_TYPE_3D:                   numCoords = 3;  break;
+               case TEXTURE_TYPE_CUBE_ARRAY:   numCoords = 4;  break;
                default:
-                       DE_ASSERT(false);
+                       TCU_THROW(InternalError, "Invalid texture type");
        }
 
-       if (isShadowSampler(samplerType))
+       if (isShadowSampler(samplerType) && samplerType != TYPE_SAMPLER_CUBE_ARRAY_SHADOW)
                numCoords += 1;
 
        DE_ASSERT(de::inRange(numCoords, 1, 4));
@@ -246,14 +259,14 @@ static deUint32 getGLTextureTarget (TextureType texType)
 {
        switch (texType)
        {
-               case TEXTURE_TYPE_1D:           return GL_TEXTURE_1D;
-               case TEXTURE_TYPE_2D:           return GL_TEXTURE_2D;
-               case TEXTURE_TYPE_2D_ARRAY:     return GL_TEXTURE_2D_ARRAY;
-               case TEXTURE_TYPE_CUBE:         return GL_TEXTURE_CUBE_MAP;
-               case TEXTURE_TYPE_3D:           return GL_TEXTURE_3D;
+               case TEXTURE_TYPE_1D:                   return GL_TEXTURE_1D;
+               case TEXTURE_TYPE_2D:                   return GL_TEXTURE_2D;
+               case TEXTURE_TYPE_2D_ARRAY:             return GL_TEXTURE_2D_ARRAY;
+               case TEXTURE_TYPE_CUBE:                 return GL_TEXTURE_CUBE_MAP;
+               case TEXTURE_TYPE_3D:                   return GL_TEXTURE_3D;
+               case TEXTURE_TYPE_CUBE_ARRAY:   return GL_TEXTURE_CUBE_MAP_ARRAY;
                default:
-                       DE_ASSERT(false);
-                       return 0;
+                       TCU_THROW(InternalError, "Invalid texture type");
        }
 }
 
@@ -290,6 +303,13 @@ static void setupTexture (const glw::Functions&    gl,
                        gl.texSubImage3D(texTarget, 0, 0, 0, 0, 1, 1, 1, transferFmt.format, transferFmt.dataType, color);
                        break;
 
+               case TEXTURE_TYPE_CUBE_ARRAY:
+                       gl.texStorage3D(texTarget, 1, intFormat, 1, 1, 6);
+                       for (int zoffset = 0; zoffset < 6; ++zoffset)
+                               for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
+                                       gl.texSubImage3D(texTarget, 0, 0, 0, zoffset, 1, 1, 1, transferFmt.format, transferFmt.dataType, color);
+                       break;
+
                case TEXTURE_TYPE_CUBE:
                        gl.texStorage2D(texTarget, 1, intFormat, 1, 1);
                        for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
@@ -297,7 +317,7 @@ static void setupTexture (const glw::Functions&     gl,
                        break;
 
                default:
-                       DE_ASSERT(false);
+                       TCU_THROW(InternalError, "Invalid texture type");
        }
 
        gl.texParameteri(texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -322,7 +342,7 @@ private:
                                                        SamplerIndexingCase                     (const SamplerIndexingCase&);
        SamplerIndexingCase&    operator=                                       (const SamplerIndexingCase&);
 
-       void                                    getShaderSpec                           (ShaderSpec* spec, int numSamplers, int numLookups, const int* lookupIndices) const;
+       void                                    getShaderSpec                           (ShaderSpec* spec, int numSamplers, int numLookups, const int* lookupIndices, const RenderContext& renderContext) const;
 
        const glu::ShaderType   m_shaderType;
        const glu::DataType             m_samplerType;
@@ -343,15 +363,26 @@ SamplerIndexingCase::~SamplerIndexingCase (void)
 
 void SamplerIndexingCase::init (void)
 {
-       const char* extName = "GL_EXT_gpu_shader5";
-
-       if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL &&
-               m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION &&
-               !m_context.getContextInfo().isExtensionSupported(extName))
-               throw tcu::NotSupportedError(string(extName) + " extension is required for dynamic indexing of interface blocks");
+       if (!contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               if (m_shaderType == SHADERTYPE_GEOMETRY)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"),
+                               "GL_EXT_geometry_shader extension is required to run geometry shader tests.");
+
+               if (m_shaderType == SHADERTYPE_TESSELLATION_CONTROL || m_shaderType == SHADERTYPE_TESSELLATION_EVALUATION)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"),
+                               "GL_EXT_tessellation_shader extension is required to run tessellation shader tests.");
+
+               if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"),
+                               "GL_EXT_gpu_shader5 extension is required for dynamic indexing of sampler arrays.");
+       }
 }
 
-void SamplerIndexingCase::getShaderSpec (ShaderSpec* spec, int numSamplers, int numLookups, const int* lookupIndices) const
+void SamplerIndexingCase::getShaderSpec (ShaderSpec* spec, int numSamplers, int numLookups, const int* lookupIndices, const RenderContext& renderContext) const
 {
        const char*                     samplersName    = "sampler";
        const char*                     coordsName              = "coords";
@@ -359,11 +390,13 @@ void SamplerIndexingCase::getShaderSpec (ShaderSpec* spec, int numSamplers, int
        const char*                     resultPrefix    = "result";
        const DataType          coordType               = getSamplerCoordType(m_samplerType);
        const DataType          outType                 = getSamplerOutputType(m_samplerType);
-       std::ostringstream      global, code;
+       const bool                      isES32                  = contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
+       std::ostringstream      global;
+       std::ostringstream      code;
 
        spec->inputs.push_back(Symbol(coordsName, VarType(coordType, PRECISION_HIGHP)));
 
-       if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL)
+       if (!isES32 && m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
                global << "#extension GL_EXT_gpu_shader5 : require\n";
 
        if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
@@ -400,10 +433,11 @@ void SamplerIndexingCase::getShaderSpec (ShaderSpec* spec, int numSamplers, int
                else
                        code << indicesPrefix << lookupNdx;
 
-               code << "], " << coordsName << ");\n";
+
+               code << "], " << coordsName << (m_samplerType == TYPE_SAMPLER_CUBE_ARRAY_SHADOW ? ", 0.0" : "") << ");\n";
        }
 
-       spec->version                           = GLSL_VERSION_310_ES;
+       spec->version                           = isES32 ? GLSL_VERSION_320_ES : GLSL_VERSION_310_ES;
        spec->globalDeclarations        = global.str();
        spec->source                            = code.str();
 }
@@ -443,17 +477,18 @@ SamplerIndexingCase::IterateResult SamplerIndexingCase::iterate (void)
        vector<deUint32>                                outData;
        vector<deUint8>                                 texData                         (numSamplers * texFormat.getPixelSize());
        const tcu::PixelBufferAccess    refTexAccess            (texFormat, numSamplers, 1, 1, &texData[0]);
+
        ShaderSpec                                              shaderSpec;
        de::Random                                              rnd                                     (deInt32Hash(m_samplerType) ^ deInt32Hash(m_shaderType) ^ deInt32Hash(m_indexExprType));
 
        for (int ndx = 0; ndx < numLookups; ndx++)
                lookupIndices[ndx] = rnd.getInt(0, numSamplers-1);
 
-       getShaderSpec(&shaderSpec, numSamplers, numLookups, &lookupIndices[0]);
+       getShaderSpec(&shaderSpec, numSamplers, numLookups, &lookupIndices[0], m_context.getRenderContext());
 
        coords.resize(numInvocations * getDataTypeScalarSize(coordType));
 
-       if (isShadowSampler(m_samplerType))
+       if (m_samplerType != TYPE_SAMPLER_CUBE_ARRAY_SHADOW && isShadowSampler(m_samplerType))
        {
                // Use different comparison value per invocation.
                // \note Texture uses odd values, comparison even values.
@@ -658,7 +693,7 @@ private:
                                                                BlockArrayIndexingCase          (const BlockArrayIndexingCase&);
        BlockArrayIndexingCase&         operator=                                       (const BlockArrayIndexingCase&);
 
-       void                                            getShaderSpec                           (ShaderSpec* spec, int numInstances, int numReads, const int* readIndices) const;
+       void                                            getShaderSpec                           (ShaderSpec* spec, int numInstances, int numReads, const int* readIndices, const RenderContext& renderContext) const;
 
        const BlockType                         m_blockType;
        const IndexExprType                     m_indexExprType;
@@ -682,12 +717,23 @@ BlockArrayIndexingCase::~BlockArrayIndexingCase (void)
 
 void BlockArrayIndexingCase::init (void)
 {
-       const char* extName = "GL_EXT_gpu_shader5";
-
-       if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL &&
-               m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION &&
-               !m_context.getContextInfo().isExtensionSupported(extName))
-               throw tcu::NotSupportedError(string(extName) + " extension is required for dynamic indexing of interface blocks");
+       if (!contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               if (m_shaderType == SHADERTYPE_GEOMETRY)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"),
+                               "GL_EXT_geometry_shader extension is required to run geometry shader tests.");
+
+               if (m_shaderType == SHADERTYPE_TESSELLATION_CONTROL || m_shaderType == SHADERTYPE_TESSELLATION_EVALUATION)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"),
+                               "GL_EXT_tessellation_shader extension is required to run tessellation shader tests.");
+
+               if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"),
+                               "GL_EXT_gpu_shader5 extension is required for dynamic indexing of interface blocks.");
+       }
 
        if (m_blockType == BLOCKTYPE_BUFFER)
        {
@@ -712,7 +758,7 @@ void BlockArrayIndexingCase::init (void)
        }
 }
 
-void BlockArrayIndexingCase::getShaderSpec (ShaderSpec* spec, int numInstances, int numReads, const int* readIndices) const
+void BlockArrayIndexingCase::getShaderSpec (ShaderSpec* spec, int numInstances, int numReads, const int* readIndices, const RenderContext& renderContext) const
 {
        const int                       binding                 = 2;
        const char*                     blockName               = "Block";
@@ -721,10 +767,11 @@ void BlockArrayIndexingCase::getShaderSpec (ShaderSpec* spec, int numInstances,
        const char*                     resultPrefix    = "result";
        const char*                     interfaceName   = m_blockType == BLOCKTYPE_UNIFORM ? "uniform" : "buffer";
        const char*                     layout                  = m_blockType == BLOCKTYPE_UNIFORM ? "std140" : "std430";
-       std::ostringstream      global, code;
+       const bool                      isES32                  = contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
+       std::ostringstream      global;
+       std::ostringstream      code;
 
-       if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL
-               && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
+       if (!isES32 && m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
                global << "#extension GL_EXT_gpu_shader5 : require\n";
 
        if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
@@ -767,7 +814,7 @@ void BlockArrayIndexingCase::getShaderSpec (ShaderSpec* spec, int numInstances,
                code << "].value;\n";
        }
 
-       spec->version                           = GLSL_VERSION_310_ES;
+       spec->version                           = isES32 ? GLSL_VERSION_320_ES : GLSL_VERSION_310_ES;
        spec->globalDeclarations        = global.str();
        spec->source                            = code.str();
 }
@@ -789,7 +836,7 @@ BlockArrayIndexingCase::IterateResult BlockArrayIndexingCase::iterate (void)
        for (int instanceNdx = 0; instanceNdx < numInstances; instanceNdx++)
                inValues[instanceNdx] = rnd.getUint32();
 
-       getShaderSpec(&shaderSpec, numInstances, numReads, &readIndices[0]);
+       getShaderSpec(&shaderSpec, numInstances, numReads, &readIndices[0], m_context.getRenderContext());
 
        {
                const RenderContext&    renderCtx               = m_context.getRenderContext();
@@ -878,7 +925,7 @@ private:
                                                                AtomicCounterIndexingCase               (const AtomicCounterIndexingCase&);
        AtomicCounterIndexingCase&      operator=                                               (const AtomicCounterIndexingCase&);
 
-       void                                            getShaderSpec                                   (ShaderSpec* spec, int numCounters, int numOps, const int* opIndices) const;
+       void                                            getShaderSpec                                   (ShaderSpec* spec, int numCounters, int numOps, const int* opIndices, const RenderContext& renderContext) const;
 
        const IndexExprType                     m_indexExprType;
        const glu::ShaderType           m_shaderType;
@@ -897,12 +944,23 @@ AtomicCounterIndexingCase::~AtomicCounterIndexingCase (void)
 
 void AtomicCounterIndexingCase::init (void)
 {
-       const char* extName = "GL_EXT_gpu_shader5";
-
-       if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL &&
-               m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION &&
-               !m_context.getContextInfo().isExtensionSupported(extName))
-               throw tcu::NotSupportedError(string(extName) + " extension is required for dynamic indexing of interface blocks");
+       if (!contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
+       {
+               if (m_shaderType == SHADERTYPE_GEOMETRY)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_geometry_shader"),
+                               "GL_EXT_geometry_shader extension is required to run geometry shader tests.");
+
+               if (m_shaderType == SHADERTYPE_TESSELLATION_CONTROL || m_shaderType == SHADERTYPE_TESSELLATION_EVALUATION)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_tessellation_shader"),
+                               "GL_EXT_tessellation_shader extension is required to run tessellation shader tests.");
+
+               if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
+                       TCU_CHECK_AND_THROW(NotSupportedError,
+                               m_context.getContextInfo().isExtensionSupported("GL_EXT_gpu_shader5"),
+                               "GL_EXT_gpu_shader5 extension is required for dynamic indexing of atomic counters.");
+       }
 
        if (m_shaderType == glu::SHADERTYPE_VERTEX || m_shaderType == glu::SHADERTYPE_FRAGMENT)
        {
@@ -912,18 +970,22 @@ void AtomicCounterIndexingCase::init (void)
                                                                                                                                &numAtomicCounterBuffers);
 
                if (numAtomicCounterBuffers == 0)
-                       throw tcu::NotSupportedError(string("Atomic counters not supported in ") + glu::getShaderTypeName(m_shaderType) + " shader");
+               {
+                       const string message =  "Atomic counters not supported in " + string(glu::getShaderTypeName(m_shaderType)) + " shader";
+                       TCU_THROW(NotSupportedError, message.c_str());
+               }
        }
 }
 
-void AtomicCounterIndexingCase::getShaderSpec (ShaderSpec* spec, int numCounters, int numOps, const int* opIndices) const
+void AtomicCounterIndexingCase::getShaderSpec (ShaderSpec* spec, int numCounters, int numOps, const int* opIndices, const RenderContext& renderContext) const
 {
        const char*                     indicesPrefix   = "index";
        const char*                     resultPrefix    = "result";
-       std::ostringstream      global, code;
+       const bool                      isES32                  = contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
+       std::ostringstream      global;
+       std::ostringstream      code;
 
-       if (m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL
-               && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
+       if (!isES32 && m_indexExprType != INDEX_EXPR_TYPE_CONST_LITERAL && m_indexExprType != INDEX_EXPR_TYPE_CONST_EXPRESSION)
                global << "#extension GL_EXT_gpu_shader5 : require\n";
 
        if (m_indexExprType == INDEX_EXPR_TYPE_CONST_EXPRESSION)
@@ -963,7 +1025,7 @@ void AtomicCounterIndexingCase::getShaderSpec (ShaderSpec* spec, int numCounters
                code << "]);\n";
        }
 
-       spec->version                           = GLSL_VERSION_310_ES;
+       spec->version                           = isES32 ? GLSL_VERSION_320_ES : GLSL_VERSION_310_ES;
        spec->globalDeclarations        = global.str();
        spec->source                            = code.str();
 }
@@ -985,7 +1047,7 @@ AtomicCounterIndexingCase::IterateResult AtomicCounterIndexingCase::iterate (voi
        for (int opNdx = 0; opNdx < numOps; opNdx++)
                opIndices[opNdx] = rnd.getInt(0, numOps-1);
 
-       getShaderSpec(&shaderSpec, numCounters, numOps, &opIndices[0]);
+       getShaderSpec(&shaderSpec, numCounters, numOps, &opIndices[0], m_context.getRenderContext());
 
        {
                const BufferVector              buffers                 (renderCtx, numCounters);
@@ -1168,9 +1230,12 @@ void OpaqueTypeIndexingTests::init (void)
                const char*             name;
        } shaderTypes[] =
        {
-               { SHADERTYPE_VERTEX,            "vertex"        },
-               { SHADERTYPE_FRAGMENT,          "fragment"      },
-               { SHADERTYPE_COMPUTE,           "compute"       }
+               { SHADERTYPE_VERTEX,                                    "vertex"                                        },
+               { SHADERTYPE_FRAGMENT,                                  "fragment"                                      },
+               { SHADERTYPE_COMPUTE,                                   "compute"                                       },
+               { SHADERTYPE_GEOMETRY,                                  "geometry"                                      },
+               { SHADERTYPE_TESSELLATION_CONTROL,              "tessellation_control"          },
+               { SHADERTYPE_TESSELLATION_EVALUATION,   "tessellation_evaluation"       }
        };
 
        // .sampler
@@ -1197,6 +1262,10 @@ void OpaqueTypeIndexingTests::init (void)
                        TYPE_UINT_SAMPLER_CUBE,
                        TYPE_UINT_SAMPLER_2D_ARRAY,
                        TYPE_UINT_SAMPLER_3D,
+                       TYPE_SAMPLER_CUBE_ARRAY,
+                       TYPE_SAMPLER_CUBE_ARRAY_SHADOW,
+                       TYPE_INT_SAMPLER_CUBE_ARRAY,
+                       TYPE_UINT_SAMPLER_CUBE_ARRAY
                };
 
                tcu::TestCaseGroup* const samplerGroup = new tcu::TestCaseGroup(m_testCtx, "sampler", "Sampler Array Indexing Tests");
index f60b862..bfd04e5 100644 (file)
@@ -29,6 +29,7 @@
 #include "tcuTextureUtil.hpp"
 #include "tcuVectorUtil.hpp"
 #include "tcuFormatUtil.hpp"
+#include "tcuStringTemplate.hpp"
 #include "gluContextInfo.hpp"
 #include "gluShaderProgram.hpp"
 #include "gluRenderContext.hpp"
 
 namespace deqp
 {
+
+using std::map;
+using std::string;
+
 namespace gles31
 {
 namespace Functional
@@ -271,8 +276,9 @@ MultisampleRenderCase::~MultisampleRenderCase (void)
 
 void MultisampleRenderCase::init (void)
 {
-       if (!m_context.getContextInfo().isExtensionSupported("GL_OES_sample_variables"))
-               throw tcu::NotSupportedError("Test requires GL_OES_sample_variables extension");
+       const bool      isES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       if (!isES32 && !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_variables"))
+               TCU_THROW(NotSupportedError, "Test requires GL_OES_sample_variables extension or a context version 3.2 or higher.");
 
        MultisampleShaderRenderUtil::MultisampleRenderCase::init();
 }
@@ -304,10 +310,14 @@ NumSamplesCase::~NumSamplesCase (void)
 
 std::string NumSamplesCase::genFragmentSource (int numTargetSamples) const
 {
-       std::ostringstream buf;
+       std::ostringstream      buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
-       buf <<  "#version 310 es\n"
-                       "#extension GL_OES_sample_variables : require\n"
+       buf <<  "${GLSL_VERSION_DECL}\n"
+                       "${GLSL_EXTENSION}\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n"
                        "void main (void)\n"
                        "{\n"
@@ -316,7 +326,7 @@ std::string NumSamplesCase::genFragmentSource (int numTargetSamples) const
                        "               fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool NumSamplesCase::verifyImage (const tcu::Surface& resultImage)
@@ -380,10 +390,14 @@ std::string MaxSamplesCase::genFragmentSource (int numTargetSamples) const
 {
        DE_UNREF(numTargetSamples);
 
-       std::ostringstream buf;
+       std::ostringstream      buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
-       buf <<  "#version 310 es\n"
-                       "#extension GL_OES_sample_variables : require\n"
+       buf <<  "${GLSL_VERSION_DECL}\n"
+                       "${GLSL_EXTENSION}\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n"
                        "uniform mediump int u_maxSamples;\n"
                        "void main (void)\n"
@@ -393,7 +407,7 @@ std::string MaxSamplesCase::genFragmentSource (int numTargetSamples) const
                        "               fragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool MaxSamplesCase::verifyImage (const tcu::Surface& resultImage)
@@ -464,12 +478,16 @@ std::string SampleIDCase::genFragmentSource (int numTargetSamples) const
        DE_ASSERT(numTargetSamples != 0);
 
        std::ostringstream buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
        if (m_vericationMode == VERIFY_USING_SAMPLES)
        {
                // encode the id to the output, and then verify it during sampling
-               buf <<  "#version 310 es\n"
-                               "#extension GL_OES_sample_variables : require\n"
+               buf <<  "${GLSL_VERSION_DECL}\n"
+                               "${GLSL_EXTENSION}\n"
                                "layout(location = 0) out mediump vec4 fragColor;\n"
                                "void main (void)\n"
                                "{\n"
@@ -482,8 +500,8 @@ std::string SampleIDCase::genFragmentSource (int numTargetSamples) const
                if (numTargetSamples == 1)
                {
                        // single sample, just verify value is 0
-                       buf <<  "#version 310 es\n"
-                                       "#extension GL_OES_sample_variables : require\n"
+                       buf <<  "${GLSL_VERSION_DECL}\n"
+                                       "${GLSL_EXTENSION}\n"
                                        "layout(location = 0) out mediump vec4 fragColor;\n"
                                        "void main (void)\n"
                                        "{\n"
@@ -496,8 +514,8 @@ std::string SampleIDCase::genFragmentSource (int numTargetSamples) const
                else
                {
                        // select only one sample per PIXEL
-                       buf <<  "#version 310 es\n"
-                                       "#extension GL_OES_sample_variables : require\n"
+                       buf <<  "${GLSL_VERSION_DECL}\n"
+                                       "${GLSL_EXTENSION}\n"
                                        "in highp vec4 v_position;\n"
                                        "layout(location = 0) out mediump vec4 fragColor;\n"
                                        "void main (void)\n"
@@ -516,7 +534,7 @@ std::string SampleIDCase::genFragmentSource (int numTargetSamples) const
        else
                DE_ASSERT(false);
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool SampleIDCase::verifyImage (const tcu::Surface& resultImage)
@@ -631,14 +649,18 @@ std::string SamplePosDistributionCase::genFragmentSource (int numTargetSamples)
        DE_ASSERT(numTargetSamples != 0);
        DE_UNREF(numTargetSamples);
 
-       const bool                      multisampleTarget = (m_numRequestedSamples > 0) || (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() > 1);
+       const bool                      multisampleTarget       = (m_numRequestedSamples > 0) || (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() > 1);
        std::ostringstream      buf;
+       const bool                      isES32                          = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]                               = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]                                  = isES32 ? "\n" : "#extension GL_OES_sample_variables : require\n";
 
        if (multisampleTarget)
        {
                // encode the position to the output, use red channel as error channel
-               buf <<  "#version 310 es\n"
-                               "#extension GL_OES_sample_variables : require\n"
+               buf <<  "${GLSL_VERSION_DECL}\n"
+                               "${GLSL_EXTENSION}\n"
                                "layout(location = 0) out mediump vec4 fragColor;\n"
                                "void main (void)\n"
                                "{\n"
@@ -651,8 +673,8 @@ std::string SamplePosDistributionCase::genFragmentSource (int numTargetSamples)
        else
        {
                // verify value is ok
-               buf <<  "#version 310 es\n"
-                               "#extension GL_OES_sample_variables : require\n"
+               buf <<  "${GLSL_VERSION_DECL}\n"
+                               "${GLSL_EXTENSION}\n"
                                "layout(location = 0) out mediump vec4 fragColor;\n"
                                "void main (void)\n"
                                "{\n"
@@ -663,7 +685,7 @@ std::string SamplePosDistributionCase::genFragmentSource (int numTargetSamples)
                                "}\n";
        }
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool SamplePosDistributionCase::verifyImage (const tcu::Surface& resultImage)
@@ -898,10 +920,11 @@ SamplePosCorrectnessCase::~SamplePosCorrectnessCase (void)
 
 void SamplePosCorrectnessCase::init (void)
 {
+       const bool isES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
        // requirements: per-invocation interpolation required
-       if (!m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation") &&
+       if (!isES32 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation") &&
                !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
-               throw tcu::NotSupportedError("Test requires GL_OES_shader_multisample_interpolation or GL_OES_sample_shading extension");
+               TCU_THROW(NotSupportedError, "Test requires GL_OES_shader_multisample_interpolation or GL_OES_sample_shading extension or a context version 3.2 or higher.");
 
        // prefer to use the sample qualifier path
        m_useSampleQualifier = m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation");
@@ -948,10 +971,14 @@ std::string SamplePosCorrectnessCase::genVertexSource (int numTargetSamples) con
 {
        DE_UNREF(numTargetSamples);
 
-       std::ostringstream buf;
+       std::ostringstream      buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : m_useSampleQualifier ? "#extension GL_OES_shader_multisample_interpolation : require" : "";
 
-       buf <<  "#version 310 es\n"
-               <<      ((m_useSampleQualifier) ? ("#extension GL_OES_shader_multisample_interpolation : require\n") : (""))
+       buf <<  "${GLSL_VERSION_DECL}\n"
+                       "${GLSL_EXTENSION}\n"
                <<      "in highp vec4 a_position;\n"
                <<      ((m_useSampleQualifier) ? ("sample ") : ("")) << "out highp vec4 v_position;\n"
                        "void main (void)\n"
@@ -960,19 +987,24 @@ std::string SamplePosCorrectnessCase::genVertexSource (int numTargetSamples) con
                        "       v_position = a_position;\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 std::string SamplePosCorrectnessCase::genFragmentSource (int numTargetSamples) const
 {
        DE_UNREF(numTargetSamples);
 
-       std::ostringstream buf;
+       std::ostringstream      buf;
+       const bool                      isES32                  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]                       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_SAMPLE_EXTENSION"]           = isES32 ? "" : "#extension GL_OES_sample_variables : require";
+       args["GLSL_MULTISAMPLE_EXTENSION"]      = isES32 ? "" : m_useSampleQualifier ? "#extension GL_OES_shader_multisample_interpolation : require" : "";
 
        // encode the position to the output, use red channel as error channel
-       buf <<  "#version 310 es\n"
-                       "#extension GL_OES_sample_variables : require\n"
-               <<      ((m_useSampleQualifier) ? ("#extension GL_OES_shader_multisample_interpolation : require\n") : (""))
+       buf <<  "${GLSL_VERSION_DECL}\n"
+                       "${GLSL_SAMPLE_EXTENSION}\n"
+                       "${GLSL_MULTISAMPLE_EXTENSION}\n"
                <<      ((m_useSampleQualifier) ? ("sample ") : ("")) << "in highp vec4 v_position;\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n"
                        "void main (void)\n"
@@ -1001,7 +1033,7 @@ std::string SamplePosCorrectnessCase::genFragmentSource (int numTargetSamples) c
                        "               fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool SamplePosCorrectnessCase::verifyImage (const tcu::Surface& resultImage)
@@ -1046,9 +1078,10 @@ SampleMaskBaseCase::~SampleMaskBaseCase (void)
 
 void SampleMaskBaseCase::init (void)
 {
+       const bool isES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
        // required extra extension
-       if (m_runMode == RUN_PER_TWO_SAMPLES && !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
-               throw tcu::NotSupportedError("Test requires GL_OES_sample_shading extension");
+       if (m_runMode == RUN_PER_TWO_SAMPLES && !isES32 && !m_context.getContextInfo().isExtensionSupported("GL_OES_sample_shading"))
+                       TCU_THROW(NotSupportedError, "Test requires GL_OES_sample_shading extension or a context version 3.2 or higher.");
 
        MultisampleRenderCase::init();
 }
@@ -1173,17 +1206,21 @@ std::string SampleMaskCase::genFragmentSource (int numTargetSamples) const
 {
        DE_ASSERT(numTargetSamples != 0);
 
-       const bool                      multisampleTarget = (m_numRequestedSamples > 0) || (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() > 1);
+       const bool                      multisampleTarget       = (m_numRequestedSamples > 0) || (m_renderTarget == TARGET_DEFAULT && m_context.getRenderTarget().getNumSamples() > 1);
        std::ostringstream      buf;
+       const bool                      isES32                          = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]                               = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]                                  = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
        // test supports only one sample mask word
        if (numTargetSamples > 32)
-               throw tcu::NotSupportedError("Sample count larger than 32 is not supported.");
+               TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
 
        if (multisampleTarget)
        {
-               buf <<  "#version 310 es\n"
-                               "#extension GL_OES_sample_variables : require\n"
+               buf <<  "${GLSL_VERSION_DECL}\n"
+                               "${GLSL_EXTENSION}\n"
                                "layout(location = 0) out mediump vec4 fragColor;\n"
                                "uniform highp uint u_sampleMask;\n"
                                "void main (void)\n"
@@ -1198,8 +1235,8 @@ std::string SampleMaskCase::genFragmentSource (int numTargetSamples) const
        {
                // non-multisample targets don't get multisample operations like ANDing with mask
 
-               buf <<  "#version 310 es\n"
-                               "#extension GL_OES_sample_variables : require\n"
+               buf <<  "${GLSL_VERSION_DECL}\n"
+                               "${GLSL_EXTENSION}\n"
                                "layout(location = 0) out mediump vec4 fragColor;\n"
                                "uniform highp uint u_sampleMask;\n"
                                "void main (void)\n"
@@ -1211,7 +1248,7 @@ std::string SampleMaskCase::genFragmentSource (int numTargetSamples) const
                                "}\n";
        }
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 class SampleMaskCountCase : public SampleMaskBaseCase
@@ -1329,16 +1366,20 @@ std::string SampleMaskCountCase::genFragmentSource (int numTargetSamples) const
 {
        DE_ASSERT(numTargetSamples != 0);
 
-       std::ostringstream buf;
+       std::ostringstream      buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
        // test supports only one sample mask word
        if (numTargetSamples > 32)
-               throw tcu::NotSupportedError("Sample count larger than 32 is not supported.");
+               TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
 
        // count the number of the bits in gl_SampleMask
 
-       buf <<  "#version 310 es\n"
-                       "#extension GL_OES_sample_variables : require\n"
+       buf <<  "${GLSL_VERSION_DECL}\n"
+                       "${GLSL_EXTENSION}\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n";
 
        if (m_runMode != RUN_PER_SAMPLE)
@@ -1375,7 +1416,7 @@ std::string SampleMaskCountCase::genFragmentSource (int numTargetSamples) const
                                "}\n";
        }
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 class SampleMaskUniqueCase : public SampleMaskBaseCase
@@ -1426,15 +1467,19 @@ std::string SampleMaskUniqueCase::genFragmentSource (int numTargetSamples) const
 {
        DE_ASSERT(numTargetSamples != 0);
 
-       std::ostringstream buf;
+       std::ostringstream      buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
        // test supports only one sample mask word
        if (numTargetSamples > 32)
-               throw tcu::NotSupportedError("Sample count larger than 32 is not supported.");
+               TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
 
        // find our sampleID by searching for unique bit.
-       buf <<  "#version 310 es\n"
-                       "#extension GL_OES_sample_variables : require\n"
+       buf <<  "${GLSL_VERSION_DECL}\n"
+                       "${GLSL_EXTENSION}\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n"
                        "void main (void)\n"
                        "{\n"
@@ -1464,7 +1509,7 @@ std::string SampleMaskUniqueCase::genFragmentSource (int numTargetSamples) const
                        "               fragColor = vec4(0.0, encodedSampleId, blue, 1.0);\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool SampleMaskUniqueCase::verifySampleBuffers (const std::vector<tcu::Surface>& resultBuffers)
@@ -1665,15 +1710,19 @@ std::string SampleMaskUniqueSetCase::genFragmentSource (int numTargetSamples) co
 {
        DE_ASSERT(numTargetSamples != 0);
 
-       std::ostringstream buf;
+       std::ostringstream      buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
        // test supports only one sample mask word
        if (numTargetSamples > 32)
-               throw tcu::NotSupportedError("Sample count larger than 32 is not supported.");
+               TCU_THROW(NotSupportedError, "Sample count larger than 32 is not supported.");
 
        // output min and max sample id
-       buf <<  "#version 310 es\n"
-                       "#extension GL_OES_sample_variables : require\n"
+       buf <<  "${GLSL_VERSION_DECL}\n"
+                       "${GLSL_EXTENSION}\n"
                        "uniform highp uint u_bitSelector;\n"
                        "layout(location = 0) out mediump vec4 fragColor;\n"
                        "void main (void)\n"
@@ -1692,7 +1741,7 @@ std::string SampleMaskUniqueSetCase::genFragmentSource (int numTargetSamples) co
                        "       fragColor = vec4(float(redBits) / float(31), float(greenBits) / float(63), float(blueBits) / float(31), 1.0);\n"
                        "}\n";
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool SampleMaskUniqueSetCase::verifySampleBuffers (const std::vector<tcu::Surface>& resultBuffers)
@@ -2032,13 +2081,17 @@ std::string SampleMaskWriteCase::genFragmentSource (int numTargetSamples) const
        DE_UNREF(numTargetSamples);
 
        std::ostringstream      buf;
+       const bool                      isES32  = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>     args;
+       args["GLSL_VERSION_DECL"]       = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_EXTENSION"]          = isES32 ? "" : "#extension GL_OES_sample_variables : require";
 
        if (m_testMode == TEST_DISCARD)
        {
                // mask out every other coverage bit
 
-               buf <<  "#version 310 es\n"
-                               "#extension GL_OES_sample_variables : require\n"
+               buf <<  "${GLSL_VERSION_DECL}\n"
+                               "${GLSL_EXTENSION}\n"
                                "layout(location = 0) out mediump vec4 fragColor;\n"
                                "void main (void)\n"
                                "{\n"
@@ -2060,8 +2113,8 @@ std::string SampleMaskWriteCase::genFragmentSource (int numTargetSamples) const
        {
                // inverse every coverage bit
 
-               buf <<  "#version 310 es\n"
-                               "#extension GL_OES_sample_variables : require\n"
+               buf <<  "${GLSL_VERSION_DECL}\n"
+                               "${GLSL_EXTENSION}\n"
                                "layout(location = 0) out mediump vec4 fragColor;\n"
                                "uniform highp uint u_mask;\n"
                                "void main (void)\n"
@@ -2082,7 +2135,7 @@ std::string SampleMaskWriteCase::genFragmentSource (int numTargetSamples) const
        else
                DE_ASSERT(false);
 
-       return buf.str();
+       return tcu::StringTemplate(buf.str()).specialize(args);
 }
 
 bool SampleMaskWriteCase::verifyImage (const tcu::Surface& resultImage)
index 42c07d5..17f393b 100644 (file)
@@ -158,8 +158,29 @@ ShaderBuiltinConstantCase<DataType>::~ShaderBuiltinConstantCase (void)
 template<typename DataType>
 void ShaderBuiltinConstantCase<DataType>::init (void)
 {
-       if (!m_requiredExt.empty() && !m_context.getContextInfo().isExtensionSupported(m_requiredExt.c_str()))
-               throw tcu::NotSupportedError(m_requiredExt + " not supported");
+       const bool isES32 = contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+
+       if (m_requiredExt == "GL_OES_sample_variables" || m_requiredExt == "GL_EXT_geometry_shader" || m_requiredExt == "GL_EXT_tessellation_shader")
+       {
+               if(!isES32)
+               {
+                       const std::string message = "The test requires a 3.2 context or support for the extension " + m_requiredExt + ".";
+                       TCU_CHECK_AND_THROW(NotSupportedError, m_context.getContextInfo().isExtensionSupported(m_requiredExt.c_str()), message.c_str());
+               }
+       }
+       else if (!m_requiredExt.empty() && !m_context.getContextInfo().isExtensionSupported(m_requiredExt.c_str()))
+                       throw tcu::NotSupportedError(m_requiredExt + " not supported");
+
+       if (!isES32 && (m_varName == "gl_MaxTessControlImageUniforms"   ||
+               m_varName == "gl_MaxTessEvaluationImageUniforms"                        ||
+               m_varName == "gl_MaxTessControlAtomicCounters"                          ||
+               m_varName == "gl_MaxTessEvaluationAtomicCounters"                       ||
+               m_varName == "gl_MaxTessControlAtomicCounterBuffers"            ||
+               m_varName == "gl_MaxTessEvaluationAtomicCounterBuffers"))
+       {
+               std::string message = "The test requires a 3.2 context. The constant '" + m_varName + "' is not supported.";
+               TCU_THROW(NotSupportedError, message.c_str());
+       }
 }
 
 static gls::ShaderExecUtil::ShaderExecutor* createGetConstantExecutor (const glu::RenderContext&       renderCtx,
@@ -170,14 +191,15 @@ static gls::ShaderExecUtil::ShaderExecutor* createGetConstantExecutor (const glu
 {
        using namespace gls::ShaderExecUtil;
 
+       const bool      isES32          = contextSupports(renderCtx.getType(), glu::ApiType::es(3, 2));
        ShaderSpec      shaderSpec;
 
-       shaderSpec.version      = glu::GLSL_VERSION_310_ES;
+       shaderSpec.version      = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
        shaderSpec.source       = string("result = ") + varName + ";\n";
 
        shaderSpec.outputs.push_back(Symbol("result", glu::VarType(dataType, glu::PRECISION_HIGHP)));
 
-       if (!extName.empty())
+       if (!extName.empty() && !(isES32 && (extName == "GL_OES_sample_variables" || extName == "GL_EXT_geometry_shader" || extName == "GL_EXT_tessellation_shader")))
                shaderSpec.globalDeclarations = "#extension " + extName + " : require\n";
 
        return createExecutor(renderCtx, shaderType, shaderSpec);
@@ -383,21 +405,28 @@ void ShaderBuiltinConstantTests::init (void)
                        ShaderBuiltinConstantCase<int>::GetConstantValueFunc    getValue;
                } intConstants[] =
                {
-                       { "gl_MaxTessControlInputComponents",                   getInteger<GL_MAX_TESS_CONTROL_INPUT_COMPONENTS>                },
-                       { "gl_MaxTessControlOutputComponents",                  getInteger<GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS>               },
-                       { "gl_MaxTessControlTextureImageUnits",                 getInteger<GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS>             },
-                       { "gl_MaxTessControlUniformComponents",                 getInteger<GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS>              },
-                       { "gl_MaxTessControlTotalOutputComponents",             getInteger<GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS> },
-
-                       { "gl_MaxTessEvaluationInputComponents",                getInteger<GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS>             },
-                       { "gl_MaxTessEvaluationOutputComponents",               getInteger<GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS>    },
-                       { "gl_MaxTessEvaluationTextureImageUnits",              getInteger<GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS>  },
-                       { "gl_MaxTessEvaluationUniformComponents",              getInteger<GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS>   },
-
-                       { "gl_MaxTessPatchComponents",                                  getInteger<GL_MAX_TESS_PATCH_COMPONENTS>                                },
-
-                       { "gl_MaxPatchVertices",                                                getInteger<GL_MAX_PATCH_VERTICES>                                               },
-                       { "gl_MaxTessGenLevel",                                                 getInteger<GL_MAX_TESS_GEN_LEVEL>                                               },
+                       { "gl_MaxTessControlInputComponents",                   getInteger<GL_MAX_TESS_CONTROL_INPUT_COMPONENTS>                        },
+                       { "gl_MaxTessControlOutputComponents",                  getInteger<GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS>                       },
+                       { "gl_MaxTessControlTextureImageUnits",                 getInteger<GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS>                     },
+                       { "gl_MaxTessControlUniformComponents",                 getInteger<GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS>                      },
+                       { "gl_MaxTessControlTotalOutputComponents",             getInteger<GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS>         },
+
+                       { "gl_MaxTessControlImageUniforms",                             getInteger<GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS>                          },
+                       { "gl_MaxTessEvaluationImageUniforms",                  getInteger<GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS>                       },
+                       { "gl_MaxTessControlAtomicCounters",                    getInteger<GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS>                         },
+                       { "gl_MaxTessEvaluationAtomicCounters",                 getInteger<GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS>                      },
+                       { "gl_MaxTessControlAtomicCounterBuffers",              getInteger<GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS>          },
+                       { "gl_MaxTessEvaluationAtomicCounterBuffers",   getInteger<GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS>       },
+
+                       { "gl_MaxTessEvaluationInputComponents",                getInteger<GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS>                     },
+                       { "gl_MaxTessEvaluationOutputComponents",               getInteger<GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS>            },
+                       { "gl_MaxTessEvaluationTextureImageUnits",              getInteger<GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS>          },
+                       { "gl_MaxTessEvaluationUniformComponents",              getInteger<GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS>           },
+
+                       { "gl_MaxTessPatchComponents",                                  getInteger<GL_MAX_TESS_PATCH_COMPONENTS>                                        },
+
+                       { "gl_MaxPatchVertices",                                                getInteger<GL_MAX_PATCH_VERTICES>                                                       },
+                       { "gl_MaxTessGenLevel",                                                 getInteger<GL_MAX_TESS_GEN_LEVEL>                                                       },
                };
 
                tcu::TestCaseGroup* const tessGroup = new tcu::TestCaseGroup(m_testCtx, "tessellation_shader", "GL_EXT_tessellation_shader");
index 64fa4ed..a235e43 100644 (file)
@@ -78,7 +78,9 @@ InterpolationOffsetCase::~InterpolationOffsetCase (void)
 
 void InterpolationOffsetCase::init (void)
 {
-       if (!m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
+       const bool isES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+
+       if (!isES32 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
                throw tcu::NotSupportedError("Test requires GL_OES_shader_multisample_interpolation extension");
 }
 
@@ -124,7 +126,9 @@ FragmentInterpolationOffsetBitsCase::~FragmentInterpolationOffsetBitsCase (void)
 
 void FragmentInterpolationOffsetBitsCase::init (void)
 {
-       if (!m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
+       const bool isES32 = glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2));
+
+       if (!isES32 && !m_context.getContextInfo().isExtensionSupported("GL_OES_shader_multisample_interpolation"))
                throw tcu::NotSupportedError("Test requires GL_OES_shader_multisample_interpolation extension");
 }