Commit f5f74ae0 by Frank Henigman Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 74da73fe
...@@ -1358,6 +1358,91 @@ bool ValidateGetInternalFormativBase(Context *context, ...@@ -1358,6 +1358,91 @@ bool ValidateGetInternalFormativBase(Context *context,
return true; 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 } // anonymous namespace
bool ValidTextureTarget(const ValidationContext *context, GLenum target) bool ValidTextureTarget(const ValidationContext *context, GLenum target)
...@@ -2689,68 +2774,8 @@ bool ValidateGetQueryObjectui64vRobustANGLE(Context *context, ...@@ -2689,68 +2774,8 @@ bool ValidateGetQueryObjectui64vRobustANGLE(Context *context,
return true; 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, bool ValidateProgramUniform(gl::Context *context,
GLenum uniformType, GLenum valueType,
GLuint program, GLuint program,
GLint location, GLint location,
GLsizei count) GLsizei count)
...@@ -2764,24 +2789,12 @@ bool ValidateProgramUniform(gl::Context *context, ...@@ -2764,24 +2789,12 @@ bool ValidateProgramUniform(gl::Context *context,
const LinkedUniform *uniform = nullptr; const LinkedUniform *uniform = nullptr;
gl::Program *programObject = GetValidProgram(context, program); gl::Program *programObject = GetValidProgram(context, program);
if (!ValidateUniformCommonBase(context, programObject, uniformType, location, count, &uniform)) return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
{ ValidateUniformValue(context, valueType, uniform->type);
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;
} }
bool ValidateProgramUniformMatrix(gl::Context *context, bool ValidateProgramUniformMatrix(gl::Context *context,
GLenum matrixType, GLenum valueType,
GLuint program, GLuint program,
GLint location, GLint location,
GLsizei count, GLsizei count,
...@@ -2796,57 +2809,34 @@ bool ValidateProgramUniformMatrix(gl::Context *context, ...@@ -2796,57 +2809,34 @@ bool ValidateProgramUniformMatrix(gl::Context *context,
const LinkedUniform *uniform = nullptr; const LinkedUniform *uniform = nullptr;
gl::Program *programObject = GetValidProgram(context, program); gl::Program *programObject = GetValidProgram(context, program);
if (!ValidateUniformCommonBase(context, programObject, matrixType, location, count, &uniform)) return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
{ ValidateUniformMatrixValue(context, valueType, uniform->type);
return false;
}
if (uniform->type != matrixType)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
return true;
} }
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 // Check for ES3 uniform entry points
if (VariableComponentType(uniformType) == GL_UNSIGNED_INT && if (VariableComponentType(valueType) == GL_UNSIGNED_INT && context->getClientMajorVersion() < 3)
context->getClientMajorVersion() < 3)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
return false; return false;
} }
const LinkedUniform *uniform = nullptr; const LinkedUniform *uniform = nullptr;
gl::Program *program = context->getGLState().getProgram(); gl::Program *programObject = context->getGLState().getProgram();
if (!ValidateUniformCommonBase(context, program, uniformType, location, count, &uniform)) return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
{ ValidateUniformValue(context, valueType, uniform->type);
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;
} }
bool ValidateUniformMatrix(gl::Context *context, bool ValidateUniformMatrix(gl::Context *context,
GLenum matrixType, GLenum valueType,
GLint location, GLint location,
GLsizei count, GLsizei count,
GLboolean transpose) GLboolean transpose)
{ {
// Check for ES3 uniform entry points // Check for ES3 uniform entry points
int rows = VariableRowCount(matrixType); int rows = VariableRowCount(valueType);
int cols = VariableColumnCount(matrixType); int cols = VariableColumnCount(valueType);
if (rows != cols && context->getClientMajorVersion() < 3) if (rows != cols && context->getClientMajorVersion() < 3)
{ {
context->handleError(Error(GL_INVALID_OPERATION)); context->handleError(Error(GL_INVALID_OPERATION));
...@@ -2860,19 +2850,9 @@ bool ValidateUniformMatrix(gl::Context *context, ...@@ -2860,19 +2850,9 @@ bool ValidateUniformMatrix(gl::Context *context,
} }
const LinkedUniform *uniform = nullptr; const LinkedUniform *uniform = nullptr;
gl::Program *program = context->getGLState().getProgram(); gl::Program *programObject = context->getGLState().getProgram();
if (!ValidateUniformCommonBase(context, program, matrixType, location, count, &uniform)) return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
{ ValidateUniformMatrixValue(context, valueType, uniform->type);
return false;
}
if (uniform->type != matrixType)
{
context->handleError(Error(GL_INVALID_OPERATION));
return false;
}
return true;
} }
bool ValidateStateQuery(ValidationContext *context, bool ValidateStateQuery(ValidationContext *context,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment