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>
This commit is contained in:
Jamie Madill 2018-10-02 13:38:56 -04:00 коммит произвёл Commit Bot
Родитель df836ff8f1
Коммит 44a6fbfd95
11 изменённых файлов: 296 добавлений и 243 удалений

Просмотреть файл

@ -1024,7 +1024,7 @@ gl::LabeledObject *Context::getLabeledObject(GLenum identifier, GLuint name) con
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::bindImageTexture(GLuint unit,
void Context::useProgram(GLuint program)
{
mGLState.setProgram(this, getProgram(program));
mGLState.setProgram(this, getProgramResolveLink(program));
mStateCache.onProgramExecutableChange(this);
}
@ -2340,7 +2340,7 @@ void Context::popGroupMarker()
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::stencilThenCoverStrokePathInstanced(GLsizei numPaths,
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 @@ void Context::programPathFragmentInputGen(GLuint program,
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 @@ void Context::getProgramResourceName(GLuint program,
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 @@ GLint Context::getProgramResourceLocation(GLuint program,
GLenum programInterface,
const GLchar *name)
{
const auto *programObject = getProgram(program);
const Program *programObject = getProgramResolveLink(program);
return QueryProgramResourceLocation(programObject, programInterface, name);
}
@ -2588,7 +2588,7 @@ void Context::getProgramResourceiv(GLuint program,
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 @@ void Context::getProgramInterfaceiv(GLuint program,
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::getSamplerParameterfvRobust(GLuint sampler,
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::copyBufferSubData(BufferBinding readTarget,
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::deleteTextures(GLsizei n, const GLuint *textures)
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 @@ void Context::getActiveAttrib(GLuint program,
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 @@ void Context::getActiveUniform(GLuint program,
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::getIntegervRobust(GLenum pname, GLsizei bufSize, GLsizei *length,
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::getProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params)
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::getShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, G
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::getUniformfvRobust(GLuint program,
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 @@ void Context::getUniformivRobust(GLuint program,
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 @@ GLboolean Context::isProgram(GLuint program)
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 @@ GLboolean Context::isTexture(GLuint texture)
void Context::linkProgram(GLuint program)
{
Program *programObject = getProgram(program);
Program *programObject = getProgramNoResolveLink(program);
ASSERT(programObject);
handleError(programObject->link(this));
@ -5715,6 +5717,7 @@ void Context::linkProgram(GLuint program)
// ProgramD3D.
if (programObject->isInUse())
{
programObject->resolveLink();
if (programObject->isLinked())
{
mGLState.onProgramExecutableChange(programObject);
@ -5902,7 +5905,7 @@ void Context::uniformMatrix4fv(GLint location,
void Context::validateProgram(GLuint program)
{
Program *programObject = getProgram(program);
Program *programObject = getProgramResolveLink(program);
ASSERT(programObject);
programObject->validate(mCaps);
}
@ -5918,7 +5921,7 @@ void Context::getProgramBinary(GLuint program,
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::getProgramBinary(GLuint program,
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 @@ void Context::transformFeedbackVaryings(GLuint program,
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 @@ void Context::getTransformFeedbackVarying(GLuint program,
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::resumeTransformFeedback()
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 @@ void Context::getUniformuivRobust(GLuint program,
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 @@ void Context::getUniformIndices(GLuint program,
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 @@ void Context::getActiveUniformsiv(GLuint program,
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 @@ void Context::getActiveUniformsiv(GLuint program,
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 @@ void Context::getActiveUniformBlockiv(GLuint program,
GLenum pname,
GLint *params)
{
const Program *programObject = getProgram(program);
const Program *programObject = getProgramResolveLink(program);
QueryActiveUniformBlockiv(programObject, uniformBlockIndex, pname, params);
}
@ -6295,7 +6298,7 @@ void Context::getActiveUniformBlockName(GLuint program,
GLsizei *length,
GLchar *uniformBlockName)
{
const Program *programObject = getProgram(program);
const Program *programObject = getProgramResolveLink(program);
programObject->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName);
}
@ -6303,7 +6306,7 @@ void Context::uniformBlockBinding(GLuint program,
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::programUniform4f(GLuint program,
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 @@ void Context::programUniformMatrix2fv(GLuint program,
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 @@ void Context::programUniformMatrix3fv(GLuint program,
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 @@ void Context::programUniformMatrix4fv(GLuint program,
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 @@ void Context::programUniformMatrix2x3fv(GLuint program,
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 @@ void Context::programUniformMatrix3x2fv(GLuint program,
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 @@ void Context::programUniformMatrix2x4fv(GLuint program,
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 @@ void Context::programUniformMatrix4x2fv(GLuint program,
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 @@ void Context::programUniformMatrix3x4fv(GLuint program,
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 @@ void Context::programUniformMatrix4x3fv(GLuint program,
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::getTranslatedShaderSource(GLuint shader,
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::getnUniformfvRobust(GLuint program,
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 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
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);
}

Просмотреть файл

@ -1585,7 +1585,8 @@ class Context final : public egl::LabeledObject, angle::NonCopyable, public angl
bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams);
bool getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned int *numParams);
Program *getProgram(GLuint handle) const;
Program *getProgramResolveLink(GLuint handle) const;
Program *getProgramNoResolveLink(GLuint handle) const;
Shader *getShader(GLuint handle) const;
bool isTextureGenerated(GLuint texture) const;

Просмотреть файл

@ -1859,7 +1859,7 @@ FramebufferAttachment *Framebuffer::getAttachmentFromSubjectIndex(angle::Subject
bool Framebuffer::formsRenderingFeedbackLoopWith(const State &state) const
{
const Program *program = state.getProgram();
const Program *program = state.getLinkedProgram();
// TODO(jmadill): Default framebuffer feedback loops.
if (mState.mId == 0)

Просмотреть файл

@ -538,6 +538,7 @@ Error GLES1Renderer::linkProgram(Context *context,
}
ANGLE_TRY(programObject->link(context));
programObject->resolveLink();
glState->onProgramExecutableChange(programObject);

Просмотреть файл

@ -920,7 +920,7 @@ Program::~Program()
void Program::onDestroy(const Context *context)
{
resolveLink();
ASSERT(mLinkResolved);
for (ShaderType shaderType : AllShaderTypes())
{
if (mState.mAttachedShaders[shaderType])
@ -940,30 +940,30 @@ void Program::onDestroy(const Context *context)
}
GLuint Program::id() const
{
resolveLink();
ASSERT(mLinkResolved);
return mHandle;
}
void Program::setLabel(const std::string &label)
{
resolveLink();
ASSERT(mLinkResolved);
mState.mLabel = label;
}
const std::string &Program::getLabel() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mLabel;
}
rx::ProgramImpl *Program::getImplementation() const
{
resolveLink();
ASSERT(mLinkResolved);
return mProgram;
}
void Program::attachShader(Shader *shader)
{
resolveLink();
ASSERT(mLinkResolved);
ShaderType shaderType = shader->getType();
ASSERT(shaderType != ShaderType::InvalidEnum);
@ -973,7 +973,7 @@ void Program::attachShader(Shader *shader)
void Program::detachShader(const Context *context, Shader *shader)
{
resolveLink();
ASSERT(mLinkResolved);
ShaderType shaderType = shader->getType();
ASSERT(shaderType != ShaderType::InvalidEnum);
@ -984,7 +984,7 @@ void Program::detachShader(const Context *context, Shader *shader)
int Program::getAttachedShadersCount() const
{
resolveLink();
ASSERT(mLinkResolved);
int numAttachedShaders = 0;
for (const Shader *shader : mState.mAttachedShaders)
{
@ -999,31 +999,31 @@ int Program::getAttachedShadersCount() const
const Shader *Program::getAttachedShader(ShaderType shaderType) const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.getAttachedShader(shaderType);
}
void Program::bindAttributeLocation(GLuint index, const char *name)
{
resolveLink();
ASSERT(mLinkResolved);
mAttributeBindings.bindLocation(index, name);
}
void Program::bindUniformLocation(GLuint index, const char *name)
{
resolveLink();
ASSERT(mLinkResolved);
mUniformLocationBindings.bindLocation(index, name);
}
void Program::bindFragmentInputLocation(GLint index, const char *name)
{
resolveLink();
ASSERT(mLinkResolved);
mFragmentInputBindings.bindLocation(index, name);
}
BindingInfo Program::getFragmentInputBindingInfo(GLint index) const
{
resolveLink();
ASSERT(mLinkResolved);
BindingInfo ret;
ret.type = GL_NONE;
ret.valid = false;
@ -1079,7 +1079,7 @@ void Program::pathFragmentInputGen(GLint index,
GLint components,
const GLfloat *coeffs)
{
resolveLink();
ASSERT(mLinkResolved);
// If the location is -1 then the command is silently ignored
if (index == -1)
return;
@ -1277,12 +1277,6 @@ bool Program::isLinking() const
return (mLinkingState.get() && mLinkingState->linkEvent->isLinking());
}
bool Program::isLinked() const
{
resolveLink();
return mLinked;
}
void Program::resolveLinkImpl()
{
ASSERT(mLinkingState.get());
@ -1429,7 +1423,7 @@ Error Program::loadBinary(const Context *context,
const void *binary,
GLsizei length)
{
resolveLink();
ASSERT(mLinkResolved);
unlink();
#if ANGLE_PROGRAM_BINARY_LOAD != ANGLE_ENABLED
@ -1465,7 +1459,7 @@ Error Program::saveBinary(const Context *context,
GLsizei bufSize,
GLsizei *length) const
{
resolveLink();
ASSERT(mLinkResolved);
if (binaryFormat)
{
*binaryFormat = GL_PROGRAM_BINARY_ANGLE;
@ -1510,7 +1504,7 @@ Error Program::saveBinary(const Context *context,
GLint Program::getBinaryLength(const Context *context) const
{
resolveLink();
ASSERT(mLinkResolved);
if (!mLinked)
{
return 0;
@ -1528,7 +1522,7 @@ GLint Program::getBinaryLength(const Context *context) const
void Program::setBinaryRetrievableHint(bool retrievable)
{
resolveLink();
ASSERT(mLinkResolved);
// TODO(jmadill) : replace with dirty bits
mProgram->setBinaryRetrievableHint(retrievable);
mState.mBinaryRetrieveableHint = retrievable;
@ -1536,13 +1530,13 @@ void Program::setBinaryRetrievableHint(bool retrievable)
bool Program::getBinaryRetrievableHint() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mBinaryRetrieveableHint;
}
void Program::setSeparable(bool separable)
{
resolveLink();
ASSERT(mLinkResolved);
// TODO(yunchao) : replace with dirty bits
if (mState.mSeparable != separable)
{
@ -1553,13 +1547,13 @@ void Program::setSeparable(bool separable)
bool Program::isSeparable() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mSeparable;
}
void Program::release(const Context *context)
{
resolveLink();
ASSERT(mLinkResolved);
mRefCount--;
if (mRefCount == 0 && mDeleteStatus)
@ -1570,7 +1564,7 @@ void Program::release(const Context *context)
void Program::addRef()
{
resolveLink();
ASSERT(mLinkResolved);
mRefCount++;
}
@ -1581,19 +1575,19 @@ unsigned int Program::getRefCount() const
int Program::getInfoLogLength() const
{
resolveLink();
ASSERT(mLinkResolved);
return static_cast<int>(mInfoLog.getLength());
}
void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
{
resolveLink();
ASSERT(mLinkResolved);
return mInfoLog.getLog(bufSize, length, infoLog);
}
void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders) const
{
resolveLink();
ASSERT(mLinkResolved);
int total = 0;
for (const Shader *shader : mState.mAttachedShaders)
@ -1613,13 +1607,13 @@ void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shade
GLuint Program::getAttributeLocation(const std::string &name) const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.getAttributeLocation(name);
}
bool Program::isAttribLocationActive(size_t attribLocation) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(attribLocation < mState.mActiveAttribLocationsMask.size());
return mState.mActiveAttribLocationsMask[attribLocation];
}
@ -1631,7 +1625,7 @@ void Program::getActiveAttribute(GLuint index,
GLenum *type,
GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
if (!mLinked)
{
if (bufsize > 0)
@ -1664,7 +1658,7 @@ void Program::getActiveAttribute(GLuint index,
GLint Program::getActiveAttributeCount() const
{
resolveLink();
ASSERT(mLinkResolved);
if (!mLinked)
{
return 0;
@ -1675,7 +1669,7 @@ GLint Program::getActiveAttributeCount() const
GLint Program::getActiveAttributeMaxLength() const
{
resolveLink();
ASSERT(mLinkResolved);
if (!mLinked)
{
return 0;
@ -1693,69 +1687,69 @@ GLint Program::getActiveAttributeMaxLength() const
const std::vector<sh::Attribute> &Program::getAttributes() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mAttributes;
}
const std::vector<SamplerBinding> &Program::getSamplerBindings() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mSamplerBindings;
}
const sh::WorkGroupSize &Program::getComputeShaderLocalSize() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mComputeShaderLocalSize;
}
PrimitiveMode Program::getGeometryShaderInputPrimitiveType() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mGeometryShaderInputPrimitiveType;
}
PrimitiveMode Program::getGeometryShaderOutputPrimitiveType() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mGeometryShaderOutputPrimitiveType;
}
GLint Program::getGeometryShaderInvocations() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mGeometryShaderInvocations;
}
GLint Program::getGeometryShaderMaxVertices() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mGeometryShaderMaxVertices;
}
GLuint Program::getInputResourceIndex(const GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
return GetResourceIndexFromName(mState.mAttributes, std::string(name));
}
GLuint Program::getOutputResourceIndex(const GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
return GetResourceIndexFromName(mState.mOutputVariables, std::string(name));
}
size_t Program::getOutputResourceCount() const
{
resolveLink();
ASSERT(mLinkResolved);
return (mLinked ? mState.mOutputVariables.size() : 0);
}
const std::vector<GLenum> &Program::getOutputVariableTypes() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mOutputVariableTypes;
}
DrawBufferMask Program::getActiveOutputVariables() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mActiveOutputVariables;
}
@ -1793,7 +1787,7 @@ void Program::getInputResourceName(GLuint index,
GLsizei *length,
GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
getResourceName(index, mState.mAttributes, bufSize, length, name);
}
@ -1802,7 +1796,7 @@ void Program::getOutputResourceName(GLuint index,
GLsizei *length,
GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
getResourceName(index, mState.mOutputVariables, bufSize, length, name);
}
@ -1811,7 +1805,7 @@ void Program::getUniformResourceName(GLuint index,
GLsizei *length,
GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
getResourceName(index, mState.mUniforms, bufSize, length, name);
}
@ -1820,71 +1814,71 @@ void Program::getBufferVariableResourceName(GLuint index,
GLsizei *length,
GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
getResourceName(index, mState.mBufferVariables, bufSize, length, name);
}
const sh::Attribute &Program::getInputResource(GLuint index) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(index < mState.mAttributes.size());
return mState.mAttributes[index];
}
const sh::OutputVariable &Program::getOutputResource(GLuint index) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(index < mState.mOutputVariables.size());
return mState.mOutputVariables[index];
}
const ProgramBindings &Program::getAttributeBindings() const
{
resolveLink();
ASSERT(mLinkResolved);
return mAttributeBindings;
}
const ProgramBindings &Program::getUniformLocationBindings() const
{
resolveLink();
ASSERT(mLinkResolved);
return mUniformLocationBindings;
}
const ProgramBindings &Program::getFragmentInputBindings() const
{
resolveLink();
ASSERT(mLinkResolved);
return mFragmentInputBindings;
}
int Program::getNumViews() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.getNumViews();
}
ComponentTypeMask Program::getDrawBufferTypeMask() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mDrawBufferTypeMask;
}
ComponentTypeMask Program::getAttributesTypeMask() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mAttributesTypeMask;
}
AttributesMask Program::getAttributesMask() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mAttributesMask;
}
const std::vector<GLsizei> &Program::getTransformFeedbackStrides() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mTransformFeedbackStrides;
}
GLint Program::getFragDataLocation(const std::string &name) const
{
resolveLink();
ASSERT(mLinkResolved);
return GetVariableLocation(mState.mOutputVariables, mState.mOutputLocations, name);
}
@ -1895,7 +1889,7 @@ void Program::getActiveUniform(GLuint index,
GLenum *type,
GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
if (mLinked)
{
// index must be smaller than getActiveUniformCount()
@ -1930,7 +1924,7 @@ void Program::getActiveUniform(GLuint index,
GLint Program::getActiveUniformCount() const
{
resolveLink();
ASSERT(mLinkResolved);
if (mLinked)
{
return static_cast<GLint>(mState.mUniforms.size());
@ -1943,13 +1937,13 @@ GLint Program::getActiveUniformCount() const
size_t Program::getActiveBufferVariableCount() const
{
resolveLink();
ASSERT(mLinkResolved);
return mLinked ? mState.mBufferVariables.size() : 0;
}
GLint Program::getActiveUniformMaxLength() const
{
resolveLink();
ASSERT(mLinkResolved);
size_t maxLength = 0;
if (mLinked)
@ -1973,7 +1967,7 @@ GLint Program::getActiveUniformMaxLength() const
bool Program::isValidUniformLocation(GLint location) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(angle::IsValueInRangeForNumericType<GLint>(mState.mUniformLocations.size()));
return (location >= 0 && static_cast<size_t>(location) < mState.mUniformLocations.size() &&
mState.mUniformLocations[static_cast<size_t>(location)].used());
@ -1981,52 +1975,40 @@ bool Program::isValidUniformLocation(GLint location) const
const LinkedUniform &Program::getUniformByLocation(GLint location) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(location >= 0 && static_cast<size_t>(location) < mState.mUniformLocations.size());
return mState.mUniforms[mState.getUniformIndexFromLocation(location)];
}
const VariableLocation &Program::getUniformLocation(GLint location) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(location >= 0 && static_cast<size_t>(location) < mState.mUniformLocations.size());
return mState.mUniformLocations[location];
}
const std::vector<VariableLocation> &Program::getUniformLocations() const
{
resolveLink();
return mState.mUniformLocations;
}
const LinkedUniform &Program::getUniformByIndex(GLuint index) const
{
resolveLink();
ASSERT(index < static_cast<size_t>(mState.mUniforms.size()));
return mState.mUniforms[index];
}
const BufferVariable &Program::getBufferVariableByIndex(GLuint index) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(index < static_cast<size_t>(mState.mBufferVariables.size()));
return mState.mBufferVariables[index];
}
GLint Program::getUniformLocation(const std::string &name) const
{
resolveLink();
ASSERT(mLinkResolved);
return GetVariableLocation(mState.mUniforms, mState.mUniformLocations, name);
}
GLuint Program::getUniformIndex(const std::string &name) const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.getUniformIndexFromName(name);
}
void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v);
mProgram->setUniform1fv(location, clampedCount, v);
@ -2034,7 +2016,7 @@ void Program::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
void Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v);
mProgram->setUniform2fv(location, clampedCount, v);
@ -2042,7 +2024,7 @@ void Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
void Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v);
mProgram->setUniform3fv(location, clampedCount, v);
@ -2050,7 +2032,7 @@ void Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v);
mProgram->setUniform4fv(location, clampedCount, v);
@ -2058,7 +2040,7 @@ void Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
Program::SetUniformResult Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v);
@ -2075,7 +2057,7 @@ Program::SetUniformResult Program::setUniform1iv(GLint location, GLsizei count,
void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v);
mProgram->setUniform2iv(location, clampedCount, v);
@ -2083,7 +2065,7 @@ void Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
void Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v);
mProgram->setUniform3iv(location, clampedCount, v);
@ -2091,7 +2073,7 @@ void Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
void Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v);
mProgram->setUniform4iv(location, clampedCount, v);
@ -2099,7 +2081,7 @@ void Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
void Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 1, v);
mProgram->setUniform1uiv(location, clampedCount, v);
@ -2107,7 +2089,7 @@ void Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
void Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 2, v);
mProgram->setUniform2uiv(location, clampedCount, v);
@ -2115,7 +2097,7 @@ void Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
void Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 3, v);
mProgram->setUniform3uiv(location, clampedCount, v);
@ -2123,7 +2105,7 @@ void Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
void Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &locationInfo = mState.mUniformLocations[location];
GLsizei clampedCount = clampUniformCount(locationInfo, count, 4, v);
mProgram->setUniform4uiv(location, clampedCount, v);
@ -2134,7 +2116,7 @@ void Program::setUniformMatrix2fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<2, 2>(location, count, transpose, v);
mProgram->setUniformMatrix2fv(location, clampedCount, transpose, v);
}
@ -2144,7 +2126,7 @@ void Program::setUniformMatrix3fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<3, 3>(location, count, transpose, v);
mProgram->setUniformMatrix3fv(location, clampedCount, transpose, v);
}
@ -2154,7 +2136,7 @@ void Program::setUniformMatrix4fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<4, 4>(location, count, transpose, v);
mProgram->setUniformMatrix4fv(location, clampedCount, transpose, v);
}
@ -2164,7 +2146,7 @@ void Program::setUniformMatrix2x3fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<2, 3>(location, count, transpose, v);
mProgram->setUniformMatrix2x3fv(location, clampedCount, transpose, v);
}
@ -2174,7 +2156,7 @@ void Program::setUniformMatrix2x4fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<2, 4>(location, count, transpose, v);
mProgram->setUniformMatrix2x4fv(location, clampedCount, transpose, v);
}
@ -2184,7 +2166,7 @@ void Program::setUniformMatrix3x2fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<3, 2>(location, count, transpose, v);
mProgram->setUniformMatrix3x2fv(location, clampedCount, transpose, v);
}
@ -2194,7 +2176,7 @@ void Program::setUniformMatrix3x4fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<3, 4>(location, count, transpose, v);
mProgram->setUniformMatrix3x4fv(location, clampedCount, transpose, v);
}
@ -2204,7 +2186,7 @@ void Program::setUniformMatrix4x2fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<4, 2>(location, count, transpose, v);
mProgram->setUniformMatrix4x2fv(location, clampedCount, transpose, v);
}
@ -2214,14 +2196,14 @@ void Program::setUniformMatrix4x3fv(GLint location,
GLboolean transpose,
const GLfloat *v)
{
resolveLink();
ASSERT(mLinkResolved);
GLsizei clampedCount = clampMatrixUniformCount<4, 3>(location, count, transpose, v);
mProgram->setUniformMatrix4x3fv(location, clampedCount, transpose, v);
}
GLuint Program::getSamplerUniformBinding(const VariableLocation &uniformLocation) const
{
resolveLink();
ASSERT(mLinkResolved);
GLuint samplerIndex = mState.getSamplerIndexFromUniformIndex(uniformLocation.index);
const std::vector<GLuint> &boundTextureUnits =
mState.mSamplerBindings[samplerIndex].boundTextureUnits;
@ -2230,7 +2212,7 @@ GLuint Program::getSamplerUniformBinding(const VariableLocation &uniformLocation
void Program::getUniformfv(const Context *context, GLint location, GLfloat *v) const
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &uniformLocation = mState.getUniformLocations()[location];
const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index];
@ -2253,7 +2235,7 @@ void Program::getUniformfv(const Context *context, GLint location, GLfloat *v) c
void Program::getUniformiv(const Context *context, GLint location, GLint *v) const
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &uniformLocation = mState.getUniformLocations()[location];
const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index];
@ -2276,7 +2258,7 @@ void Program::getUniformiv(const Context *context, GLint location, GLint *v) con
void Program::getUniformuiv(const Context *context, GLint location, GLuint *v) const
{
resolveLink();
ASSERT(mLinkResolved);
const VariableLocation &uniformLocation = mState.getUniformLocations()[location];
const LinkedUniform &uniform = mState.getUniforms()[uniformLocation.index];
@ -2299,19 +2281,19 @@ void Program::getUniformuiv(const Context *context, GLint location, GLuint *v) c
void Program::flagForDeletion()
{
resolveLink();
ASSERT(mLinkResolved);
mDeleteStatus = true;
}
bool Program::isFlaggedForDeletion() const
{
resolveLink();
ASSERT(mLinkResolved);
return mDeleteStatus;
}
void Program::validate(const Caps &caps)
{
resolveLink();
ASSERT(mLinkResolved);
mInfoLog.reset();
if (mLinked)
@ -2326,7 +2308,7 @@ void Program::validate(const Caps &caps)
bool Program::validateSamplersImpl(InfoLog *infoLog, const Caps &caps)
{
resolveLink();
ASSERT(mLinkResolved);
// if any two active samplers in a program are of different types, but refer to the same
// texture image unit, and this is the current program, then ValidateProgram will fail, and
@ -2353,19 +2335,19 @@ bool Program::validateSamplersImpl(InfoLog *infoLog, const Caps &caps)
bool Program::isValidated() const
{
resolveLink();
ASSERT(mLinkResolved);
return mValidated;
}
GLuint Program::getActiveAtomicCounterBufferCount() const
{
resolveLink();
ASSERT(mLinkResolved);
return static_cast<GLuint>(mState.mAtomicCounterBuffers.size());
}
GLuint Program::getActiveShaderStorageBlockCount() const
{
resolveLink();
ASSERT(mLinkResolved);
return static_cast<GLuint>(mState.mShaderStorageBlocks.size());
}
@ -2374,7 +2356,7 @@ void Program::getActiveUniformBlockName(const GLuint blockIndex,
GLsizei *length,
GLchar *blockName) const
{
resolveLink();
ASSERT(mLinkResolved);
GetInterfaceBlockName(blockIndex, mState.mUniformBlocks, bufSize, length, blockName);
}
@ -2383,7 +2365,7 @@ void Program::getActiveShaderStorageBlockName(const GLuint blockIndex,
GLsizei *length,
GLchar *blockName) const
{
resolveLink();
ASSERT(mLinkResolved);
GetInterfaceBlockName(blockIndex, mState.mShaderStorageBlocks, bufSize, length, blockName);
}
@ -2409,45 +2391,45 @@ GLint Program::getActiveInterfaceBlockMaxNameLength(const std::vector<T> &resour
GLint Program::getActiveUniformBlockMaxNameLength() const
{
resolveLink();
ASSERT(mLinkResolved);
return getActiveInterfaceBlockMaxNameLength(mState.mUniformBlocks);
}
GLint Program::getActiveShaderStorageBlockMaxNameLength() const
{
resolveLink();
ASSERT(mLinkResolved);
return getActiveInterfaceBlockMaxNameLength(mState.mShaderStorageBlocks);
}
GLuint Program::getUniformBlockIndex(const std::string &name) const
{
resolveLink();
ASSERT(mLinkResolved);
return GetInterfaceBlockIndex(mState.mUniformBlocks, name);
}
GLuint Program::getShaderStorageBlockIndex(const std::string &name) const
{
resolveLink();
ASSERT(mLinkResolved);
return GetInterfaceBlockIndex(mState.mShaderStorageBlocks, name);
}
const InterfaceBlock &Program::getUniformBlockByIndex(GLuint index) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(index < static_cast<GLuint>(mState.mUniformBlocks.size()));
return mState.mUniformBlocks[index];
}
const InterfaceBlock &Program::getShaderStorageBlockByIndex(GLuint index) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(index < static_cast<GLuint>(mState.mShaderStorageBlocks.size()));
return mState.mShaderStorageBlocks[index];
}
void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
resolveLink();
ASSERT(mLinkResolved);
mState.mUniformBlocks[uniformBlockIndex].binding = uniformBlockBinding;
mState.mActiveUniformBlockBindings.set(uniformBlockIndex, uniformBlockBinding != 0);
mDirtyBits.set(DIRTY_BIT_UNIFORM_BLOCK_BINDING_0 + uniformBlockIndex);
@ -2455,13 +2437,13 @@ void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBind
GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.getUniformBlockBinding(uniformBlockIndex);
}
GLuint Program::getShaderStorageBlockBinding(GLuint shaderStorageBlockIndex) const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.getShaderStorageBlockBinding(shaderStorageBlockIndex);
}
@ -2469,7 +2451,7 @@ void Program::setTransformFeedbackVaryings(GLsizei count,
const GLchar *const *varyings,
GLenum bufferMode)
{
resolveLink();
ASSERT(mLinkResolved);
mState.mTransformFeedbackVaryingNames.resize(count);
for (GLsizei i = 0; i < count; i++)
{
@ -2486,7 +2468,7 @@ void Program::getTransformFeedbackVarying(GLuint index,
GLenum *type,
GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
if (mLinked)
{
ASSERT(index < mState.mLinkedTransformFeedbackVaryings.size());
@ -2515,7 +2497,7 @@ void Program::getTransformFeedbackVarying(GLuint index,
GLsizei Program::getTransformFeedbackVaryingCount() const
{
resolveLink();
ASSERT(mLinkResolved);
if (mLinked)
{
return static_cast<GLsizei>(mState.mLinkedTransformFeedbackVaryings.size());
@ -2528,7 +2510,7 @@ GLsizei Program::getTransformFeedbackVaryingCount() const
GLsizei Program::getTransformFeedbackVaryingMaxLength() const
{
resolveLink();
ASSERT(mLinkResolved);
if (mLinked)
{
GLsizei maxSize = 0;
@ -2548,7 +2530,7 @@ GLsizei Program::getTransformFeedbackVaryingMaxLength() const
GLenum Program::getTransformFeedbackBufferMode() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mTransformFeedbackBufferMode;
}
@ -2673,7 +2655,7 @@ bool Program::linkValidateShaders(InfoLog &infoLog)
GLuint Program::getTransformFeedbackVaryingResourceIndex(const GLchar *name) const
{
resolveLink();
ASSERT(mLinkResolved);
for (GLuint tfIndex = 0; tfIndex < mState.mLinkedTransformFeedbackVaryings.size(); ++tfIndex)
{
const auto &tf = mState.mLinkedTransformFeedbackVaryings[tfIndex];
@ -2687,7 +2669,7 @@ GLuint Program::getTransformFeedbackVaryingResourceIndex(const GLchar *name) con
const TransformFeedbackVarying &Program::getTransformFeedbackVaryingResource(GLuint index) const
{
resolveLink();
ASSERT(mLinkResolved);
ASSERT(index < mState.mLinkedTransformFeedbackVaryings.size());
return mState.mLinkedTransformFeedbackVaryings[index];
}
@ -3913,7 +3895,7 @@ void Program::getUniformInternal(const Context *context,
bool Program::samplesFromTexture(const gl::State &state, GLuint textureID) const
{
resolveLink();
ASSERT(mLinkResolved);
// Must be called after samplers are validated.
ASSERT(mCachedValidateSamplersResult.valid() && mCachedValidateSamplersResult.value());
@ -3938,7 +3920,7 @@ Error Program::syncState(const Context *context)
{
if (mDirtyBits.any())
{
resolveLink();
ASSERT(mLinkResolved);
ANGLE_TRY(mProgram->syncState(context, mDirtyBits));
mDirtyBits.reset();
}

Просмотреть файл

@ -512,7 +512,11 @@ class Program final : angle::NonCopyable, public LabeledObject
// Peek whether there is any running linking tasks.
bool isLinking() const;
bool isLinked() const;
bool isLinked() const
{
ASSERT(mLinkResolved);
return mLinked;
}
bool hasLinkedShaderStage(ShaderType shaderType) const
{
@ -570,8 +574,19 @@ class Program final : angle::NonCopyable, public LabeledObject
bool isValidUniformLocation(GLint location) const;
const LinkedUniform &getUniformByLocation(GLint location) const;
const VariableLocation &getUniformLocation(GLint location) const;
const std::vector<VariableLocation> &getUniformLocations() const;
const LinkedUniform &getUniformByIndex(GLuint index) const;
const std::vector<VariableLocation> &getUniformLocations() const
{
ASSERT(mLinkResolved);
return mState.mUniformLocations;
}
const LinkedUniform &getUniformByIndex(GLuint index) const
{
ASSERT(mLinkResolved);
ASSERT(index < static_cast<size_t>(mState.mUniforms.size()));
return mState.mUniforms[index];
}
const BufferVariable &getBufferVariableByIndex(GLuint index) const;
@ -704,14 +719,14 @@ class Program final : angle::NonCopyable, public LabeledObject
const AttributesMask &getActiveAttribLocationsMask() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mActiveAttribLocationsMask;
}
const std::vector<SamplerBinding> &getSamplerBindings() const;
const std::vector<ImageBinding> &getImageBindings() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState.mImageBindings;
}
const sh::WorkGroupSize &getComputeShaderLocalSize() const;
@ -722,7 +737,7 @@ class Program final : angle::NonCopyable, public LabeledObject
const ProgramState &getState() const
{
resolveLink();
ASSERT(mLinkResolved);
return mState;
}
@ -780,6 +795,15 @@ class Program final : angle::NonCopyable, public LabeledObject
Error syncState(const Context *context);
// Try to resolve linking. Inlined to make sure its overhead is as low as possible.
void resolveLink()
{
if (!mLinkResolved)
{
resolveLinkImpl();
}
}
private:
struct LinkingState;
@ -873,16 +897,7 @@ class Program final : angle::NonCopyable, public LabeledObject
GLuint getSamplerUniformBinding(const VariableLocation &uniformLocation) const;
bool validateSamplersImpl(InfoLog *infoLog, const Caps &caps);
// Try to resolve linking.
// Note: this method is frequently called in each draw call. Please make sure its overhead
// is as low as possible.
void resolveLink() const
{
if (!mLinkResolved)
{
return const_cast<Program *>(this)->resolveLinkImpl();
}
}
// Block until linking is finished and resolve it.
void resolveLinkImpl();

Просмотреть файл

@ -227,7 +227,21 @@ class State : angle::NonCopyable
// Program binding manipulation
void setProgram(const Context *context, Program *newProgram);
Program *getProgram() const { return mProgram; }
Program *getProgram() const
{
ASSERT(!mProgram || !mProgram->isLinking());
return mProgram;
}
Program *getLinkedProgram() const
{
if (mProgram)
{
mProgram->resolveLink();
}
return mProgram;
}
// Transform feedback object (not buffer) binding manipulation
void setTransformFeedbackBinding(const Context *context, TransformFeedback *transformFeedback);

Просмотреть файл

@ -385,7 +385,7 @@ bool ValidateTextureMaxAnisotropyValue(Context *context, GLfloat paramValue)
bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
{
const Program *program = context->getGLState().getProgram();
const Program *program = context->getGLState().getLinkedProgram();
const Framebuffer *framebuffer = context->getGLState().getDrawFramebuffer();
return ComponentTypeMask::Validate(program->getDrawBufferTypeMask().to_ulong(),
@ -397,7 +397,7 @@ bool ValidateFragmentShaderColorBufferTypeMatch(Context *context)
bool ValidateVertexShaderAttributeTypeMatch(Context *context)
{
const auto &glState = context->getGLState();
const Program *program = context->getGLState().getProgram();
const Program *program = context->getGLState().getLinkedProgram();
const VertexArray *vao = context->getGLState().getVertexArray();
unsigned long stateCurrentValuesTypeBits = glState.getCurrentValuesTypeMask().to_ulong();
@ -655,7 +655,7 @@ bool ValidateDrawInstancedANGLE(Context *context)
// Verify there is at least one active attribute with a divisor of zero
const State &state = context->getGLState();
Program *program = state.getProgram();
Program *program = state.getLinkedProgram();
const auto &attribs = state.getVertexArray()->getVertexAttributes();
const auto &bindings = state.getVertexArray()->getVertexBindings();
@ -1011,14 +1011,14 @@ bool ValidateWebGLVertexAttribPointer(Context *context,
return true;
}
Program *GetValidProgram(Context *context, GLuint id)
Program *GetValidProgramNoResolve(Context *context, GLuint id)
{
// ES3 spec (section 2.11.1) -- "Commands that accept shader or program object names will
// generate the error INVALID_VALUE if the provided name is not the name of either a shader
// or program object and INVALID_OPERATION if the provided name identifies an object
// that is not the expected type."
Program *validProgram = context->getProgram(id);
Program *validProgram = context->getProgramNoResolveLink(id);
if (!validProgram)
{
@ -1035,6 +1035,16 @@ Program *GetValidProgram(Context *context, GLuint id)
return validProgram;
}
Program *GetValidProgram(Context *context, GLuint id)
{
Program *program = GetValidProgramNoResolve(context, id);
if (program)
{
program->resolveLink();
}
return program;
}
Shader *GetValidShader(Context *context, GLuint id)
{
// See ValidProgram for spec details.
@ -1043,7 +1053,7 @@ Shader *GetValidShader(Context *context, GLuint id)
if (!validShader)
{
if (context->getProgram(id))
if (context->getProgramNoResolveLink(id))
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedShaderName);
}
@ -2140,7 +2150,7 @@ bool ValidateUniformMatrixValue(Context *context, GLenum valueType, GLenum unifo
bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei count)
{
const LinkedUniform *uniform = nullptr;
Program *programObject = context->getGLState().getProgram();
Program *programObject = context->getGLState().getLinkedProgram();
return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
ValidateUniformValue(context, valueType, uniform->type);
}
@ -2148,7 +2158,7 @@ bool ValidateUniform(Context *context, GLenum valueType, GLint location, GLsizei
bool ValidateUniform1iv(Context *context, GLint location, GLsizei count, const GLint *value)
{
const LinkedUniform *uniform = nullptr;
Program *programObject = context->getGLState().getProgram();
Program *programObject = context->getGLState().getLinkedProgram();
return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
ValidateUniform1ivValue(context, uniform->type, count, value);
}
@ -2166,7 +2176,7 @@ bool ValidateUniformMatrix(Context *context,
}
const LinkedUniform *uniform = nullptr;
Program *programObject = context->getGLState().getProgram();
Program *programObject = context->getGLState().getLinkedProgram();
return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
ValidateUniformMatrixValue(context, valueType, uniform->type);
}
@ -2647,7 +2657,7 @@ const char *ValidateDrawStates(Context *context)
// If we are running GLES1, there is no current program.
if (context->getClientVersion() >= Version(2, 0))
{
Program *program = state.getProgram();
Program *program = state.getLinkedProgram();
if (!program)
{
return kErrorProgramNotBound;
@ -2794,7 +2804,7 @@ bool ValidateDrawMode(Context *context, PrimitiveMode mode)
{
const State &state = context->getGLState();
Program *program = state.getProgram();
Program *program = state.getLinkedProgram();
ASSERT(program);
// Do geometry shader specific validations
@ -3269,7 +3279,7 @@ static bool ValidateSizedGetUniform(Context *context,
return false;
}
Program *programObject = context->getProgram(program);
Program *programObject = context->getProgramResolveLink(program);
ASSERT(programObject);
// sized queries -- ensure the provided buffer is large enough
@ -4405,7 +4415,10 @@ bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GL
*numParams = 1;
}
Program *programObject = GetValidProgram(context, program);
// Special case for GL_COMPLETION_STATUS_KHR: don't resolve the link. Otherwise resolve it now.
Program *programObject = (pname == GL_COMPLETION_STATUS_KHR)
? GetValidProgramNoResolve(context, program)
: GetValidProgram(context, program);
if (!programObject)
{
return false;
@ -4415,7 +4428,6 @@ bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GL
{
case GL_DELETE_STATUS:
case GL_LINK_STATUS:
case GL_COMPLETION_STATUS_KHR:
case GL_VALIDATE_STATUS:
case GL_INFO_LOG_LENGTH:
case GL_ATTACHED_SHADERS:
@ -4507,6 +4519,14 @@ bool ValidateGetProgramivBase(Context *context, GLuint program, GLenum pname, GL
}
break;
case GL_COMPLETION_STATUS_KHR:
if (!context->getExtensions().parallelShaderCompile)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
return false;
}
break;
default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
return false;
@ -5357,7 +5377,6 @@ bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsi
case GL_SHADER_TYPE:
case GL_DELETE_STATUS:
case GL_COMPILE_STATUS:
case GL_COMPLETION_STATUS_KHR:
case GL_INFO_LOG_LENGTH:
case GL_SHADER_SOURCE_LENGTH:
break;
@ -5370,6 +5389,14 @@ bool ValidateGetShaderivBase(Context *context, GLuint shader, GLenum pname, GLsi
}
break;
case GL_COMPLETION_STATUS_KHR:
if (!context->getExtensions().parallelShaderCompile)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
return false;
}
break;
default:
ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
return false;

Просмотреть файл

@ -2250,7 +2250,7 @@ static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier,
return true;
case GL_PROGRAM:
if (context->getProgram(name) == nullptr)
if (context->getProgramNoResolveLink(name) == nullptr)
{
context->handleError(InvalidValue() << "name is not a valid program.");
return false;
@ -3843,7 +3843,7 @@ bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
return false;
}
const auto *programObject = context->getProgram(program);
const auto *programObject = context->getProgramNoResolveLink(program);
if (!programObject)
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
@ -3878,7 +3878,7 @@ bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
return false;
}
const auto *programObject = context->getProgram(program);
const auto *programObject = context->getProgramResolveLink(program);
if (!programObject || programObject->isFlaggedForDeletion())
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
@ -4933,7 +4933,7 @@ bool ValidateDeleteProgram(Context *context, GLuint program)
return false;
}
if (!context->getProgram(program))
if (!context->getProgramResolveLink(program))
{
if (context->getShader(program))
{
@ -4959,7 +4959,7 @@ bool ValidateDeleteShader(Context *context, GLuint shader)
if (!context->getShader(shader))
{
if (context->getProgram(shader))
if (context->getProgramResolveLink(shader))
{
ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
return false;
@ -6322,7 +6322,7 @@ bool ValidateUseProgram(Context *context, GLuint program)
{
if (program != 0)
{
Program *programObject = context->getProgram(program);
Program *programObject = context->getProgramResolveLink(program);
if (!programObject)
{
// ES 3.1.0 section 7.3 page 72

Просмотреть файл

@ -2192,7 +2192,7 @@ bool ValidateBeginTransformFeedback(Context *context, PrimitiveMode primitiveMod
}
}
Program *program = context->getGLState().getProgram();
Program *program = context->getGLState().getLinkedProgram();
if (!program)
{

Просмотреть файл

@ -1419,7 +1419,7 @@ bool ValidateDispatchCompute(Context *context,
}
const State &state = context->getGLState();
Program *program = state.getProgram();
Program *program = state.getLinkedProgram();
if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
{
@ -1462,7 +1462,7 @@ bool ValidateDispatchComputeIndirect(Context *context, GLintptr indirect)
}
const State &state = context->getGLState();
Program *program = state.getProgram();
Program *program = state.getLinkedProgram();
if (program == nullptr || !program->hasLinkedShaderStage(ShaderType::Compute))
{