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)
return Error(GL_NO_ERROR);
}
if (!linkUniformBlocks(mInfoLog, *data.caps))
{
return Error(GL_NO_ERROR);
}
int registers;
std::vector<LinkedVarying> linkedVaryings;
rx::LinkResult result =
......@@ -310,12 +315,6 @@ Error Program::link(const gl::Data &data)
return result.error;
}
if (!linkUniformBlocks(mInfoLog, *mData.mAttachedVertexShader, *mData.mAttachedFragmentShader,
*data.caps))
{
return Error(GL_NO_ERROR);
}
if (!gatherTransformFeedbackLinkedVaryings(
mInfoLog, linkedVaryings, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
{
......@@ -1438,55 +1437,62 @@ bool Program::linkAttributes(const gl::Data &data,
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> &fragmentInterfaceBlocks = fragmentShader.getInterfaceBlocks();
// Check that interface blocks defined in the vertex and fragment shaders are identical
typedef std::map<std::string, const sh::InterfaceBlock*> UniformBlockMap;
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;
}
for (unsigned int blockIndex = 0; blockIndex < fragmentInterfaceBlocks.size(); blockIndex++)
{
const sh::InterfaceBlock &fragmentInterfaceBlock = fragmentInterfaceBlocks[blockIndex];
UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
if (entry != linkedUniformBlocks.end())
// Note: shared and std140 layouts are always considered active
if (vertexInterfaceBlock.staticUse || vertexInterfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
{
const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
if (++vertexBlockCount > caps.maxVertexUniformBlocks)
{
infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS ("
<< caps.maxVertexUniformBlocks << ")";
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];
// Note: shared and std140 layouts are always considered active
if (interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED)
auto entry = linkedUniformBlocks.find(fragmentInterfaceBlock.name);
if (entry != linkedUniformBlocks.end())
{
if (!mProgram->defineUniformBlock(infoLog, vertexShader, interfaceBlock, caps))
const sh::InterfaceBlock &vertexInterfaceBlock = *entry->second;
if (!areMatchingInterfaceBlocks(infoLog, vertexInterfaceBlock, fragmentInterfaceBlock))
{
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
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 true;
}
......
......@@ -308,7 +308,7 @@ class Program : angle::NonCopyable
InfoLog &infoLog,
const AttributeBindings &attributeBindings,
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,
const Shader *vertexShader,
const Shader *fragmentShader);
......
......@@ -86,13 +86,8 @@ class ProgramImpl : angle::NonCopyable
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 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::map<GLuint, gl::VariableLocation> &getUniformIndices() const { return mUniformIndex; }
......
......@@ -1152,6 +1152,8 @@ LinkResult ProgramD3D::link(const gl::Data &data, gl::InfoLog &infoLog,
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
defineUniformBlocks(*data.caps);
return LinkResult(true, gl::Error(GL_NO_ERROR));
}
......@@ -1256,30 +1258,23 @@ gl::Error ProgramD3D::applyUniformBuffers(const gl::Data &data, GLuint uniformBl
return mRenderer->setUniformBuffers(data, mVertexUBOCache, mFragmentUBOCache);
}
bool ProgramD3D::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
unsigned int registerIndex, const gl::Caps &caps)
void ProgramD3D::assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
GLenum shader,
unsigned int registerIndex,
const gl::Caps &caps)
{
// Validation done in the GL-level Program.
if (shader == GL_VERTEX_SHADER)
{
uniformBlock->vsRegisterIndex = registerIndex;
if (registerIndex - mRenderer->getReservedVertexUniformBuffers() >= caps.maxVertexUniformBlocks)
{
infoLog << "Vertex shader uniform block count exceed GL_MAX_VERTEX_UNIFORM_BLOCKS (" << caps.maxVertexUniformBlocks << ")";
return false;
}
ASSERT(registerIndex < caps.maxVertexUniformBlocks);
}
else if (shader == GL_FRAGMENT_SHADER)
{
uniformBlock->psRegisterIndex = registerIndex;
if (registerIndex - mRenderer->getReservedFragmentUniformBuffers() >= caps.maxFragmentUniformBlocks)
{
infoLog << "Fragment shader uniform block count exceed GL_MAX_FRAGMENT_UNIFORM_BLOCKS (" << caps.maxFragmentUniformBlocks << ")";
return false;
}
ASSERT(registerIndex < caps.maxFragmentUniformBlocks);
}
else UNREACHABLE();
return true;
}
void ProgramD3D::dirtyAllUniforms()
......@@ -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>
static inline void SetIfDirty(T *dest, const T& source, bool *dirtyFlag)
{
......@@ -1834,8 +1852,7 @@ void ProgramD3D::defineUniformBlockMembers(const std::vector<VarT> &fields, cons
}
}
bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog,
const gl::Shader &shader,
void ProgramD3D::defineUniformBlock(const gl::Shader &shader,
const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps)
{
......@@ -1897,15 +1914,10 @@ bool ProgramD3D::defineUniformBlock(gl::InfoLog &infoLog,
gl::UniformBlock *uniformBlock = mUniformBlocks[blockIndex + uniformBlockElement];
ASSERT(uniformBlock->name == interfaceBlock.name);
if (!assignUniformBlockRegister(infoLog, uniformBlock, shader.getType(),
interfaceBlockRegister + uniformBlockElement, caps))
{
return false;
}
assignUniformBlockRegister(uniformBlock, shader.getType(),
interfaceBlockRegister + uniformBlockElement, caps);
}
}
return true;
}
bool ProgramD3D::assignSamplers(unsigned int startSamplerIndex,
......
......@@ -80,8 +80,10 @@ class ProgramD3D : public ProgramImpl
void initializeUniformStorage();
gl::Error applyUniforms();
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);
void assignUniformBlockRegister(gl::UniformBlock *uniformBlock,
GLenum shader,
unsigned int registerIndex,
const gl::Caps &caps);
void dirtyAllUniforms();
void setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
......@@ -113,8 +115,6 @@ class ProgramD3D : public ProgramImpl
const UniformStorageD3D &getVertexUniformStorage() const { return *mVertexUniformStorage; }
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();
unsigned int getSerial() const;
......@@ -187,6 +187,11 @@ class ProgramD3D : public ProgramImpl
static bool assignSamplers(unsigned int startSamplerIndex, GLenum samplerType, unsigned int samplerCount,
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>
void setUniform(GLint location, GLsizei count, const T* v, GLenum targetUniformType);
......
......@@ -395,13 +395,6 @@ LinkResult ProgramGL::compileProgramExecutables(gl::InfoLog &infoLog, int regist
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()
{
//UNIMPLEMENTED();
......@@ -415,13 +408,6 @@ gl::Error ProgramGL::applyUniformBuffers(const gl::Data &data, GLuint uniformBlo
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()
{
ProgramImpl::reset();
......
......@@ -79,13 +79,13 @@ class ProgramGL : public ProgramImpl
LinkResult compileProgramExecutables(gl::InfoLog &infoLog, int registers) override;
bool defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps) override;
void defineUniformBlock(gl::InfoLog &infoLog,
const gl::Shader &shader,
const sh::InterfaceBlock &interfaceBlock,
const gl::Caps &caps);
gl::Error applyUniforms() 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;
......
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