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: