Optimize resolveLink.
This changes the program query to resolve the link if required. If the
validation layer is skipped the link is resolved in the gl::Context.
Resolving the link on program query allows us to avoid resolving the
link on most of the gl::Program query APIs.
This improves inlining and particularly affects uniform update. It
fixes a performance regression introduced by the parallel shader
linking extension. Gives a 17% increased score on a uniform benchmark.
Also fixes two missing cases of checking for the extension in our
validation code.
Note that some bugs might still exist when the validation layer is
disabled.
Bug: angleproject:2851
Change-Id: I5d725eede3fa147cedf2ce0129791b3412a97a61
Reviewed-on: https://chromium-review.googlesource.com/1255509
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Yuly Novikov <ynovikov@google.com>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 374e174..f1efed8 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -1024,7 +1024,7 @@
case GL_SHADER:
return getShader(name);
case GL_PROGRAM:
- return getProgram(name);
+ return getProgramNoResolveLink(name);
case GL_VERTEX_ARRAY:
return getVertexArray(name);
case GL_QUERY:
@@ -1178,7 +1178,7 @@
void Context::useProgram(GLuint program)
{
- mGLState.setProgram(this, getProgram(program));
+ mGLState.setProgram(this, getProgramResolveLink(program));
mStateCache.onProgramExecutableChange(this);
}
@@ -2340,7 +2340,7 @@
void Context::bindUniformLocation(GLuint program, GLint location, const GLchar *name)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->bindUniformLocation(location, name);
@@ -2538,7 +2538,7 @@
void Context::bindFragmentInputLocation(GLuint program, GLint location, const GLchar *name)
{
- auto *programObject = getProgram(program);
+ auto *programObject = getProgramResolveLink(program);
programObject->bindFragmentInputLocation(location, name);
}
@@ -2549,14 +2549,14 @@
GLint components,
const GLfloat *coeffs)
{
- auto *programObject = getProgram(program);
+ auto *programObject = getProgramResolveLink(program);
programObject->pathFragmentInputGen(location, genMode, components, coeffs);
}
GLuint Context::getProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name)
{
- const auto *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
return QueryProgramResourceIndex(programObject, programInterface, name);
}
@@ -2567,7 +2567,7 @@
GLsizei *length,
GLchar *name)
{
- const auto *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
QueryProgramResourceName(programObject, programInterface, index, bufSize, length, name);
}
@@ -2575,7 +2575,7 @@
GLenum programInterface,
const GLchar *name)
{
- const auto *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
return QueryProgramResourceLocation(programObject, programInterface, name);
}
@@ -2588,7 +2588,7 @@
GLsizei *length,
GLint *params)
{
- const auto *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
QueryProgramResourceiv(programObject, programInterface, index, propCount, props, bufSize,
length, params);
}
@@ -2598,7 +2598,7 @@
GLenum pname,
GLint *params)
{
- const auto *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
QueryProgramInterfaceiv(programObject, programInterface, pname, params);
}
@@ -2960,7 +2960,7 @@
void Context::programParameteri(GLuint program, GLenum pname, GLint value)
{
- gl::Program *programObject = getProgram(program);
+ gl::Program *programObject = getProgramResolveLink(program);
SetProgramParameteri(programObject, pname, value);
}
@@ -5018,8 +5018,8 @@
void Context::bindAttribLocation(GLuint program, GLuint index, const GLchar *name)
{
- Program *programObject = getProgram(program);
- // TODO(jmadill): Re-use this from the validation if possible.
+ // Ideally we could share the program query with the validation layer if possible.
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->bindAttributeLocation(index, name);
}
@@ -5313,7 +5313,7 @@
void Context::detachShader(GLuint program, GLuint shader)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramNoResolveLink(program);
ASSERT(programObject);
Shader *shaderObject = getShader(shader);
@@ -5362,7 +5362,7 @@
GLenum *type,
GLchar *name)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getActiveAttribute(index, bufsize, length, size, type, name);
}
@@ -5375,21 +5375,21 @@
GLenum *type,
GLchar *name)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getActiveUniform(index, bufsize, length, size, type, name);
}
void Context::getAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramNoResolveLink(program);
ASSERT(programObject);
programObject->getAttachedShaders(maxcount, count, shaders);
}
GLint Context::getAttribLocation(GLuint program, const GLchar *name)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
return programObject->getAttributeLocation(name);
}
@@ -5459,7 +5459,9 @@
void Context::getProgramiv(GLuint program, GLenum pname, GLint *params)
{
- Program *programObject = getProgram(program);
+ // Don't resolve link if checking the link completion status.
+ Program *programObject = (pname == GL_COMPLETION_STATUS_KHR ? getProgramNoResolveLink(program)
+ : getProgramResolveLink(program));
ASSERT(programObject);
QueryProgramiv(this, programObject, pname, params);
}
@@ -5480,7 +5482,7 @@
void Context::getProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getInfoLog(bufsize, length, infolog);
}
@@ -5598,7 +5600,7 @@
void Context::getUniformfv(GLuint program, GLint location, GLfloat *params)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getUniformfv(this, location, params);
}
@@ -5614,7 +5616,7 @@
void Context::getUniformiv(GLuint program, GLint location, GLint *params)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getUniformiv(this, location, params);
}
@@ -5630,7 +5632,7 @@
GLint Context::getUniformLocation(GLuint program, const GLchar *name)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
return programObject->getUniformLocation(name);
}
@@ -5667,7 +5669,7 @@
return GL_FALSE;
}
- return (getProgram(program) ? GL_TRUE : GL_FALSE);
+ return (getProgramNoResolveLink(program) ? GL_TRUE : GL_FALSE);
}
GLboolean Context::isRenderbuffer(GLuint renderbuffer)
@@ -5702,7 +5704,7 @@
void Context::linkProgram(GLuint program)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramNoResolveLink(program);
ASSERT(programObject);
handleError(programObject->link(this));
@@ -5715,6 +5717,7 @@
// ProgramD3D.
if (programObject->isInUse())
{
+ programObject->resolveLink();
if (programObject->isLinked())
{
mGLState.onProgramExecutableChange(programObject);
@@ -5902,7 +5905,7 @@
void Context::validateProgram(GLuint program)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->validate(mCaps);
}
@@ -5918,7 +5921,7 @@
GLenum *binaryFormat,
void *binary)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject != nullptr);
handleError(programObject->saveBinary(this, binaryFormat, binary, bufSize, length));
@@ -5926,7 +5929,7 @@
void Context::programBinary(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject != nullptr);
handleError(programObject->loadBinary(this, binaryFormat, binary, length));
@@ -6130,7 +6133,7 @@
const GLchar *const *varyings,
GLenum bufferMode)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setTransformFeedbackVaryings(count, varyings, bufferMode);
}
@@ -6143,7 +6146,7 @@
GLenum *type,
GLchar *name)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name);
}
@@ -6209,7 +6212,7 @@
void Context::getUniformuiv(GLuint program, GLint location, GLuint *params)
{
- const Program *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
programObject->getUniformuiv(this, location, params);
}
@@ -6224,7 +6227,7 @@
GLint Context::getFragDataLocation(GLuint program, const GLchar *name)
{
- const Program *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
return programObject->getFragDataLocation(name);
}
@@ -6233,7 +6236,7 @@
const GLchar *const *uniformNames,
GLuint *uniformIndices)
{
- const Program *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
if (!programObject->isLinked())
{
for (int uniformId = 0; uniformId < uniformCount; uniformId++)
@@ -6256,7 +6259,7 @@
GLenum pname,
GLint *params)
{
- const Program *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
for (int uniformId = 0; uniformId < uniformCount; uniformId++)
{
const GLuint index = uniformIndices[uniformId];
@@ -6266,7 +6269,7 @@
GLuint Context::getUniformBlockIndex(GLuint program, const GLchar *uniformBlockName)
{
- const Program *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
return programObject->getUniformBlockIndex(uniformBlockName);
}
@@ -6275,7 +6278,7 @@
GLenum pname,
GLint *params)
{
- const Program *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
}
@@ -6295,7 +6298,7 @@
GLsizei *length,
GLchar *uniformBlockName)
{
- const Program *programObject = getProgram(program);
+ const Program *programObject = getProgramResolveLink(program);
programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
}
@@ -6303,7 +6306,7 @@
GLuint uniformBlockIndex,
GLuint uniformBlockBinding)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding);
if (programObject->isInUse())
@@ -6515,84 +6518,84 @@
void Context::programUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
setUniform1iImpl(programObject, location, count, value);
}
void Context::programUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform2iv(location, count, value);
}
void Context::programUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform3iv(location, count, value);
}
void Context::programUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform4iv(location, count, value);
}
void Context::programUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform1uiv(location, count, value);
}
void Context::programUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform2uiv(location, count, value);
}
void Context::programUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform3uiv(location, count, value);
}
void Context::programUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform4uiv(location, count, value);
}
void Context::programUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform1fv(location, count, value);
}
void Context::programUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform2fv(location, count, value);
}
void Context::programUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform3fv(location, count, value);
}
void Context::programUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniform4fv(location, count, value);
}
@@ -6603,7 +6606,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix2fv(location, count, transpose, value);
}
@@ -6614,7 +6617,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix3fv(location, count, transpose, value);
}
@@ -6625,7 +6628,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix4fv(location, count, transpose, value);
}
@@ -6636,7 +6639,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix2x3fv(location, count, transpose, value);
}
@@ -6647,7 +6650,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix3x2fv(location, count, transpose, value);
}
@@ -6658,7 +6661,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix2x4fv(location, count, transpose, value);
}
@@ -6669,7 +6672,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix4x2fv(location, count, transpose, value);
}
@@ -6680,7 +6683,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix3x4fv(location, count, transpose, value);
}
@@ -6691,7 +6694,7 @@
GLboolean transpose,
const GLfloat *value)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->setUniformMatrix4x3fv(location, count, transpose, value);
}
@@ -6791,7 +6794,7 @@
void Context::getnUniformfv(GLuint program, GLint location, GLsizei bufSize, GLfloat *params)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getUniformfv(this, location, params);
@@ -6808,7 +6811,7 @@
void Context::getnUniformiv(GLuint program, GLint location, GLsizei bufSize, GLint *params)
{
- Program *programObject = getProgram(program);
+ Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->getUniformiv(this, location, params);
@@ -7690,7 +7693,17 @@
return false;
}
-Program *Context::getProgram(GLuint handle) const
+Program *Context::getProgramResolveLink(GLuint handle) const
+{
+ Program *program = mState.mShaderPrograms->getProgram(handle);
+ if (program)
+ {
+ program->resolveLink();
+ }
+ return program;
+}
+
+Program *Context::getProgramNoResolveLink(GLuint handle) const
{
return mState.mShaderPrograms->getProgram(handle);
}