Re^6-land "Move Uniform and UBO info to the gl::Program layer."
This data was previously stored entirely in the Impl level. Move
as much as possible to the GL level, using a read-only view in the
Impl level. Some information in D3D-specific, and should be stored
separately in the Impl.
This patch has a lot of refactoring that splits the D3D and GL info,
and moves as much validation as possible to the GL layer, where it
is shared between the back-ends.
Re-land with fix for dEQP unused uniforms. The fix involves storing
a local copy of all uniform data in the GL layer. This will also
let us validate sampler indexes during draw calls at the GL layer.
Re-re-land with a fix for multiply defined symbols on Clang.
Re-re-re-land with a fix for boolean uniforms and Uniform{1234}f.
Re^4-land with a fix for boolean uniform arrays and UBO uniforms.
Re^5-land with a fix for a test warning on Linux.
Re^6-land with a fix for transposed matrix uniform arrays.
BUG=angleproject:1123
TEST=end2end_tests, bots, dEQP GLES3.ubo and GLES2.uniform_api
Change-Id: Ie6fcde1c16eb05d67191b629338b88302a2563f5
Reviewed-on: https://chromium-review.googlesource.com/298971
Tryjob-Request: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 3a70ae9..bae8389 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -115,68 +115,41 @@
}
// Query the uniform information
- // TODO: A lot of this logic should be done at the gl::Program level
- GLint activeUniformMaxLength = 0;
- mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformMaxLength);
-
- std::vector<GLchar> uniformNameBuffer(activeUniformMaxLength);
-
- GLint uniformCount = 0;
- mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORMS, &uniformCount);
- for (GLint i = 0; i < uniformCount; i++)
+ ASSERT(mUniformRealLocationMap.empty());
+ const auto &uniforms = mData.getUniforms();
+ for (const gl::VariableLocation &entry : mData.getUniformLocations())
{
- GLsizei uniformNameLength = 0;
- GLint uniformSize = 0;
- GLenum uniformType = GL_NONE;
- mFunctions->getActiveUniform(mProgramID, i, static_cast<GLsizei>(uniformNameBuffer.size()),
- &uniformNameLength, &uniformSize, &uniformType,
- &uniformNameBuffer[0]);
-
- size_t subscript = 0;
- std::string uniformName = gl::ParseUniformName(std::string(&uniformNameBuffer[0], uniformNameLength), &subscript);
-
- bool isArray = uniformSize > 1 || subscript != GL_INVALID_INDEX;
-
- for (size_t arrayIndex = 0; arrayIndex < static_cast<size_t>(uniformSize); arrayIndex++)
+ // From the spec:
+ // "Locations for sequential array indices are not required to be sequential."
+ const gl::LinkedUniform &uniform = uniforms[entry.index];
+ std::stringstream fullNameStr;
+ fullNameStr << uniform.name;
+ if (uniform.isArray())
{
- std::string locationName = uniformName;
- if (isArray)
- {
- locationName += "[" + Str(static_cast<int>(arrayIndex)) + "]";
- }
-
- GLint location = mFunctions->getUniformLocation(mProgramID, locationName.c_str());
- if (location >= 0)
- {
- mUniformIndex[location] =
- gl::VariableLocation(uniformName, static_cast<unsigned int>(arrayIndex),
- static_cast<unsigned int>(mUniforms.size()));
-
- // If the uniform is a sampler, track it in the sampler bindings array
- if (gl::IsSamplerType(uniformType))
- {
- SamplerLocation samplerLoc;
- samplerLoc.samplerIndex = mSamplerBindings.size();
- samplerLoc.arrayIndex = arrayIndex;
- mSamplerUniformMap[location] = samplerLoc;
- }
- }
+ fullNameStr << "[" << entry.element << "]";
}
+ const std::string &fullName = fullNameStr.str();
- // ANGLE uses 0 to identify an non-array uniform.
- unsigned int arraySize = isArray ? static_cast<unsigned int>(uniformSize) : 0;
+ GLint realLocation = mFunctions->getUniformLocation(mProgramID, fullName.c_str());
+ mUniformRealLocationMap.push_back(realLocation);
+ }
- // TODO: determine uniform precision
- mUniforms.push_back(new gl::LinkedUniform(uniformType, GL_NONE, uniformName, arraySize, -1, sh::BlockMemberInfo::getDefaultBlockInfo()));
+ mUniformIndexToSamplerIndex.resize(mData.getUniforms().size(), GL_INVALID_INDEX);
+
+ for (size_t uniformId = 0; uniformId < uniforms.size(); ++uniformId)
+ {
+ const gl::LinkedUniform &linkedUniform = uniforms[uniformId];
+
+ if (!linkedUniform.isSampler() || !linkedUniform.staticUse)
+ continue;
+
+ mUniformIndexToSamplerIndex[uniformId] = mSamplerBindings.size();
// If uniform is a sampler type, insert it into the mSamplerBindings array
- if (gl::IsSamplerType(uniformType))
- {
- SamplerBindingGL samplerBinding;
- samplerBinding.textureType = gl::SamplerTypeToTextureType(uniformType);
- samplerBinding.boundTextureUnits.resize(uniformSize, 0);
- mSamplerBindings.push_back(samplerBinding);
- }
+ SamplerBindingGL samplerBinding;
+ samplerBinding.textureType = gl::SamplerTypeToTextureType(linkedUniform.type);
+ samplerBinding.boundTextureUnits.resize(linkedUniform.elementCount(), 0);
+ mSamplerBindings.push_back(samplerBinding);
}
return LinkResult(true, gl::Error(GL_NO_ERROR));
@@ -191,59 +164,61 @@
void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform1fv(location, count, v);
+ mFunctions->uniform1fv(uniLoc(location), count, v);
}
void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform2fv(location, count, v);
+ mFunctions->uniform2fv(uniLoc(location), count, v);
}
void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform3fv(location, count, v);
+ mFunctions->uniform3fv(uniLoc(location), count, v);
}
void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform4fv(location, count, v);
+ mFunctions->uniform4fv(uniLoc(location), count, v);
}
void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform1iv(location, count, v);
+ mFunctions->uniform1iv(uniLoc(location), count, v);
- auto iter = mSamplerUniformMap.find(location);
- if (iter != mSamplerUniformMap.end())
+ const gl::VariableLocation &locationEntry = mData.getUniformLocations()[location];
+
+ size_t samplerIndex = mUniformIndexToSamplerIndex[locationEntry.index];
+ if (samplerIndex != GL_INVALID_INDEX)
{
- const SamplerLocation &samplerLoc = iter->second;
- std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerLoc.samplerIndex].boundTextureUnits;
+ std::vector<GLuint> &boundTextureUnits = mSamplerBindings[samplerIndex].boundTextureUnits;
- size_t copyCount = std::max<size_t>(count, boundTextureUnits.size() - samplerLoc.arrayIndex);
- std::copy(v, v + copyCount, boundTextureUnits.begin() + samplerLoc.arrayIndex);
+ size_t copyCount =
+ std::max<size_t>(count, boundTextureUnits.size() - locationEntry.element);
+ std::copy(v, v + copyCount, boundTextureUnits.begin() + locationEntry.element);
}
}
void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform2iv(location, count, v);
+ mFunctions->uniform2iv(uniLoc(location), count, v);
}
void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform3iv(location, count, v);
+ mFunctions->uniform3iv(uniLoc(location), count, v);
}
void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform4iv(location, count, v);
+ mFunctions->uniform4iv(uniLoc(location), count, v);
}
void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
@@ -255,88 +230,73 @@
void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform2uiv(location, count, v);
+ mFunctions->uniform2uiv(uniLoc(location), count, v);
}
void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform3uiv(location, count, v);
+ mFunctions->uniform3uiv(uniLoc(location), count, v);
}
void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniform4uiv(location, count, v);
+ mFunctions->uniform4uiv(uniLoc(location), count, v);
}
void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix2fv(location, count, transpose, value);
+ mFunctions->uniformMatrix2fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix3fv(location, count, transpose, value);
+ mFunctions->uniformMatrix3fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix4fv(location, count, transpose, value);
+ mFunctions->uniformMatrix4fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix2x3fv(location, count, transpose, value);
+ mFunctions->uniformMatrix2x3fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix3x2fv(location, count, transpose, value);
+ mFunctions->uniformMatrix3x2fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix2x4fv(location, count, transpose, value);
+ mFunctions->uniformMatrix2x4fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix4x2fv(location, count, transpose, value);
+ mFunctions->uniformMatrix4x2fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix3x4fv(location, count, transpose, value);
+ mFunctions->uniformMatrix3x4fv(uniLoc(location), count, transpose, value);
}
void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
{
mStateManager->useProgram(mProgramID);
- mFunctions->uniformMatrix4x3fv(location, count, transpose, value);
-}
-
-void ProgramGL::getUniformfv(GLint location, GLfloat *params)
-{
- mFunctions->getUniformfv(mProgramID, location, params);
-}
-
-void ProgramGL::getUniformiv(GLint location, GLint *params)
-{
- mFunctions->getUniformiv(mProgramID, location, params);
-}
-
-void ProgramGL::getUniformuiv(GLint location, GLuint *params)
-{
- mFunctions->getUniformuiv(mProgramID, location, params);
+ mFunctions->uniformMatrix4x3fv(uniLoc(location), count, transpose, value);
}
bool ProgramGL::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
@@ -347,10 +307,9 @@
void ProgramGL::reset()
{
- ProgramImpl::reset();
-
- mSamplerUniformMap.clear();
+ mUniformRealLocationMap.clear();
mSamplerBindings.clear();
+ mUniformIndexToSamplerIndex.clear();
}
GLuint ProgramGL::getProgramID() const
@@ -363,4 +322,9 @@
return mSamplerBindings;
}
+void ProgramGL::gatherUniformBlockInfo(std::vector<gl::UniformBlock> * /*uniformBlocks*/,
+ std::vector<gl::LinkedUniform> * /*uniforms*/)
+{
+ // TODO(jmadill): Gather uniform block layout info, and data sizes.
+}
}