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
bool Program::isValidUniformLocation(GLint location) const
{
ASSERT(rx::IsIntegerCastSafe<GLint>(mProgram->getUniformIndices().size()));
return (location >= 0 && location < static_cast<GLint>(mProgram->getUniformIndices().size()));
const auto &uniformIndices = mProgram->getUniformIndices();
ASSERT(rx::IsIntegerCastSafe<GLint>(uniformIndices.size()));
return (location >= 0 && uniformIndices.find(location) != uniformIndices.end());
}
LinkedUniform *Program::getUniformByLocation(GLint location) const
......
......@@ -27,8 +27,8 @@ ProgramImpl::~ProgramImpl()
gl::LinkedUniform *ProgramImpl::getUniformByLocation(GLint location) const
{
ASSERT(location >= 0 && static_cast<size_t>(location) < mUniformIndex.size());
return mUniforms[mUniformIndex[location].index];
ASSERT(location >= 0 && mUniformIndex.find(location) != mUniformIndex.end());
return mUniforms[mUniformIndex.at(location).index];
}
gl::LinkedUniform *ProgramImpl::getUniformByName(const std::string &name) const
......@@ -55,15 +55,16 @@ GLint ProgramImpl::getUniformLocation(const std::string &name) const
size_t subscript = GL_INVALID_INDEX;
std::string baseName = gl::ParseUniformName(name, &subscript);
unsigned int numUniforms = mUniformIndex.size();
for (unsigned int location = 0; location < numUniforms; location++)
for (const auto &info : mUniformIndex)
{
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[index]->isArray();
const bool isArray = mUniforms[uniform.index]->isArray();
if ((isArray && mUniformIndex[location].element == subscript) ||
if ((isArray && uniform.element == subscript) ||
(subscript == GL_INVALID_INDEX))
{
return location;
......
......@@ -101,14 +101,14 @@ class ProgramImpl : angle::NonCopyable
unsigned int registerIndex, const gl::Caps &caps) = 0;
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::LinkedVarying> &getTransformFeedbackLinkedVaryings() const { return mTransformFeedbackLinkedVaryings; }
const std::vector<sh::Attribute> getShaderAttributes() { return mShaderAttributes; }
const SemanticIndexArray &getSemanticIndexes() const { return mSemanticIndex; }
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::LinkedVarying> &getTransformFeedbackLinkedVaryings() { return mTransformFeedbackLinkedVaryings; }
SemanticIndexArray &getSemanticIndexes() { return mSemanticIndex; }
......@@ -128,7 +128,10 @@ class ProgramImpl : angle::NonCopyable
protected:
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::LinkedVarying> mTransformFeedbackLinkedVaryings;
......
......@@ -529,12 +529,17 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
mUniformIndex.resize(uniformIndexCount);
for (unsigned int uniformIndexIndex = 0; uniformIndexIndex < uniformIndexCount; uniformIndexIndex++)
{
stream->readString(&mUniformIndex[uniformIndexIndex].name);
stream->readInt(&mUniformIndex[uniformIndexIndex].element);
stream->readInt(&mUniformIndex[uniformIndexIndex].index);
GLuint location;
stream->readInt(&location);
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>();
......@@ -756,11 +761,15 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
}
stream->writeInt(mUniformIndex.size());
for (size_t i = 0; i < mUniformIndex.size(); ++i)
for (const auto &uniform : mUniformIndex)
{
stream->writeString(mUniformIndex[i].name);
stream->writeInt(mUniformIndex[i].element);
stream->writeInt(mUniformIndex[i].index);
GLuint location = uniform.first;
stream->writeInt(location);
const gl::VariableLocation &variable = uniform.second;
stream->writeString(variable.name);
stream->writeInt(variable.element);
stream->writeInt(variable.index);
}
stream->writeInt(mUniformBlocks.size());
......@@ -1974,7 +1983,8 @@ bool ProgramD3D::indexUniforms(gl::InfoLog &infoLog, const gl::Caps &caps)
{
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,
GLint location = mFunctions->getUniformLocation(mProgramID, locationName.c_str());
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()));
// 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