Add negative tests for precise qualifier and advanced blending.
authorDaniel Andrade Groppe <daniel.andrade@mobica.com>
Thu, 25 Feb 2016 19:59:59 +0000 (13:59 -0600)
committerDaniel Andrade Groppe <daniel.andrade@mobica.com>
Fri, 26 Feb 2016 16:16:30 +0000 (10:16 -0600)
Change-Id: Ib0560b5e97aa7b6a272d9525d18d6e8cd82c9f8d

Android.mk
modules/gles31/functional/CMakeLists.txt
modules/gles31/functional/es31fDebugTests.cpp
modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.hpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativePreciseTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativePreciseTests.hpp [new file with mode: 0644]

index 69e79c0..d03b6b7 100644 (file)
@@ -569,6 +569,8 @@ LOCAL_SRC_FILES := \
        modules/gles31/functional/es31fNegativeAtomicCounterTests.cpp \
        modules/gles31/functional/es31fNegativeBufferApiTests.cpp \
        modules/gles31/functional/es31fNegativeFragmentApiTests.cpp \
+       modules/gles31/functional/es31fNegativePreciseTests.cpp \
+       modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp \
        modules/gles31/functional/es31fNegativeShaderApiTests.cpp \
        modules/gles31/functional/es31fNegativeShaderDirectiveTests.cpp \
        modules/gles31/functional/es31fNegativeShaderFunctionTests.cpp \
index 68b98ef..1f57b59 100644 (file)
@@ -153,6 +153,10 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fNegativeShaderFunctionTests.hpp
        es31fNegativeShaderDirectiveTests.cpp
        es31fNegativeShaderDirectiveTests.hpp
+       es31fNegativePreciseTests.cpp
+       es31fNegativePreciseTests.hpp
+       es31fNegativeAdvancedBlendEquationTests.cpp
+       es31fNegativeAdvancedBlendEquationTests.hpp
        es31fTextureGatherTests.cpp
        es31fTextureGatherTests.hpp
        es31fTextureFormatTests.cpp
index d417705..945da66 100644 (file)
@@ -34,6 +34,8 @@
 #include "es31fNegativeShaderImageLoadStoreTests.hpp"
 #include "es31fNegativeShaderFunctionTests.hpp"
 #include "es31fNegativeShaderDirectiveTests.hpp"
+#include "es31fNegativePreciseTests.hpp"
+#include "es31fNegativeAdvancedBlendEquationTests.hpp"
 
 #include "deUniquePtr.hpp"
 #include "deRandom.hpp"
@@ -2918,6 +2920,8 @@ void DebugTests::init (void)
        const vector<FunctionContainer> shaderImageLoadStoreFuncs       = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageLoadStoreTestFunctions());
        const vector<FunctionContainer> shaderFunctionFuncs                     = wrapCoreFunctions(NegativeTestShared::getNegativeShaderFunctionTestFunctions());
        const vector<FunctionContainer> shaderDirectiveFuncs            = wrapCoreFunctions(NegativeTestShared::getNegativeShaderDirectiveTestFunctions());
+       const vector<FunctionContainer> preciseFuncs                            = wrapCoreFunctions(NegativeTestShared::getNegativePreciseTestFunctions());
+       const vector<FunctionContainer> advancedBlendFuncs                      = wrapCoreFunctions(NegativeTestShared::getNegativeAdvancedBlendEquationTestFunctions());
        const vector<FunctionContainer> externalFuncs                           = getUserMessageFuncs();
 
        {
@@ -3019,6 +3023,8 @@ void DebugTests::init (void)
                        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));
+                       host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
+                       host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
                }
 
                {
@@ -3036,6 +3042,8 @@ void DebugTests::init (void)
                        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));
+                       host->addChild(createChildCases(CASETYPE_LOG, m_context, "precise",                                     "Negative Precise Cases",                                                       preciseFuncs));
+                       host->addChild(createChildCases(CASETYPE_LOG, m_context, "advanced_blend",                      "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
                }
 
                {
@@ -3053,6 +3061,8 @@ void DebugTests::init (void)
                        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));
+                       host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
+                       host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
                }
        }
 
diff --git a/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp b/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp
new file mode 100644 (file)
index 0000000..ab50df5
--- /dev/null
@@ -0,0 +1,280 @@
+/*-------------------------------------------------------------------------
+ * 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 Advanced Blend Equation Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeAdvancedBlendEquationTests.hpp"
+
+#include "gluShaderProgram.hpp"
+#include "glwEnums.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+enum BlendEquation
+{
+       BLEND_EQUATION_MULTIPLY = 0,
+       BLEND_EQUATION_SCREEN,
+       BLEND_EQUATION_OVERLAY,
+       BLEND_EQUATION_DARKEN,
+       BLEND_EQUATION_LIGHTEN,
+       BLEND_EQUATION_COLORDODGE,
+       BLEND_EQUATION_COLORBURN,
+       BLEND_EQUATION_HARDLIGHT,
+       BLEND_EQUATION_SOFTLIGHT,
+       BLEND_EQUATION_DIFFERENCE,
+       BLEND_EQUATION_EXCLUSION,
+       BLEND_EQUATION_HSL_HUE,
+       BLEND_EQUATION_HSL_SATURATION,
+       BLEND_EQUATION_HSL_COLOR,
+       BLEND_EQUATION_HSL_LUMINOSITY,
+       BLEND_EQUATION_ALL_EQUATIONS,
+
+       BLEND_EQUATION_LAST
+};
+
+static const BlendEquation s_equations[] =
+{
+       BLEND_EQUATION_MULTIPLY,
+       BLEND_EQUATION_SCREEN,
+       BLEND_EQUATION_OVERLAY,
+       BLEND_EQUATION_DARKEN,
+       BLEND_EQUATION_LIGHTEN,
+       BLEND_EQUATION_COLORDODGE,
+       BLEND_EQUATION_COLORBURN,
+       BLEND_EQUATION_HARDLIGHT,
+       BLEND_EQUATION_SOFTLIGHT,
+       BLEND_EQUATION_DIFFERENCE,
+       BLEND_EQUATION_EXCLUSION,
+       BLEND_EQUATION_HSL_HUE,
+       BLEND_EQUATION_HSL_SATURATION,
+       BLEND_EQUATION_HSL_COLOR,
+       BLEND_EQUATION_HSL_LUMINOSITY
+};
+
+std::string getShaderLayoutEquation (BlendEquation equation)
+{
+       switch (equation)
+       {
+               case BLEND_EQUATION_MULTIPLY:          return "blend_support_multiply";
+               case BLEND_EQUATION_SCREEN:            return "blend_support_screen";
+               case BLEND_EQUATION_OVERLAY:           return "blend_support_overlay";
+               case BLEND_EQUATION_DARKEN:            return "blend_support_darken";
+               case BLEND_EQUATION_LIGHTEN:           return "blend_support_lighten";
+               case BLEND_EQUATION_COLORDODGE:        return "blend_support_colordodge";
+               case BLEND_EQUATION_COLORBURN:         return "blend_support_colorburn";
+               case BLEND_EQUATION_HARDLIGHT:         return "blend_support_hardlight";
+               case BLEND_EQUATION_SOFTLIGHT:         return "blend_support_softlight";
+               case BLEND_EQUATION_DIFFERENCE:        return "blend_support_difference";
+               case BLEND_EQUATION_EXCLUSION:         return "blend_support_exclusion";
+               case BLEND_EQUATION_HSL_HUE:           return "blend_support_hsl_hue";
+               case BLEND_EQUATION_HSL_SATURATION:    return "blend_support_hsl_saturation";
+               case BLEND_EQUATION_HSL_COLOR:         return "blend_support_hsl_color";
+               case BLEND_EQUATION_HSL_LUMINOSITY:    return "blend_support_hsl_luminosity";
+               case BLEND_EQUATION_ALL_EQUATIONS:     return "blend_support_all_equations";
+               default:
+                       DE_FATAL("Equation not supported.");
+       }
+       return DE_NULL;
+}
+
+glw::GLenum getEquation (BlendEquation equation)
+{
+       switch (equation)
+       {
+               case BLEND_EQUATION_MULTIPLY:          return GL_MULTIPLY;
+               case BLEND_EQUATION_SCREEN:            return GL_SCREEN;
+               case BLEND_EQUATION_OVERLAY:           return GL_OVERLAY;
+               case BLEND_EQUATION_DARKEN:            return GL_DARKEN;
+               case BLEND_EQUATION_LIGHTEN:           return GL_LIGHTEN;
+               case BLEND_EQUATION_COLORDODGE:        return GL_COLORDODGE;
+               case BLEND_EQUATION_COLORBURN:         return GL_COLORBURN;
+               case BLEND_EQUATION_HARDLIGHT:         return GL_HARDLIGHT;
+               case BLEND_EQUATION_SOFTLIGHT:         return GL_SOFTLIGHT;
+               case BLEND_EQUATION_DIFFERENCE:        return GL_DIFFERENCE;
+               case BLEND_EQUATION_EXCLUSION:         return GL_EXCLUSION;
+               case BLEND_EQUATION_HSL_HUE:           return GL_HSL_HUE;
+               case BLEND_EQUATION_HSL_SATURATION:    return GL_HSL_SATURATION;
+               case BLEND_EQUATION_HSL_COLOR:         return GL_HSL_COLOR;
+               case BLEND_EQUATION_HSL_LUMINOSITY:    return GL_HSL_LUMINOSITY;
+               default:
+                       DE_FATAL("Equation not supported.");
+       }
+       return DE_NULL;
+}
+
+std::string generateVertexShaderSource (NegativeTestContext& ctx)
+{
+       const bool                              isES32  = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       std::ostringstream              source;
+
+       source  << glu::getGLSLVersionDeclaration(version) << "\n"
+                       << "void main ()\n"
+                       << "{\n"
+                       << "    gl_Position = vec4(0.0);\n"
+                       << "}\n";
+
+       return source.str();
+}
+
+std::string generateFragmentShaderSource (NegativeTestContext& ctx, BlendEquation equation)
+{
+       const bool                              isES32  = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       std::ostringstream              source;
+
+       source  << glu::getGLSLVersionDeclaration(version) << "\n"
+                       << (isES32 ? "" : "#extension GL_KHR_blend_equation_advanced : enable\n")
+                       << "layout(" << getShaderLayoutEquation(equation) << ") out;\n"
+                       << "layout(location=0) out mediump vec4 o_color;\n"
+                       << "void main ()\n"
+                       << "{\n"
+                       << "    o_color = vec4(0);\n"
+                       << "}\n";
+
+       return source.str();
+}
+
+glu::ProgramSources generateProgramSources (NegativeTestContext& ctx, BlendEquation equation)
+{
+       return glu::ProgramSources()
+               << glu::VertexSource(generateVertexShaderSource(ctx))
+               << glu::FragmentSource(generateFragmentShaderSource(ctx, equation));
+}
+
+void blend_qualifier_mismatch (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_KHR_blend_equation_advanced or context version 3.2 or higher.");
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, and the blend qualifier is different from blend_support_all_equations and does not match the blend equation.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
+       {
+               glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
+
+               ctx.getLog() << program;
+               TCU_CHECK(program.isOk());
+
+               ctx.glUseProgram(program.getProgram());
+               ctx.expectError(GL_NO_ERROR);
+
+               for (int ndx2 = 0; ndx2 < DE_LENGTH_OF_ARRAY(s_equations); ++ndx2)
+               {
+                       if (s_equations[ndx] == s_equations[ndx2])
+                               continue;
+
+                       ctx.glEnable(GL_BLEND);
+                       ctx.glBlendEquation(getEquation(s_equations[ndx2]));
+                       ctx.expectError(GL_NO_ERROR);
+                       ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
+                       ctx.expectError(GL_INVALID_OPERATION);
+
+                       ctx.glDisable(GL_BLEND);
+                       ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
+                       ctx.expectError(GL_NO_ERROR);
+               }
+       }
+       ctx.endSection();
+}
+
+void attachment_advanced_equation (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_KHR_blend_equation_advanced or context version 3.2 or higher.");
+
+       glw::GLuint                     fbo                             = 0x1234;
+       glw::GLuint                     texture                 = 0x1234;
+       const glw::GLenum       attachments[]   = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
+
+       ctx.glGenTextures(1, &texture);
+       ctx.glBindTexture(GL_TEXTURE_2D, texture);
+       ctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+       ctx.glGenFramebuffers(1, &fbo);
+       ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, advanced equations are used, and the draw buffer for other color outputs is not NONE.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
+       {
+               glu::ShaderProgram      program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
+               ctx.getLog() << program;
+               TCU_CHECK(program.isOk());
+
+               ctx.glUseProgram(program.getProgram());
+               ctx.glEnable(GL_BLEND);
+               ctx.glDrawBuffers(2, attachments);
+               ctx.expectError(GL_NO_ERROR);
+               ctx.glBlendEquation(getEquation(s_equations[ndx]));
+               ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
+               ctx.expectError(GL_INVALID_OPERATION);
+       }
+       ctx.endSection();
+
+       ctx.beginSection("GL_NO_ERROR is generated if no advanced blend equations are used.");
+       ctx.glBlendEquation(GL_FUNC_ADD);
+       ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
+       ctx.expectError(GL_NO_ERROR);
+       ctx.endSection();
+
+       ctx.beginSection("GL_NO_ERROR is generated if blending is disabled.");
+       ctx.glDisable(GL_BLEND);
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
+       {
+               ctx.glBlendEquation(getEquation(s_equations[ndx]));
+               ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
+               ctx.expectError(GL_NO_ERROR);
+       }
+       ctx.endSection();
+
+       ctx.glDeleteFramebuffers(1, &fbo);
+       ctx.glDeleteTextures(1, &texture);
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativeAdvancedBlendEquationTestFunctions (void)
+{
+       const FunctionContainer funcs[] =
+       {
+               {blend_qualifier_mismatch,              "blend_qualifier_mismatch",                     "Test blend qualifier mismatch."                        },
+               {attachment_advanced_equation,          "attachment_advanced_equation",         "Test draw buffer for other color outputs." },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.hpp b/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.hpp
new file mode 100644 (file)
index 0000000..37c207e
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVEADVANCEDBLENDEQUATIONTESTS_HPP
+#define _ES31FNEGATIVEADVANCEDBLENDEQUATIONTESTS_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 Advanced Blend Equation Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeAdvancedBlendEquationTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVEADVANCEDBLENDEQUATIONTESTS_HPP
diff --git a/modules/gles31/functional/es31fNegativePreciseTests.cpp b/modules/gles31/functional/es31fNegativePreciseTests.cpp
new file mode 100644 (file)
index 0000000..934b78b
--- /dev/null
@@ -0,0 +1,264 @@
+/*-------------------------------------------------------------------------
+ * 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 Precise Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativePreciseTests.hpp"
+
+#include "gluShaderProgram.hpp"
+#include "glwEnums.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+namespace
+{
+
+enum TestPrecise
+{
+       TEST_PRECISE_AS_VARIABLE_NAME = 0,
+       TEST_PRECISE_AS_FUNCTION_NAME,
+       TEST_PRECISE_AS_ARGUMENT_NAME,
+       TEST_PRECISE_AS_MACRO_NAME,
+       TEST_PRECISE_MACRO_AND_VARIABLE,
+       TEST_PRECISE_MACRO_AND_FUNCTION,
+       TEST_PRECISE_MACRO_AND_ARGUMENT,
+
+       TEST_PRECISE_LAST
+};
+
+static const glu::ShaderType s_shaderTypes[] =
+{
+       glu::SHADERTYPE_VERTEX,
+       glu::SHADERTYPE_FRAGMENT,
+       glu::SHADERTYPE_GEOMETRY,
+       glu::SHADERTYPE_COMPUTE,
+       glu::SHADERTYPE_TESSELLATION_CONTROL,
+       glu::SHADERTYPE_TESSELLATION_EVALUATION
+};
+
+std::string generateShaderSource (NegativeTestContext& ctx, glu::ShaderType shaderType, TestPrecise test)
+{
+       const bool                              isES32  = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       const glu::GLSLVersion  version = isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
+       std::ostringstream              source;
+
+       source  << glu::getGLSLVersionDeclaration(version) << "\n"
+                       << (isES32 ? "" : "#extension GL_EXT_gpu_shader5 : enable\n");
+
+       switch (test)
+       {
+               case TEST_PRECISE_AS_MACRO_NAME:                source << "#define precise 0\n";                break;
+
+               case TEST_PRECISE_MACRO_AND_VARIABLE:
+               case TEST_PRECISE_MACRO_AND_FUNCTION:
+               case TEST_PRECISE_MACRO_AND_ARGUMENT:   source << "#define precise aName\n";    break;
+               default:
+                       break;
+       }
+
+    switch (shaderType)
+    {
+        case glu::SHADERTYPE_GEOMETRY:
+            source  << (isES32 ? "" : "#extension GL_EXT_geometry_shader : enable\n")
+                    << "layout(max_vertices = 5) out;\n";
+            break;
+
+        case glu::SHADERTYPE_TESSELLATION_CONTROL:
+            source  << (isES32 ? "" : "#extension GL_EXT_tessellation_shader : enable\n")
+                    << "layout(vertices = 3) out;\n";
+            break;
+
+        case glu::SHADERTYPE_TESSELLATION_EVALUATION:
+            source  << (isES32 ? "" : "#extension GL_EXT_tessellation_shader : enable\n")
+                    << "layout(triangles, equal_spacing, cw) in;\n";
+            break;
+
+        default:
+            break;
+    }
+
+       switch (test)
+       {
+               case TEST_PRECISE_AS_FUNCTION_NAME:
+               case TEST_PRECISE_MACRO_AND_FUNCTION:
+                       source  << "\n"
+                                       << "void precise()\n"
+                                       << "{\n"
+                                       << "}\n";
+                       break;
+
+               case TEST_PRECISE_AS_ARGUMENT_NAME:
+               case TEST_PRECISE_MACRO_AND_ARGUMENT:
+                       source  << "\n"
+                                       << "void example(int precise)\n"
+                                       << "{\n"
+                                       << "}\n";
+                       break;
+
+               default:
+                       break;
+       }
+
+    source  << "void main()\n"
+                       << "{\n";
+
+       switch (test)
+       {
+               case TEST_PRECISE_AS_VARIABLE_NAME:
+               case TEST_PRECISE_MACRO_AND_VARIABLE:   source << "     int precise = 1;\n";            break;
+               case TEST_PRECISE_AS_MACRO_NAME:                source << "     int number = precise;\n";       break;
+               default:
+                       break;
+       }
+
+       source << "}\n";
+
+       return source.str();
+}
+
+void generateAndVerifyShader (NegativeTestContext& ctx, glu::ShaderType shaderType, TestPrecise test)
+{
+       glu::Shader             shader                  (ctx.getRenderContext(), shaderType);
+       std::string             shaderSource    = generateShaderSource(ctx, shaderType, test);
+       const char* const       source                  = shaderSource.c_str();
+       const int                       length                  = (int) shaderSource.size();
+
+       shader.setSources(1, &source, &length);
+       shader.compile();
+
+       ctx.getLog() << shader;
+
+       if (shader.getCompileStatus())
+               ctx.fail("Shader was not expected to compile.");
+}
+
+void precise_as_variable_name (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
+
+       ctx.beginSection("Test that precise cannot be used as a variable name.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
+               generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_VARIABLE_NAME);
+       ctx.endSection();
+}
+
+void precise_as_function_name (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
+
+       ctx.beginSection("Test that precise cannot be used as a function name.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
+               generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_FUNCTION_NAME);
+       ctx.endSection();
+}
+
+void precise_as_function_argument (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
+
+       ctx.beginSection("Test that precise cannot be used as a argument name.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
+               generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_ARGUMENT_NAME);
+       ctx.endSection();
+}
+
+void precise_as_macro_name (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
+
+       ctx.beginSection("Test precise keyword as macro name.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
+               generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_MACRO_NAME);
+       ctx.endSection();
+}
+
+void precise_as_macro_and_variable (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
+
+       ctx.beginSection("Test precise keyword as macro and variable name.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
+               generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_MACRO_AND_VARIABLE);
+       ctx.endSection();
+}
+
+void precise_as_macro_and_function (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
+
+       ctx.beginSection("Test precise keyword as macro and function name.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
+               generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_MACRO_AND_FUNCTION);
+       ctx.endSection();
+}
+
+void precise_as_macro_and_argument (NegativeTestContext& ctx)
+{
+       TCU_CHECK_AND_THROW(NotSupportedError,
+               ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
+               "This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");
+
+       ctx.beginSection("Test precise keyword as macro and argument name.");
+       for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
+               generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_MACRO_AND_ARGUMENT);
+       ctx.endSection();
+}
+
+} // anonymous
+
+std::vector<FunctionContainer> getNegativePreciseTestFunctions (void)
+{
+       const FunctionContainer funcs[] =
+       {
+        {precise_as_variable_name,                     "precise_as_variable_name",                     "Test precise keyword as variable name."                        },
+        {precise_as_function_name,                     "precise_as_function_name",                     "Test precise keyword as function name."                        },
+        {precise_as_function_argument,         "precise_as_function_argument",         "Test precise keyword as argument name."                        },
+        {precise_as_macro_name,                                "precise_as_macro_name",                        "Test precise keyword as macro name."                           },
+        {precise_as_macro_and_variable,                "precise_as_macro_and_variable",        "Test precise keyword as macro and variable name."      },
+        {precise_as_macro_and_function,                "precise_as_macro_and_function",        "Test precise keyword as macro and function name."      },
+        {precise_as_macro_and_argument,                "precise_as_macro_and_argument",        "Test precise keyword as macro and argument name."      },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativePreciseTests.hpp b/modules/gles31/functional/es31fNegativePreciseTests.hpp
new file mode 100644 (file)
index 0000000..41fc8ca
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVEPRECISETESTS_HPP
+#define _ES31FNEGATIVEPRECISETESTS_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 Precise Tests
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativePreciseTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
+
+#endif // _ES31FNEGATIVEPRECISETESTS_HPP