Refactor and clean up uniform validation.
Move uniform value checking to two new functions:
ValidateUniformValue() and ValidateUniformMatrixValue().
This reduces code duplication slightly and paves the way for further
validation of sampler uniforms in a later change.
The checking also becomes slightly more efficient by virtue of
reording the tests to put cheap/common cases first.
ValidateUniformCommonBase() moves to the anonymous namespace and
loses an unused parameter.
BUG=angleproject:1711
Change-Id: I6c4deeea27c54027f542500644636064167d5714
Reviewed-on: https://chromium-review.googlesource.com/431677
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/validationES.cpp b/src/libANGLE/validationES.cpp
index 4a9081a..43fa7ef 100644
--- a/src/libANGLE/validationES.cpp
+++ b/src/libANGLE/validationES.cpp
@@ -1358,6 +1358,91 @@
return true;
}
+bool ValidateUniformCommonBase(gl::Context *context,
+ gl::Program *program,
+ GLint location,
+ GLsizei count,
+ const LinkedUniform **uniformOut)
+{
+ // TODO(Jiajia): Add image uniform check in future.
+ if (count < 0)
+ {
+ context->handleError(Error(GL_INVALID_VALUE));
+ return false;
+ }
+
+ if (!program || !program->isLinked())
+ {
+ context->handleError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ if (location == -1)
+ {
+ // Silently ignore the uniform command
+ return false;
+ }
+
+ const auto &uniformLocations = program->getUniformLocations();
+ size_t castedLocation = static_cast<size_t>(location);
+ if (castedLocation >= uniformLocations.size())
+ {
+ context->handleError(Error(GL_INVALID_OPERATION, "Invalid uniform location"));
+ return false;
+ }
+
+ const auto &uniformLocation = uniformLocations[castedLocation];
+ if (uniformLocation.ignored)
+ {
+ // Silently ignore the uniform command
+ return false;
+ }
+
+ if (!uniformLocation.used)
+ {
+ context->handleError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ const auto &uniform = program->getUniformByIndex(uniformLocation.index);
+
+ // attempting to write an array to a non-array uniform is an INVALID_OPERATION
+ if (!uniform.isArray() && count > 1)
+ {
+ context->handleError(Error(GL_INVALID_OPERATION));
+ return false;
+ }
+
+ *uniformOut = &uniform;
+ return true;
+}
+
+bool ValidateUniformValue(gl::Context *context, GLenum valueType, GLenum uniformType)
+{
+ // Check that the value type is compatible with uniform type.
+ // Do the cheaper tests first, for a little extra speed.
+ if (valueType == uniformType || (valueType == GL_INT && IsSamplerType(uniformType)) ||
+ VariableBoolVectorType(valueType) == uniformType)
+ {
+ return true;
+ }
+
+ context->handleError(Error(GL_INVALID_OPERATION, "wrong type of value for uniform"));
+ return false;
+}
+
+bool ValidateUniformMatrixValue(gl::Context *context, GLenum valueType, GLenum uniformType)
+{
+ // Check that the value type is compatible with uniform type.
+ if (valueType == uniformType)
+ {
+ return true;
+ }
+
+ context->handleError(Error(GL_INVALID_OPERATION, "wrong type of value for uniform"));
+ return false;
+}
+
} // anonymous namespace
bool ValidTextureTarget(const ValidationContext *context, GLenum target)
@@ -2689,68 +2774,8 @@
return true;
}
-static bool ValidateUniformCommonBase(gl::Context *context,
- gl::Program *program,
- GLenum targetUniformType,
- GLint location,
- GLsizei count,
- const LinkedUniform **uniformOut)
-{
- // TODO(Jiajia): Add image uniform check in future.
- if (count < 0)
- {
- context->handleError(Error(GL_INVALID_VALUE));
- return false;
- }
-
- if (!program || !program->isLinked())
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- if (location == -1)
- {
- // Silently ignore the uniform command
- return false;
- }
-
- const auto &uniformLocations = program->getUniformLocations();
- size_t castedLocation = static_cast<size_t>(location);
- if (castedLocation >= uniformLocations.size())
- {
- context->handleError(Error(GL_INVALID_OPERATION, "Invalid uniform location"));
- return false;
- }
-
- const auto &uniformLocation = uniformLocations[castedLocation];
- if (uniformLocation.ignored)
- {
- // Silently ignore the uniform command
- return false;
- }
-
- if (!uniformLocation.used)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- const auto &uniform = program->getUniformByIndex(uniformLocation.index);
-
- // attempting to write an array to a non-array uniform is an INVALID_OPERATION
- if (!uniform.isArray() && count > 1)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- *uniformOut = &uniform;
- return true;
-}
-
bool ValidateProgramUniform(gl::Context *context,
- GLenum uniformType,
+ GLenum valueType,
GLuint program,
GLint location,
GLsizei count)
@@ -2764,24 +2789,12 @@
const LinkedUniform *uniform = nullptr;
gl::Program *programObject = GetValidProgram(context, program);
- if (!ValidateUniformCommonBase(context, programObject, uniformType, location, count, &uniform))
- {
- return false;
- }
-
- GLenum targetBoolType = VariableBoolVectorType(uniformType);
- bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT);
- if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- return true;
+ return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
+ ValidateUniformValue(context, valueType, uniform->type);
}
bool ValidateProgramUniformMatrix(gl::Context *context,
- GLenum matrixType,
+ GLenum valueType,
GLuint program,
GLint location,
GLsizei count,
@@ -2796,57 +2809,34 @@
const LinkedUniform *uniform = nullptr;
gl::Program *programObject = GetValidProgram(context, program);
- if (!ValidateUniformCommonBase(context, programObject, matrixType, location, count, &uniform))
- {
- return false;
- }
-
- if (uniform->type != matrixType)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- return true;
+ return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
+ ValidateUniformMatrixValue(context, valueType, uniform->type);
}
-bool ValidateUniform(gl::Context *context, GLenum uniformType, GLint location, GLsizei count)
+bool ValidateUniform(gl::Context *context, GLenum valueType, GLint location, GLsizei count)
{
// Check for ES3 uniform entry points
- if (VariableComponentType(uniformType) == GL_UNSIGNED_INT &&
- context->getClientMajorVersion() < 3)
+ if (VariableComponentType(valueType) == GL_UNSIGNED_INT && context->getClientMajorVersion() < 3)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
const LinkedUniform *uniform = nullptr;
- gl::Program *program = context->getGLState().getProgram();
- if (!ValidateUniformCommonBase(context, program, uniformType, location, count, &uniform))
- {
- return false;
- }
-
- GLenum targetBoolType = VariableBoolVectorType(uniformType);
- bool samplerUniformCheck = (IsSamplerType(uniform->type) && uniformType == GL_INT);
- if (!samplerUniformCheck && uniformType != uniform->type && targetBoolType != uniform->type)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- return true;
+ gl::Program *programObject = context->getGLState().getProgram();
+ return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
+ ValidateUniformValue(context, valueType, uniform->type);
}
bool ValidateUniformMatrix(gl::Context *context,
- GLenum matrixType,
+ GLenum valueType,
GLint location,
GLsizei count,
GLboolean transpose)
{
// Check for ES3 uniform entry points
- int rows = VariableRowCount(matrixType);
- int cols = VariableColumnCount(matrixType);
+ int rows = VariableRowCount(valueType);
+ int cols = VariableColumnCount(valueType);
if (rows != cols && context->getClientMajorVersion() < 3)
{
context->handleError(Error(GL_INVALID_OPERATION));
@@ -2860,19 +2850,9 @@
}
const LinkedUniform *uniform = nullptr;
- gl::Program *program = context->getGLState().getProgram();
- if (!ValidateUniformCommonBase(context, program, matrixType, location, count, &uniform))
- {
- return false;
- }
-
- if (uniform->type != matrixType)
- {
- context->handleError(Error(GL_INVALID_OPERATION));
- return false;
- }
-
- return true;
+ gl::Program *programObject = context->getGLState().getProgram();
+ return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
+ ValidateUniformMatrixValue(context, valueType, uniform->type);
}
bool ValidateStateQuery(ValidationContext *context,