Commit 95137842 by Geoff Lang

Use a map to store uniform locations instead of a vector.

Some intel drivers use seemingly arbitrary integers as uniform locations. This causes the location vector to be resized to arbitrarily large sizes. BUG=angleproject:882 Change-Id: I8db89178907dd6206eb8e646a0b426aa9bac0832 Reviewed-on: https://chromium-review.googlesource.com/274816Reviewed-by: 's avatarKenneth Russell <kbr@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 40888aab
...@@ -831,8 +831,9 @@ GLint Program::getActiveUniformi(GLuint index, GLenum pname) const ...@@ -831,8 +831,9 @@ GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
bool Program::isValidUniformLocation(GLint location) const bool Program::isValidUniformLocation(GLint location) const
{ {
ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size())); const auto &uniformIndices = mProgram->getUniformIndices();
return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size())); ASSERT(rx::IsIntegerCastSafe<GLint>(uniformIndices.size()));
return (location >= 0 && uniformIndices.find(location) != uniformIndices.end());
} }
LinkedUniform *Program::getUniformByLocation(GLint location) const LinkedUniform *Program::getUniformByLocation(GLint location) const
......
...@@ -27,8 +27,8 @@ ProgramImpl::~ProgramImpl() ...@@ -27,8 +27,8 @@ ProgramImpl::~ProgramImpl()
gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
{ {
ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size()); ASSERT(location >= 0 && mUniformIndex.find(location) != mUniformIndex.end());
return mUniforms[mUniformIndex[location].index]; return mUniforms[mUniformIndex.at(location).index];
} }
gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
...@@ -55,15 +55,16 @@ GLint ProgramImpl::getUniformLocation(const std::string &name) const ...@@ -55,15 +55,16 @@ GLint ProgramImpl::getUniformLocation(const std::string &name) const
size_t subscript = GL_INVALID_INDEX; size_t subscript = GL_INVALID_INDEX;
std::string baseName = gl::ParseUniformName(name, &subscript); std::string baseName = gl::ParseUniformName(name, &subscript);
unsigned int numUniforms = mUniformIndex.size(); for (const auto &info : mUniformIndex)
for (unsigned int location = 0; location < numUniforms; location++)
{ {
if (mUniformIndex[location].name == baseName) GLuint location = info.first;
const gl::VariableLocation &uniform = info.second;
if (uniform.name == baseName)
{ {
const int index = mUniformIndex[location].index; const bool isArray = mUniforms[uniform.index]->isArray();
const bool isArray = mUniforms[index]->isArray();
if ((isArray && mUniformIndex[location].element == subscript) || if ((isArray && uniform.element == subscript) ||
(subscript == GL_INVALID_INDEX)) (subscript == GL_INVALID_INDEX))
{ {
return location; return location;
......
...@@ -101,14 +101,14 @@ class ProgramImpl : angle::NonCopyable ...@@ -101,14 +101,14 @@ class ProgramImpl : angle::NonCopyable
unsigned int registerIndex, const gl::Caps &caps) = 0; unsigned int registerIndex, const gl::Caps &caps) = 0;
const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; } const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
const std::vector<gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; } const std::map<GLuint, gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; } const std::vector<gl::UniformBlock*> &getUniformBlocks() const { return mUniformBlocks; }
const std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; } const std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; }
const std::vector<sh::Attribute> getShaderAttributes() { return mShaderAttributes; } const std::vector<sh::Attribute> getShaderAttributes() { return mShaderAttributes; }
const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndex; } const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndex; }
std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; } std::vector<gl::LinkedUniform*> &getUniforms() { return mUniforms; }
std::vector<gl::VariableLocation> &getUniformIndices() { return mUniformIndex; } std::map<GLuint, gl::VariableLocation> &getUniformIndices() { return mUniformIndex; }
std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; } std::vector<gl::UniformBlock*> &getUniformBlocks() { return mUniformBlocks; }
std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; } std::vector<gl::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; }
SemanticIndexArray &getSemanticIndexes() { return mSemanticIndex; } SemanticIndexArray &getSemanticIndexes() { return mSemanticIndex; }
...@@ -128,7 +128,10 @@ class ProgramImpl : angle::NonCopyable ...@@ -128,7 +128,10 @@ class ProgramImpl : angle::NonCopyable
protected: protected:
std::vector<gl::LinkedUniform*> mUniforms; std::vector<gl::LinkedUniform*> mUniforms;
std::vector<gl::VariableLocation> mUniformIndex;
// TODO: use a hash map
std::map<GLuint, gl::VariableLocation> mUniformIndex;
std::vector<gl::UniformBlock*> mUniformBlocks; std::vector<gl::UniformBlock*> mUniformBlocks;
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings; std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
......
...@@ -529,12 +529,17 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -529,12 +529,17 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
mUniformIndex.resize(uniformIndexCount);
for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++) for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
{ {
stream->readString(&mUniformIndex[uniformIndexIndex].name); GLuint location;
stream->readInt(&mUniformIndex[uniformIndexIndex].element); stream->readInt(&location);
stream->readInt(&mUniformIndex[uniformIndexIndex].index);
gl::VariableLocation variable;
stream->readString(&variable.name);
stream->readInt(&variable.element);
stream->readInt(&variable.index);
mUniformIndex[location] = variable;
} }
unsigned int uniformBlockCount = stream->readInt<unsigned int>(); unsigned int uniformBlockCount = stream->readInt<unsigned int>();
...@@ -756,11 +761,15 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -756,11 +761,15 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
} }
stream->writeInt(mUniformIndex.size()); stream->writeInt(mUniformIndex.size());
for (size_t i = 0; i < mUniformIndex.size(); ++i) for (const auto &uniform : mUniformIndex)
{ {
stream->writeString(mUniformIndex[i].name); GLuint location = uniform.first;
stream->writeInt(mUniformIndex[i].element); stream->writeInt(location);
stream->writeInt(mUniformIndex[i].index);
const gl::VariableLocation &variable = uniform.second;
stream->writeString(variable.name);
stream->writeInt(variable.element);
stream->writeInt(variable.index);
} }
stream->writeInt(mUniformBlocks.size()); stream->writeInt(mUniformBlocks.size());
...@@ -1974,7 +1983,8 @@ bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps) ...@@ -1974,7 +1983,8 @@ bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
{ {
if (!uniform.isBuiltIn()) if (!uniform.isBuiltIn())
{ {
mUniformIndex.push_back(gl::VariableLocation(uniform.name, arrayIndex, uniformIndex)); // Assign in-order uniform locations
mUniformIndex[mUniformIndex.size()] = gl::VariableLocation(uniform.name, arrayIndex, uniformIndex);
} }
} }
} }
......
...@@ -147,12 +147,6 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog, ...@@ -147,12 +147,6 @@ LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog,
GLint location = mFunctions->getUniformLocation(mProgramID, locationName.c_str()); GLint location = mFunctions->getUniformLocation(mProgramID, locationName.c_str());
if (location >= 0) if (location >= 0)
{ {
// Make sure the uniform index array is large enough
if (static_cast<size_t>(location) >= mUniformIndex.size())
{
mUniformIndex.resize(location + 1);
}
mUniformIndex[location] = gl::VariableLocation(uniformName, arrayIndex, static_cast<unsigned int>(mUniforms.size())); mUniformIndex[location] = gl::VariableLocation(uniformName, arrayIndex, static_cast<unsigned int>(mUniforms.size()));
// If the uniform is a sampler, track it in the sampler bindings array // If the uniform is a sampler, track it in the sampler bindings array
......
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