OSDN Git Service

Fix validation of uniform block size.
authorNicolas Capens <capn@google.com>
Mon, 30 Jul 2018 20:42:49 +0000 (16:42 -0400)
committerNicolas Capens <nicolascapens@google.com>
Tue, 31 Jul 2018 14:59:26 +0000 (14:59 +0000)
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>
src/OpenGL/libGLESv2/Program.cpp
src/OpenGL/libGLESv2/Program.h
src/OpenGL/libGLESv2/libGLESv3.cpp

index 9b10a7f..77912cc 100644 (file)
@@ -51,14 +51,6 @@ namespace es2
                        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 @@ namespace es2
 
        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 @@ namespace es2
                        {
                                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 @@ namespace es2
                }
                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 @@ namespace es2
 
        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];
 
index 6f9940b..501d081 100644 (file)
@@ -42,11 +42,11 @@ namespace es2
                {
                        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);
index adb24d7..b4f5377 100644 (file)
@@ -2629,6 +2629,11 @@ GL_APICALL void GL_APIENTRY glGetActiveUniformBlockiv(GLuint program, GLuint uni
                        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 @@ GL_APICALL void GL_APIENTRY glGetActiveUniformBlockName(GLuint program, GLuint u
                        return error(GL_INVALID_OPERATION);
                }
 
+               if(uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+               {
+                       return error(GL_INVALID_VALUE);
+               }
+
                programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
        }
 }
@@ -2694,6 +2704,11 @@ GL_APICALL void GL_APIENTRY glUniformBlockBinding(GLuint program, GLuint uniform
                        return error(GL_INVALID_VALUE);
                }
 
+               if(uniformBlockIndex >= programObject->getActiveUniformBlockCount())
+               {
+                       return error(GL_INVALID_VALUE);
+               }
+
                programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
        }
 }