Add negative tests for precise qualifier and advanced blending.

Change-Id: Ib0560b5e97aa7b6a272d9525d18d6e8cd82c9f8d
diff --git a/Android.mk b/Android.mk
index 69e79c0..d03b6b7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -569,6 +569,8 @@
 	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 \
diff --git a/modules/gles31/functional/CMakeLists.txt b/modules/gles31/functional/CMakeLists.txt
index 68b98ef..1f57b59 100644
--- a/modules/gles31/functional/CMakeLists.txt
+++ b/modules/gles31/functional/CMakeLists.txt
@@ -153,6 +153,10 @@
 	es31fNegativeShaderFunctionTests.hpp
 	es31fNegativeShaderDirectiveTests.cpp
 	es31fNegativeShaderDirectiveTests.hpp
+	es31fNegativePreciseTests.cpp
+	es31fNegativePreciseTests.hpp
+	es31fNegativeAdvancedBlendEquationTests.cpp
+	es31fNegativeAdvancedBlendEquationTests.hpp
 	es31fTextureGatherTests.cpp
 	es31fTextureGatherTests.hpp
 	es31fTextureFormatTests.cpp
diff --git a/modules/gles31/functional/es31fDebugTests.cpp b/modules/gles31/functional/es31fDebugTests.cpp
index d417705..945da66 100644
--- a/modules/gles31/functional/es31fDebugTests.cpp
+++ b/modules/gles31/functional/es31fDebugTests.cpp
@@ -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 @@
 	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 @@
 			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 @@
 			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 @@
 			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
index 0000000..ab50df5
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.cpp
@@ -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
index 0000000..37c207e
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativeAdvancedBlendEquationTests.hpp
@@ -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
index 0000000..934b78b
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativePreciseTests.cpp
@@ -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
index 0000000..41fc8ca
--- /dev/null
+++ b/modules/gles31/functional/es31fNegativePreciseTests.hpp
@@ -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