Added validation to shader related functions

- Added uniform block binding validation
- Disallowed setting int uniforms from unsigned
  int specific functions and vice versa.
- Moved early returns from uniform related
  functions further down the functions to allow
  gl errors to be returned
- Added active transform feedback checks
- Fixed some gl error return codes.

Fixes most failures in:
dEQP-GLES3.functional.negative_api.shader*

Change-Id: Id9f914a09dd89fea61728725f8bd828dc7b3f81b
Reviewed-on: https://swiftshader-review.googlesource.com/14128
Tested-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index 6836e2d..37c294f 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -489,6 +489,11 @@
 
 	void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
 	{
+		if(uniformBlockIndex >= getActiveUniformBlockCount())
+		{
+			return error(GL_INVALID_VALUE);
+		}
+
 		uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
 	}
 
@@ -716,7 +721,7 @@
 
 		count = std::min(size - (int)uniformIndex[location].element, count);
 
-		if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
+		if(targetUniform->type == GL_INT || IsSamplerUniform(targetUniform->type))
 		{
 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
 				   v, sizeof(GLint) * count);
@@ -753,7 +758,6 @@
 	bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)
 	{
 		static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
-		static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
 		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
 
 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
@@ -774,7 +778,7 @@
 		count = std::min(size - (int)uniformIndex[location].element, count);
 
 		int index = numElements - 1;
-		if(targetUniform->type == intType[index] || targetUniform->type == uintType[index])
+		if(targetUniform->type == intType[index])
 		{
 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,
 				   v, numElements * sizeof(GLint)* count);
@@ -835,7 +839,7 @@
 
 		count = std::min(size - (int)uniformIndex[location].element, count);
 
-		if(targetUniform->type == GL_INT || targetUniform->type == GL_UNSIGNED_INT || IsSamplerUniform(targetUniform->type))
+		if(targetUniform->type == GL_UNSIGNED_INT)
 		{
 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),
 				   v, sizeof(GLuint)* count);
@@ -871,7 +875,6 @@
 
 	bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)
 	{
-		static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
 		static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
 		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
 
@@ -893,7 +896,7 @@
 		count = std::min(size - (int)uniformIndex[location].element, count);
 
 		int index = numElements - 1;
-		if(targetUniform->type == uintType[index] || targetUniform->type == intType[index])
+		if(targetUniform->type == uintType[index])
 		{
 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,
 				   v, numElements * sizeof(GLuint)* count);
diff --git a/src/OpenGL/libGLESv2/libGLESv2.cpp b/src/OpenGL/libGLESv2/libGLESv2.cpp
index c560600..5f14e9c 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.cpp
@@ -4532,6 +4532,15 @@
 			}
 		}
 
+		if(programObject == context->getCurrentProgram())
+		{
+			es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+			if(transformFeedback && transformFeedback->isActive())
+			{
+				return error(GL_INVALID_OPERATION);
+			}
+		}
+
 		programObject->link();
 	}
 }
@@ -5563,11 +5572,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5579,6 +5583,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform1fv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5600,11 +5609,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5616,6 +5620,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform1iv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5639,11 +5648,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5655,6 +5659,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform2fv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5678,11 +5687,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5694,6 +5698,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform2iv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5717,11 +5726,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5733,6 +5737,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform3fv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5756,11 +5765,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5772,6 +5776,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform3iv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5795,11 +5804,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5811,6 +5815,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform4fv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5834,11 +5843,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5850,6 +5854,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform4iv(location, count, v))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5867,11 +5876,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5888,6 +5892,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix2fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5905,11 +5914,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5926,6 +5930,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix3fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5943,11 +5952,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -5964,6 +5968,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix4fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -5979,6 +5988,12 @@
 
 	if(context)
 	{
+		es2::TransformFeedback* transformFeedback = context->getTransformFeedback();
+		if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+
 		es2::Program *programObject = context->getProgram(program);
 
 		if(!programObject && program != 0)
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index 2f2c8ca..76381e1 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -1305,11 +1305,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -1321,6 +1316,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix2x3fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -1337,11 +1337,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -1353,6 +1348,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix3x2fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -1369,11 +1369,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -1385,6 +1380,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix2x4fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -1401,11 +1401,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -1417,6 +1412,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix4x2fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -1433,11 +1433,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -1449,6 +1444,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix3x4fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -1465,11 +1465,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -1481,6 +1476,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniformMatrix4x3fv(location, count, transpose, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -2475,11 +2475,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -2491,6 +2486,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform1uiv(location, count, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -2508,11 +2508,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -2524,6 +2519,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform2uiv(location, count, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -2541,11 +2541,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -2557,6 +2552,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform3uiv(location, count, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -2574,11 +2574,6 @@
 		return error(GL_INVALID_VALUE);
 	}
 
-	if(location == -1)
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -2590,6 +2585,11 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
+		if(location == -1)
+		{
+			return;
+		}
+
 		if(!program->setUniform4uiv(location, count, value))
 		{
 			return error(GL_INVALID_OPERATION);
@@ -3533,11 +3533,6 @@
 		return error(GL_INVALID_ENUM);
 	}
 
-	if(!ValidateTexParamParameters(pname, static_cast<GLint>(roundf(*param))))
-	{
-		return;
-	}
-
 	es2::Context *context = es2::getContext();
 
 	if(context)
@@ -3547,7 +3542,10 @@
 			return error(GL_INVALID_OPERATION);
 		}
 
-		context->samplerParameterf(sampler, pname, *param);
+		if(ValidateTexParamParameters(pname, static_cast<GLint>(roundf(*param))))
+		{
+			context->samplerParameterf(sampler, pname, *param);
+		}
 	}
 }
 
@@ -3567,7 +3565,7 @@
 	{
 		if(!context->isSampler(sampler))
 		{
-			return error(GL_INVALID_VALUE);
+			return error(GL_INVALID_OPERATION);
 		}
 
 		*params = context->getSamplerParameteri(sampler, pname);
@@ -3590,7 +3588,7 @@
 	{
 		if(!context->isSampler(sampler))
 		{
-			return error(GL_INVALID_VALUE);
+			return error(GL_INVALID_OPERATION);
 		}
 
 		*params = context->getSamplerParameterf(sampler, pname);
@@ -3769,6 +3767,18 @@
 		return error(GL_INVALID_VALUE);
 	}
 
+	es2::Context *context = es2::getContext();
+
+	if(context)
+	{
+		es2::Program *programObject = context->getProgram(program);
+
+		if(!programObject || !programObject->isLinked())
+		{
+			return error(GL_INVALID_OPERATION);
+		}
+	}
+
 	UNIMPLEMENTED();
 }
 
@@ -3798,12 +3808,16 @@
 
 		if(!programObject)
 		{
-			return error(GL_INVALID_OPERATION);
+			return error(GL_INVALID_VALUE);
 		}
 
 		switch(pname)
 		{
 		case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
+			if((value != GL_TRUE) && (value != GL_FALSE))
+			{
+				return error(GL_INVALID_VALUE);
+			}
 			programObject->setBinaryRetrievable(value != GL_FALSE);
 			break;
 		default: