Fix validation of uniform block size.
Uniform block members should not be validated against the
GL_MAX_VERTEX_UNIFORM_VECTORS and GL_MAX_FRAGMENT_UNIFORM_VECTORS
limits. Instead, block sizes should not exceed MAX_UNIFORM_BLOCK_SIZE.
Also move uniform block index validation to the entry functions.
Bug b/111803744
Change-Id: I0ea530813d1f2c29141dc64a93aa10f50460885b
Reviewed-on: https://swiftshader-review.googlesource.com/20028
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index 9b10a7f..77912cc 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -51,14 +51,6 @@
matrixStride = uniform.blockInfo.matrixStride;
isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;
}
- else
- {
- index = -1;
- offset = -1;
- arrayStride = -1;
- matrixStride = -1;
- isRowMajorMatrix = false;
- }
}
Uniform::Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo)
@@ -492,20 +484,15 @@
void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
- if(uniformBlockIndex >= getActiveUniformBlockCount())
- {
- return error(GL_INVALID_VALUE);
- }
+ ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
}
GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
{
- if(uniformBlockIndex >= getActiveUniformBlockCount())
- {
- return error(GL_INVALID_VALUE, GL_INVALID_INDEX);
- }
+ ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
+
return uniformBlockBindings[uniformBlockIndex];
}
@@ -1713,8 +1700,24 @@
{
const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;
ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());
- blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);
+ const std::string &uniformBlockName = activeUniformBlocks[uniform.blockId].name;
+ blockIndex = getUniformBlockIndex(uniformBlockName);
ASSERT(blockIndex != GL_INVALID_INDEX);
+
+ if(activeUniformBlocks[uniform.blockId].dataSize > MAX_UNIFORM_BLOCK_SIZE)
+ {
+ if(shader->getType() == GL_VERTEX_SHADER)
+ {
+ appendToInfoLog("Vertex shader active uniform block (%s) exceeds GL_MAX_UNIFORM_BLOCK_SIZE (%d)", uniformBlockName.c_str(), MAX_UNIFORM_BLOCK_SIZE);
+ return false;
+ }
+ else if(shader->getType() == GL_FRAGMENT_SHADER)
+ {
+ appendToInfoLog("Fragment shader active uniform block (%s) exceeds GL_MAX_UNIFORM_BLOCK_SIZE (%d)", uniformBlockName.c_str(), MAX_UNIFORM_BLOCK_SIZE);
+ return false;
+ }
+ else UNREACHABLE(shader->getType());
+ }
}
if(!defineUniform(shader->getType(), uniform, Uniform::BlockInfo(uniform, blockIndex)))
@@ -1865,23 +1868,26 @@
}
else UNREACHABLE(shader);
- if(shader == GL_VERTEX_SHADER)
+ if(uniform->blockInfo.index < 0)
{
- if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
+ if(shader == GL_VERTEX_SHADER)
{
- appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
- return false;
+ if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
+ {
+ appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
+ return false;
+ }
}
- }
- else if(shader == GL_FRAGMENT_SHADER)
- {
- if(glslUniform.registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
+ else if(shader == GL_FRAGMENT_SHADER)
{
- appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
- return false;
+ if(glslUniform.registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
+ {
+ appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
+ return false;
+ }
}
+ else UNREACHABLE(shader);
}
- else UNREACHABLE(shader);
return true;
}
@@ -2859,10 +2865,7 @@
void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const
{
- if(index >= getActiveUniformBlockCount())
- {
- return error(GL_INVALID_VALUE);
- }
+ ASSERT(index < getActiveUniformBlockCount());
const UniformBlock &uniformBlock = *uniformBlocks[index];
diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h
index 6f9940b..501d081 100644
--- a/src/OpenGL/libGLESv2/Program.h
+++ b/src/OpenGL/libGLESv2/Program.h
@@ -42,11 +42,11 @@
{
BlockInfo(const glsl::Uniform& uniform, int blockIndex);
- int index;
- int offset;
- int arrayStride;
- int matrixStride;
- bool isRowMajorMatrix;
+ int index = -1;
+ int offset = -1;
+ int arrayStride = -1;
+ int matrixStride = -1;
+ bool isRowMajorMatrix = false;
};
Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo);
diff --git a/src/OpenGL/libGLESv2/libGLESv3.cpp b/src/OpenGL/libGLESv2/libGLESv3.cpp
index adb24d7..b4f5377 100644
--- a/src/OpenGL/libGLESv2/libGLESv3.cpp
+++ b/src/OpenGL/libGLESv2/libGLESv3.cpp
@@ -2629,6 +2629,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
switch(pname)
{
case GL_UNIFORM_BLOCK_BINDING:
@@ -2669,6 +2674,11 @@
return error(GL_INVALID_OPERATION);
}
+ if(uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
}
}
@@ -2694,6 +2704,11 @@
return error(GL_INVALID_VALUE);
}
+ if(uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
}
}