Fix leaking uniforms.
We were leaking memory for uniforms that were previously defined but
don't have a location, e.g. structures.
This change also verifies that such uniforms have the same type in both
shaders. Also, simplify uniform lookup.
Bug chromium:863682
Change-Id: I468aace4df6f5329dc7bb9f33bf9bf533a743ae1
Reviewed-on: https://swiftshader-review.googlesource.com/19928
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Corentin Wallez <cwallez@google.com>
diff --git a/src/Common/Version.h b/src/Common/Version.h
index 4dbc92f..eae755d 100644
--- a/src/Common/Version.h
+++ b/src/Common/Version.h
@@ -15,7 +15,7 @@
#define MAJOR_VERSION 4
#define MINOR_VERSION 1
#define BUILD_VERSION 0
-#define BUILD_REVISION 0
+#define BUILD_REVISION 1
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
diff --git a/src/Main/Config.hpp b/src/Main/Config.hpp
index 764bfed..017e38b 100644
--- a/src/Main/Config.hpp
+++ b/src/Main/Config.hpp
@@ -80,7 +80,7 @@
TEXTURE_IMAGE_UNITS = 16,
VERTEX_TEXTURE_IMAGE_UNITS = 16,
TOTAL_IMAGE_UNITS = TEXTURE_IMAGE_UNITS + VERTEX_TEXTURE_IMAGE_UNITS,
- FRAGMENT_UNIFORM_VECTORS = 227,
+ FRAGMENT_UNIFORM_VECTORS = 264,
VERTEX_UNIFORM_VECTORS = 259,
MAX_VERTEX_INPUTS = 32,
MAX_VERTEX_OUTPUTS = 34,
diff --git a/src/OpenGL/libGLESv2/Program.cpp b/src/OpenGL/libGLESv2/Program.cpp
index d2cff33..9b10a7f 100644
--- a/src/OpenGL/libGLESv2/Program.cpp
+++ b/src/OpenGL/libGLESv2/Program.cpp
@@ -71,14 +71,6 @@
data = new unsigned char[bytes];
memset(data, 0, bytes);
}
- else
- {
- data = nullptr;
- }
- dirty = true;
-
- psRegisterIndex = -1;
- vsRegisterIndex = -1;
}
Uniform::~Uniform()
@@ -368,24 +360,20 @@
return TEXTURE_2D;
}
- bool Program::isUniformDefined(const std::string &name) const
+ Uniform *Program::getUniform(const std::string &name) const
{
unsigned int subscript = GL_INVALID_INDEX;
std::string baseName = es2::ParseUniformName(name, &subscript);
- size_t numUniforms = uniformIndex.size();
- for(size_t location = 0; location < numUniforms; location++)
+ for(size_t index = 0; index < uniforms.size(); index++)
{
- const unsigned int index = uniformIndex[location].index;
- if((uniformIndex[location].name == baseName) && ((index == GL_INVALID_INDEX) ||
- ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) ||
- (subscript == GL_INVALID_INDEX))))
+ if(uniforms[index]->name == baseName)
{
- return true;
+ return uniforms[index];
}
}
- return false;
+ return nullptr;
}
GLint Program::getUniformLocation(const std::string &name) const
@@ -393,15 +381,26 @@
unsigned int subscript = GL_INVALID_INDEX;
std::string baseName = es2::ParseUniformName(name, &subscript);
- size_t numUniforms = uniformIndex.size();
- for(size_t location = 0; location < numUniforms; location++)
+ for(size_t location = 0; location < uniformIndex.size(); location++)
{
- const unsigned int index = uniformIndex[location].index;
- if((index != GL_INVALID_INDEX) && (uniformIndex[location].name == baseName) &&
- ((uniforms[index]->isArray() && uniformIndex[location].element == subscript) ||
- (subscript == GL_INVALID_INDEX)))
+ if(uniformIndex[location].name == baseName)
{
- return (GLint)location;
+ const unsigned int index = uniformIndex[location].index;
+
+ if(index != GL_INVALID_INDEX)
+ {
+ if(subscript == GL_INVALID_INDEX)
+ {
+ return (GLint)location;
+ }
+ else if(uniforms[index]->isArray())
+ {
+ if(uniformIndex[location].element == subscript)
+ {
+ return (GLint)location;
+ }
+ }
+ }
}
}
@@ -1717,6 +1716,7 @@
blockIndex = getUniformBlockIndex(activeUniformBlocks[uniform.blockId].name);
ASSERT(blockIndex != GL_INVALID_INDEX);
}
+
if(!defineUniform(shader->getType(), uniform, Uniform::BlockInfo(uniform, blockIndex)))
{
return false;
@@ -1737,7 +1737,7 @@
bool Program::defineUniform(GLenum shader, const glsl::Uniform &glslUniform, const Uniform::BlockInfo& blockInfo)
{
if(IsSamplerUniform(glslUniform.type))
- {
+ {
int index = glslUniform.registerIndex;
do
@@ -1819,15 +1819,24 @@
index++;
}
while(index < glslUniform.registerIndex + static_cast<int>(glslUniform.arraySize));
- }
+ }
- Uniform *uniform = 0;
- GLint location = getUniformLocation(glslUniform.name);
+ Uniform *uniform = getUniform(glslUniform.name);
- if(location >= 0) // Previously defined, types must match
+ if(!uniform)
{
- uniform = uniforms[uniformIndex[location].index];
+ uniform = new Uniform(glslUniform, blockInfo);
+ uniforms.push_back(uniform);
+ unsigned int index = (blockInfo.index == -1) ? static_cast<unsigned int>(uniforms.size() - 1) : GL_INVALID_INDEX;
+
+ for(int i = 0; i < uniform->size(); i++)
+ {
+ uniformIndex.push_back(UniformLocation(glslUniform.name, i, index));
+ }
+ }
+ else // Previously defined, types must match
+ {
if(uniform->type != glslUniform.type)
{
appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
@@ -1845,15 +1854,6 @@
return false;
}
}
- else
- {
- uniform = new Uniform(glslUniform, blockInfo);
- }
-
- if(!uniform)
- {
- return false;
- }
if(shader == GL_VERTEX_SHADER)
{
@@ -1865,17 +1865,6 @@
}
else UNREACHABLE(shader);
- if(!isUniformDefined(glslUniform.name))
- {
- uniforms.push_back(uniform);
- unsigned int index = (blockInfo.index == -1) ? static_cast<unsigned int>(uniforms.size() - 1) : GL_INVALID_INDEX;
-
- for(int i = 0; i < uniform->size(); i++)
- {
- uniformIndex.push_back(UniformLocation(glslUniform.name, i, index));
- }
- }
-
if(shader == GL_VERTEX_SHADER)
{
if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
diff --git a/src/OpenGL/libGLESv2/Program.h b/src/OpenGL/libGLESv2/Program.h
index 4d89d7a..6f9940b 100644
--- a/src/OpenGL/libGLESv2/Program.h
+++ b/src/OpenGL/libGLESv2/Program.h
@@ -64,11 +64,11 @@
const BlockInfo blockInfo;
std::vector<glsl::ShaderVariable> fields;
- unsigned char *data;
- bool dirty;
+ unsigned char *data = nullptr;
+ bool dirty = true;
- short psRegisterIndex;
- short vsRegisterIndex;
+ short psRegisterIndex = -1;
+ short vsRegisterIndex = -1;
};
// Helper struct representing a single shader uniform block
@@ -145,7 +145,6 @@
GLuint getUniformBlockBinding(GLuint uniformBlockIndex) const;
void getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const;
- bool isUniformDefined(const std::string &name) const;
GLint getUniformLocation(const std::string &name) const;
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
bool setUniform2fv(GLint location, GLsizei count, const GLfloat *v);
@@ -231,6 +230,7 @@
bool linkAttributes();
int getAttributeBinding(const glsl::Attribute &attribute);
+ Uniform *getUniform(const std::string &name) const;
bool linkUniforms(const Shader *shader);
bool linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader);
bool areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2);
@@ -275,7 +275,6 @@
static unsigned int issueSerial();
- private:
FragmentShader *fragmentShader;
VertexShader *vertexShader;