Link interface blocks in ProgramImpl::link.
This allows the back-end to have access to the interface block info
in the link operation, and also allows the interface block info to
have direct access to the post-link Impl information.
BUG=angleproject:2208
Change-Id: Ib2bfb3c9155eee715bd3d29de1c3fdd67b16eed4
Reviewed-on: https://chromium-review.googlesource.com/753521
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 6310ba7..150ffa3 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -199,6 +199,97 @@
UNREACHABLE();
}
+class UniformBlockInfo final : angle::NonCopyable
+{
+ public:
+ UniformBlockInfo() {}
+
+ void getShaderBlockInfo(const gl::Context *context, gl::Shader *shader);
+
+ bool getBlockSize(const std::string &name, const std::string &mappedName, size_t *sizeOut);
+ bool getBlockMemberInfo(const std::string &name,
+ const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut);
+
+ private:
+ size_t getBlockInfo(const sh::InterfaceBlock &interfaceBlock);
+
+ std::map<std::string, size_t> mBlockSizes;
+ sh::BlockLayoutMap mBlockLayout;
+};
+
+void UniformBlockInfo::getShaderBlockInfo(const gl::Context *context, gl::Shader *shader)
+{
+ for (const sh::InterfaceBlock &interfaceBlock : shader->getUniformBlocks(context))
+ {
+ if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
+ continue;
+
+ if (mBlockSizes.count(interfaceBlock.name) > 0)
+ continue;
+
+ size_t dataSize = getBlockInfo(interfaceBlock);
+ mBlockSizes[interfaceBlock.name] = dataSize;
+ }
+}
+
+size_t UniformBlockInfo::getBlockInfo(const sh::InterfaceBlock &interfaceBlock)
+{
+ ASSERT(interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED);
+
+ // define member uniforms
+ sh::Std140BlockEncoder std140Encoder;
+ sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
+ sh::BlockLayoutEncoder *encoder = nullptr;
+
+ if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140)
+ {
+ encoder = &std140Encoder;
+ }
+ else
+ {
+ encoder = &hlslEncoder;
+ }
+
+ sh::GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
+ interfaceBlock.isRowMajorLayout, &mBlockLayout);
+
+ return encoder->getBlockSize();
+}
+
+bool UniformBlockInfo::getBlockSize(const std::string &name,
+ const std::string &mappedName,
+ size_t *sizeOut)
+{
+ size_t nameLengthWithoutArrayIndex;
+ gl::ParseArrayIndex(name, &nameLengthWithoutArrayIndex);
+ std::string baseName = name.substr(0u, nameLengthWithoutArrayIndex);
+ auto sizeIter = mBlockSizes.find(baseName);
+ if (sizeIter == mBlockSizes.end())
+ {
+ *sizeOut = 0;
+ return false;
+ }
+
+ *sizeOut = sizeIter->second;
+ return true;
+};
+
+bool UniformBlockInfo::getBlockMemberInfo(const std::string &name,
+ const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut)
+{
+ auto infoIter = mBlockLayout.find(name);
+ if (infoIter == mBlockLayout.end())
+ {
+ *infoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
+ return false;
+ }
+
+ *infoOut = infoIter->second;
+ return true;
+};
+
} // anonymous namespace
// D3DUniform Implementation
@@ -1028,10 +1119,6 @@
stream->writeInt(uniform->registerElement);
}
- // Ensure we init the uniform block structure data if we should.
- // http://anglebug.com/1637
- ensureUniformBlocksInitialized();
-
stream->writeInt(mD3DUniformBlocks.size());
for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
{
@@ -1505,8 +1592,6 @@
infoLog << "Failed to create D3D compute shader.";
return result;
}
-
- initUniformBlockInfo(context, computeShader);
}
else
{
@@ -1582,11 +1667,10 @@
infoLog << "Failed to create D3D shaders.";
return result;
}
-
- initUniformBlockInfo(context, vertexShader);
- initUniformBlockInfo(context, fragmentShader);
}
+ linkResources(context, resources);
+
return true;
}
@@ -1596,29 +1680,15 @@
return GL_TRUE;
}
-void ProgramD3D::initUniformBlockInfo(const gl::Context *context, gl::Shader *shader)
+void ProgramD3D::initializeUniformBlocks()
{
- for (const sh::InterfaceBlock &interfaceBlock : shader->getUniformBlocks(context))
- {
- if (!interfaceBlock.staticUse && interfaceBlock.layout == sh::BLOCKLAYOUT_PACKED)
- continue;
-
- if (mBlockDataSizes.count(interfaceBlock.name) > 0)
- continue;
-
- size_t dataSize = getUniformBlockInfo(interfaceBlock);
- mBlockDataSizes[interfaceBlock.name] = dataSize;
- }
-}
-
-void ProgramD3D::ensureUniformBlocksInitialized()
-{
- // Lazy init.
- if (mState.getUniformBlocks().empty() || !mD3DUniformBlocks.empty())
+ if (mState.getUniformBlocks().empty())
{
return;
}
+ ASSERT(mD3DUniformBlocks.empty());
+
// Assign registers and update sizes.
const ShaderD3D *vertexShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
const ShaderD3D *fragmentShaderD3D =
@@ -1731,8 +1801,6 @@
return;
}
- ensureUniformBlocksInitialized();
-
mVertexUBOCache.clear();
mFragmentUBOCache.clear();
@@ -2278,30 +2346,6 @@
}
}
-size_t ProgramD3D::getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock)
-{
- ASSERT(interfaceBlock.staticUse || interfaceBlock.layout != sh::BLOCKLAYOUT_PACKED);
-
- // define member uniforms
- sh::Std140BlockEncoder std140Encoder;
- sh::HLSLBlockEncoder hlslEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
- sh::BlockLayoutEncoder *encoder = nullptr;
-
- if (interfaceBlock.layout == sh::BLOCKLAYOUT_STD140)
- {
- encoder = &std140Encoder;
- }
- else
- {
- encoder = &hlslEncoder;
- }
-
- sh::GetUniformBlockInfo(interfaceBlock.fields, interfaceBlock.fieldPrefix(), encoder,
- interfaceBlock.isRowMajorLayout, &mBlockInfo);
-
- return encoder->getBlockSize();
-}
-
void ProgramD3D::assignAllSamplerRegisters()
{
for (D3DUniform *d3dUniform : mD3DUniforms)
@@ -2595,40 +2639,6 @@
return mD3DUniforms[mState.getUniformLocations()[location].index];
}
-bool ProgramD3D::getUniformBlockSize(const std::string &blockName,
- const std::string & /* blockMappedName */,
- size_t *sizeOut) const
-{
- size_t nameLengthWithoutArrayIndex;
- gl::ParseArrayIndex(blockName, &nameLengthWithoutArrayIndex);
- std::string baseName = blockName.substr(0u, nameLengthWithoutArrayIndex);
-
- auto sizeIter = mBlockDataSizes.find(baseName);
- if (sizeIter == mBlockDataSizes.end())
- {
- *sizeOut = 0;
- return false;
- }
-
- *sizeOut = sizeIter->second;
- return true;
-}
-
-bool ProgramD3D::getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string & /* memberUniformMappedName */,
- sh::BlockMemberInfo *memberInfoOut) const
-{
- auto infoIter = mBlockInfo.find(memberUniformName);
- if (infoIter == mBlockInfo.end())
- {
- *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
- return false;
- }
-
- *memberInfoOut = infoIter->second;
- return true;
-}
-
void ProgramD3D::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode,
GLint components,
@@ -2720,4 +2730,56 @@
}
}
+void ProgramD3D::linkResources(const gl::Context *context,
+ const gl::ProgramLinkedResources &resources)
+{
+ UniformBlockInfo uniformBlockInfo;
+
+ if (mState.getAttachedVertexShader())
+ {
+ uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedVertexShader());
+ }
+
+ if (mState.getAttachedFragmentShader())
+ {
+ uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedFragmentShader());
+ }
+
+ if (mState.getAttachedComputeShader())
+ {
+ uniformBlockInfo.getShaderBlockInfo(context, mState.getAttachedComputeShader());
+ }
+
+ // Gather interface block info.
+ auto getUniformBlockSize = [&uniformBlockInfo](const std::string &name,
+ const std::string &mappedName, size_t *sizeOut) {
+ return uniformBlockInfo.getBlockSize(name, mappedName, sizeOut);
+ };
+
+ auto getUniformBlockMemberInfo = [&uniformBlockInfo](const std::string &name,
+ const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut) {
+ return uniformBlockInfo.getBlockMemberInfo(name, mappedName, infoOut);
+ };
+
+ resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
+ initializeUniformBlocks();
+
+ // TODO(jiajia.qin@intel.com): Determine correct shader storage block info.
+ auto getShaderStorageBlockSize = [](const std::string &name, const std::string &mappedName,
+ size_t *sizeOut) {
+ *sizeOut = 0;
+ return true;
+ };
+
+ auto getShaderStorageBlockMemberInfo =
+ [](const std::string &name, const std::string &mappedName, sh::BlockMemberInfo *infoOut) {
+ *infoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
+ return true;
+ };
+
+ resources.shaderStorageBlockLinker.linkBlocks(getShaderStorageBlockSize,
+ getShaderStorageBlockMemberInfo);
+}
+
} // namespace rx