Commit e473deee by Jamie Madill

Clean up uniform block Program Impl APIs.

The D3D-specific code we can split into D3D-only methods, and the GL-level shared code we can place in Program instead of making Impl methods. This cleans up the Impl inteface significantly. BUG=angleproject:1123 Change-Id: Ibcb7d07733eb939adf5bb4f5395a661875a60238 Reviewed-on: https://chromium-review.googlesource.com/293763Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 39939686
...@@ -300,6 +300,11 @@ Error Program::link(const gl::Data &data) ...@@ -300,6 +300,11 @@ Error Program::link(const gl::Data &data)
return Error(GL_NO_ERROR); return Error(GL_NO_ERROR);
} }
if (!linkUniformBlocks(mInfoLog, *data.caps))
{
return Error(GL_NO_ERROR);
}
int registers; int registers;
std::vector<LinkedVarying> linkedVaryings; std::vector<LinkedVarying> linkedVaryings;
rx::LinkResult result = rx::LinkResult result =
...@@ -310,12 +315,6 @@ Error Program::link(const gl::Data &data) ...@@ -310,12 +315,6 @@ Error Program::link(const gl::Data &data)
return result.error; return result.error;
} }
if (!linkUniformBlocks(mInfoLog, *mData.mAttachedVertexShader, *mData.mAttachedFragmentShader,
*data.caps))
{
return Error(GL_NO_ERROR);
}
if (!gatherTransformFeedbackLinkedVaryings( if (!gatherTransformFeedbackLinkedVaryings(
mInfoLog, linkedVaryings, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps)) mInfoLog, linkedVaryings, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
{ {
...@@ -1438,55 +1437,62 @@ bool Program::linkAttributes(const gl::Data &data, ...@@ -1438,55 +1437,62 @@ bool Program::linkAttributes(const gl::Data &data,
return true; return true;
} }
bool Program::linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps) bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
{ {
const Shader &vertexShader = *mData.mAttachedVertexShader;
const Shader &fragmentShader = *mData.mAttachedFragmentShader;
const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks(); const std::vector<sh::InterfaceBlock> &vertexInterfaceBlocks = vertexShader.getInterfaceBlocks();
const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks(); const std::vector<sh::InterfaceBlock> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
// Check that interface blocks defined in the vertex and fragment shaders are identical // Check that interface blocks defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap; typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
UniformBlockMap linkedUniformBlocks; UniformBlockMap linkedUniformBlocks;
for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
GLuint vertexBlockCount = 0;
for (const sh::InterfaceBlock &vertexInterfaceBlock : vertexInterfaceBlocks)
{ {
const sh::InterfaceBlock &vertexInterfaceBlock = vertexInterfaceBlocks[blockIndex];
linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock; linkedUniformBlocks[vertexInterfaceBlock.name] = &vertexInterfaceBlock;
}
for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++) // Note: shared and std140 layouts are always considered active
{ if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
if (entry != linkedUniformBlocks.end())
{ {
const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second; if (++vertexBlockCount > caps.maxVertexUniformBlocks)
if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
{ {
infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS ("
<< caps.maxVertexUniformBlocks << ")";
return false; return false;
} }
} }
} }
for (unsigned int blockIndex = 0; blockIndex < vertexInterfaceBlocks.size(); blockIndex++)
GLuint fragmentBlockCount = 0;
for (const sh::InterfaceBlock &fragmentInterfaceBlock : fragmentInterfaceBlocks)
{ {
const sh::InterfaceBlock &interfaceBlock = vertexInterfaceBlocks[blockIndex]; auto entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
// Note: shared and std140 layouts are always considered active if (entry != linkedUniformBlocks.end())
if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{ {
if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps)) const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
{ {
return false; return false;
} }
} }
}
for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
const sh::InterfaceBlock &interfaceBlock = fragmentInterfaceBlocks[blockIndex];
// Note: shared and std140 layouts are always considered active // Note: shared and std140 layouts are always considered active
if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED) if (fragmentInterfaceBlock.staticUse ||
fragmentInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{ {
if (!mProgram->defineUniformBlock(infoLog, fragmentShader, interfaceBlock, caps)) if (++fragmentBlockCount > caps.maxFragmentUniformBlocks)
{ {
infoLog
<< "Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS ("
<< caps.maxFragmentUniformBlocks << ")";
return false; return false;
} }
} }
} }
return true; return true;
} }
......
...@@ -308,7 +308,7 @@ class Program : angle::NonCopyable ...@@ -308,7 +308,7 @@ class Program : angle::NonCopyable
InfoLog &infoLog, InfoLog &infoLog,
const AttributeBindings &attributeBindings, const AttributeBindings &attributeBindings,
const Shader *vertexShader); const Shader *vertexShader);
bool linkUniformBlocks(InfoLog &infoLog, const Shader &vertexShader, const Shader &fragmentShader, const Caps &caps); bool linkUniformBlocks(InfoLog &infoLog, const Caps &caps);
static bool linkVaryings(InfoLog &infoLog, static bool linkVaryings(InfoLog &infoLog,
const Shader *vertexShader, const Shader *vertexShader,
const Shader *fragmentShader); const Shader *fragmentShader);
......
...@@ -86,13 +86,8 @@ class ProgramImpl : angle::NonCopyable ...@@ -86,13 +86,8 @@ class ProgramImpl : angle::NonCopyable
virtual LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers) = 0; virtual LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers) = 0;
virtual bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps) = 0;
virtual gl::Error applyUniforms() = 0; virtual gl::Error applyUniforms() = 0;
virtual gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) = 0; virtual gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) = 0;
virtual bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
unsigned int registerIndex, const gl::Caps &caps) = 0;
const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; } const std::vector<gl::LinkedUniform*> &getUniforms() const { return mUniforms; }
const std::map<GLuint, gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; } const std::map<GLuint, gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
......
...@@ -1152,6 +1152,8 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog, ...@@ -1152,6 +1152,8 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
return LinkResult(false, gl::Error(GL_NO_ERROR)); return LinkResult(false, gl::Error(GL_NO_ERROR));
} }
defineUniformBlocks(*data.caps);
return LinkResult(true, gl::Error(GL_NO_ERROR)); return LinkResult(true, gl::Error(GL_NO_ERROR));
} }
...@@ -1256,30 +1258,23 @@ gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data, GLuint uniformBl ...@@ -1256,30 +1258,23 @@ gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data, GLuint uniformBl
return mRenderer->setUniformBuffers(data, mVertexUBOCache, mFragmentUBOCache); return mRenderer->setUniformBuffers(data, mVertexUBOCache, mFragmentUBOCache);
} }
bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, void ProgramD3D::assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
unsigned int registerIndex, const gl::Caps &caps) GLenum shader,
unsigned int registerIndex,
const gl::Caps &caps)
{ {
// Validation done in the GL-level Program.
if (shader == GL_VERTEX_SHADER) if (shader == GL_VERTEX_SHADER)
{ {
uniformBlock->vsRegisterIndex = registerIndex; uniformBlock->vsRegisterIndex = registerIndex;
if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks) ASSERT(registerIndex < caps.maxVertexUniformBlocks);
{
infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (" << caps.maxVertexUniformBlocks << ")";
return false;
}
} }
else if (shader == GL_FRAGMENT_SHADER) else if (shader == GL_FRAGMENT_SHADER)
{ {
uniformBlock->psRegisterIndex = registerIndex; uniformBlock->psRegisterIndex = registerIndex;
if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks) ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
{
infoLog << "Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (" << caps.maxFragmentUniformBlocks << ")";
return false;
}
} }
else UNREACHABLE(); else UNREACHABLE();
return true;
} }
void ProgramD3D::dirtyAllUniforms() void ProgramD3D::dirtyAllUniforms()
...@@ -1541,6 +1536,29 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable ...@@ -1541,6 +1536,29 @@ void ProgramD3D::defineUniform(const ShaderD3D *shader, const sh::ShaderVariable
} }
} }
void ProgramD3D::defineUniformBlocks(const gl::Caps &caps)
{
const gl::Shader *vertexShader = mData.getAttachedVertexShader();
for (const sh::InterfaceBlock &vertexBlock : vertexShader->getInterfaceBlocks())
{
if (vertexBlock.staticUse || vertexBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
defineUniformBlock(*vertexShader, vertexBlock, caps);
}
}
const gl::Shader *fragmentShader = mData.getAttachedFragmentShader();
for (const sh::InterfaceBlock &fragmentBlock : fragmentShader->getInterfaceBlocks())
{
if (fragmentBlock.staticUse || fragmentBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
defineUniformBlock(*fragmentShader, fragmentBlock, caps);
}
}
}
template <typename T> template <typename T>
static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag) static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
{ {
...@@ -1834,8 +1852,7 @@ void ProgramD3D::defineUniformBlockMembers(const std::vector<VarT> &fields, cons ...@@ -1834,8 +1852,7 @@ void ProgramD3D::defineUniformBlockMembers(const std::vector<VarT> &fields, cons
} }
} }
bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog, void ProgramD3D::defineUniformBlock(const gl::Shader &shader,
const gl::Shader &shader,
const sh::InterfaceBlock &interfaceBlock, const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps) const gl::Caps &caps)
{ {
...@@ -1897,15 +1914,10 @@ bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog, ...@@ -1897,15 +1914,10 @@ bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog,
gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement]; gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
ASSERT(uniformBlock->name == interfaceBlock.name); ASSERT(uniformBlock->name == interfaceBlock.name);
if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(), assignUniformBlockRegister(uniformBlock, shader.getType(),
interfaceBlockRegister + uniformBlockElement, caps)) interfaceBlockRegister + uniformBlockElement, caps);
{
return false;
}
} }
} }
return true;
} }
bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex, bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex,
......
...@@ -80,8 +80,10 @@ class ProgramD3D : public ProgramImpl ...@@ -80,8 +80,10 @@ class ProgramD3D : public ProgramImpl
void initializeUniformStorage(); void initializeUniformStorage();
gl::Error applyUniforms(); gl::Error applyUniforms();
gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override; gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override;
bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader, void assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
unsigned int registerIndex, const gl::Caps &caps); GLenum shader,
unsigned int registerIndex,
const gl::Caps &caps);
void dirtyAllUniforms(); void dirtyAllUniforms();
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v); void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
...@@ -113,8 +115,6 @@ class ProgramD3D : public ProgramImpl ...@@ -113,8 +115,6 @@ class ProgramD3D : public ProgramImpl
const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; } const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; } const UniformStorageD3D &getFragmentUniformStorage() const { return *mFragmentUniformStorage; }
bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, const gl::Caps &caps);
void reset(); void reset();
unsigned int getSerial() const; unsigned int getSerial() const;
...@@ -187,6 +187,11 @@ class ProgramD3D : public ProgramImpl ...@@ -187,6 +187,11 @@ class ProgramD3D : public ProgramImpl
static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount, static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
std::vector<Sampler> &outSamplers, GLuint *outUsedRange); std::vector<Sampler> &outSamplers, GLuint *outUsedRange);
void defineUniformBlocks(const gl::Caps &caps);
void defineUniformBlock(const gl::Shader &shader,
const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps);
template <typename T> template <typename T>
void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType); void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
......
...@@ -395,13 +395,6 @@ LinkResult ProgramGL::compileProgramExecutables(gl::InfoLog &infoLog, int regist ...@@ -395,13 +395,6 @@ LinkResult ProgramGL::compileProgramExecutables(gl::InfoLog &infoLog, int regist
return LinkResult(true, gl::Error(GL_NO_ERROR)); return LinkResult(true, gl::Error(GL_NO_ERROR));
} }
bool ProgramGL::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps)
{
UNIMPLEMENTED();
return bool();
}
gl::Error ProgramGL::applyUniforms() gl::Error ProgramGL::applyUniforms()
{ {
//UNIMPLEMENTED(); //UNIMPLEMENTED();
...@@ -415,13 +408,6 @@ gl::Error ProgramGL::applyUniformBuffers(const gl::Data &data, GLuint uniformBlo ...@@ -415,13 +408,6 @@ gl::Error ProgramGL::applyUniformBuffers(const gl::Data &data, GLuint uniformBlo
return gl::Error(GL_INVALID_OPERATION); return gl::Error(GL_INVALID_OPERATION);
} }
bool ProgramGL::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
unsigned int registerIndex, const gl::Caps &caps)
{
UNIMPLEMENTED();
return bool();
}
void ProgramGL::reset() void ProgramGL::reset()
{ {
ProgramImpl::reset(); ProgramImpl::reset();
......
...@@ -79,13 +79,13 @@ class ProgramGL : public ProgramImpl ...@@ -79,13 +79,13 @@ class ProgramGL : public ProgramImpl
LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers) override; LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers) override;
bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock, void defineUniformBlock(gl::InfoLog &infoLog,
const gl::Caps &caps) override; const gl::Shader &shader,
const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps);
gl::Error applyUniforms() override; gl::Error applyUniforms() override;
gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override; gl::Error applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[]) override;
bool assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
unsigned int registerIndex, const gl::Caps &caps) override;
void reset() override; void reset() override;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment