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/Program.cpp b/src/libANGLE/Program.cpp
index c484668..887a001 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -871,7 +871,7 @@
}
gatherAtomicCounterBuffers();
- gatherInterfaceBlockInfo(context);
+ initInterfaceBlockBindings();
setUniformValuesFromBindingQualifiers();
@@ -2874,55 +2874,8 @@
// TODO(jie.a.chen@intel.com): Get the actual BUFFER_DATA_SIZE from backend for each buffer.
}
-void Program::gatherUniformBlockInfo(const gl::Context *context)
+void Program::initInterfaceBlockBindings()
{
- UniformBlockLinker blockLinker(&mState.mUniformBlocks, &mState.mUniforms);
- InitUniformBlockLinker(context, mState, &blockLinker);
-
- auto getImplBlockSize = [this](const std::string &name, const std::string &mappedName,
- size_t *sizeOut) {
- return this->mProgram->getUniformBlockSize(name, mappedName, sizeOut);
- };
-
- auto getImplMemberInfo = [this](const std::string &name, const std::string &mappedName,
- sh::BlockMemberInfo *infoOut) {
- return this->mProgram->getUniformBlockMemberInfo(name, mappedName, infoOut);
- };
-
- blockLinker.linkBlocks(getImplBlockSize, getImplMemberInfo);
-}
-
-void Program::gatherShaderStorageBlockInfo(const gl::Context *context)
-{
- ShaderStorageBlockLinker blockLinker(&mState.mShaderStorageBlocks);
- InitShaderStorageBlockLinker(context, mState, &blockLinker);
-
- // We don't have a way of determining block info for shader storage blocks yet.
- // TODO(jiajia.qin@intel.com): Determine correct block size and layout.
- auto getImplBlockSize = [this](const std::string &name, const std::string &mappedName,
- size_t *sizeOut) {
- return this->mProgram->getUniformBlockSize(name, mappedName, sizeOut);
- };
-
- auto getImplMemberInfo = [this](const std::string &name, const std::string &mappedName,
- sh::BlockMemberInfo *infoOut) {
- return this->mProgram->getUniformBlockMemberInfo(name, mappedName, infoOut);
- };
-
- blockLinker.linkBlocks(getImplBlockSize, getImplMemberInfo);
-}
-
-void Program::gatherInterfaceBlockInfo(const Context *context)
-{
- ASSERT(mState.mUniformBlocks.empty());
- ASSERT(mState.mShaderStorageBlocks.empty());
-
- gatherUniformBlockInfo(context);
- if (context->getClientVersion() >= Version(3, 1))
- {
- gatherShaderStorageBlockInfo(context);
- }
-
// Set initial bindings from shader.
for (unsigned int blockIndex = 0; blockIndex < mState.mUniformBlocks.size(); blockIndex++)
{
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index d0dbfb7..1973f99 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -640,9 +640,7 @@
void setUniformValuesFromBindingQualifiers();
void gatherAtomicCounterBuffers();
- void gatherUniformBlockInfo(const gl::Context *context);
- void gatherShaderStorageBlockInfo(const gl::Context *context);
- void gatherInterfaceBlockInfo(const Context *context);
+ void initInterfaceBlockBindings();
// Both these function update the cached uniform values and return a modified "count"
// so that the uniform update doesn't overflow the uniform.
diff --git a/src/libANGLE/ProgramLinkedResources.cpp b/src/libANGLE/ProgramLinkedResources.cpp
index 16ff05a..a7f64d6 100644
--- a/src/libANGLE/ProgramLinkedResources.cpp
+++ b/src/libANGLE/ProgramLinkedResources.cpp
@@ -637,6 +637,8 @@
void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize,
const GetBlockMemberInfo &getMemberInfo) const
{
+ ASSERT(mBlocksOut->empty());
+
std::set<std::string> visitedList;
for (const auto &shaderBlocks : mShaderBlocks)
diff --git a/src/libANGLE/renderer/ProgramImpl.h b/src/libANGLE/renderer/ProgramImpl.h
index 7c5fce7..2371b27 100644
--- a/src/libANGLE/renderer/ProgramImpl.h
+++ b/src/libANGLE/renderer/ProgramImpl.h
@@ -83,17 +83,6 @@
// TODO: synchronize in syncState when dirty bits exist.
virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0;
- // May only be called after a successful link operation.
- // Return false for inactive blocks.
- virtual bool getUniformBlockSize(const std::string &blockName,
- const std::string &blockMappedName,
- size_t *sizeOut) const = 0;
-
- // May only be called after a successful link operation.
- // Returns false for inactive members.
- virtual bool getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string &memberUniformMappedName,
- sh::BlockMemberInfo *memberInfoOut) const = 0;
// CHROMIUM_path_rendering
// Set parameters to control fragment shader input variable interpolation
virtual void setPathFragmentInputGen(const std::string &inputName,
diff --git a/src/libANGLE/renderer/ProgramImpl_mock.h b/src/libANGLE/renderer/ProgramImpl_mock.h
index 9c55312..4717ab8 100644
--- a/src/libANGLE/renderer/ProgramImpl_mock.h
+++ b/src/libANGLE/renderer/ProgramImpl_mock.h
@@ -63,10 +63,6 @@
MOCK_CONST_METHOD3(getUniformuiv, void(const gl::Context *, GLint, GLuint *));
MOCK_METHOD2(setUniformBlockBinding, void(GLuint, GLuint));
- MOCK_CONST_METHOD3(getUniformBlockSize,
- bool(const std::string &, const std::string &, size_t *));
- MOCK_CONST_METHOD3(getUniformBlockMemberInfo,
- bool(const std::string &, const std::string &, sh::BlockMemberInfo *));
MOCK_METHOD4(setPathFragmentInputGen,
void(const std::string &, GLenum, GLint, const GLfloat *));
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
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.h b/src/libANGLE/renderer/d3d/ProgramD3D.h
index 0d8996d..c9634d3 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.h
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.h
@@ -196,12 +196,6 @@
gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
- bool getUniformBlockSize(const std::string &blockName,
- const std::string &blockMappedName,
- size_t *sizeOut) const override;
- bool getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string &memberUniformMappedName,
- sh::BlockMemberInfo *memberInfoOut) const override;
void setPathFragmentInputGen(const std::string &inputName,
GLenum genMode,
GLint components,
@@ -428,16 +422,15 @@
void initAttribLocationsToD3DSemantic(const gl::Context *context);
void reset();
- void ensureUniformBlocksInitialized();
-
- void initUniformBlockInfo(const gl::Context *context, gl::Shader *shader);
- size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock);
+ void initializeUniformBlocks();
void updateCachedInputLayoutFromShader(const gl::Context *context);
void updateCachedOutputLayoutFromShader();
void updateCachedVertexExecutableIndex();
void updateCachedPixelExecutableIndex();
+ void linkResources(const gl::Context *context, const gl::ProgramLinkedResources &resources);
+
RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL;
@@ -498,9 +491,6 @@
bool mFragmentUniformsDirty;
bool mComputeUniformsDirty;
- std::map<std::string, sh::BlockMemberInfo> mBlockInfo;
- std::map<std::string, size_t> mBlockDataSizes;
-
static unsigned int issueSerial();
static unsigned int mCurrentSerial;
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index b1a0c3f..466f1fa 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -14,6 +14,7 @@
#include "common/string_utils.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
+#include "libANGLE/ProgramLinkedResources.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h"
@@ -212,6 +213,7 @@
mStateManager->forceUseProgram(mProgramID);
}
+ linkResources(resources);
postLink();
return true;
@@ -805,4 +807,35 @@
}
}
+void ProgramGL::linkResources(const gl::ProgramLinkedResources &resources)
+{
+ // Gather interface block info.
+ auto getUniformBlockSize = [this](const std::string &name, const std::string &mappedName,
+ size_t *sizeOut) {
+ return this->getUniformBlockSize(name, mappedName, sizeOut);
+ };
+
+ auto getUniformBlockMemberInfo = [this](const std::string &name, const std::string &mappedName,
+ sh::BlockMemberInfo *infoOut) {
+ return this->getUniformBlockMemberInfo(name, mappedName, infoOut);
+ };
+
+ resources.uniformBlockLinker.linkBlocks(getUniformBlockSize, getUniformBlockMemberInfo);
+
+ // 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
diff --git a/src/libANGLE/renderer/gl/ProgramGL.h b/src/libANGLE/renderer/gl/ProgramGL.h
index fc92511..1fee677 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.h
+++ b/src/libANGLE/renderer/gl/ProgramGL.h
@@ -71,13 +71,6 @@
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
- bool getUniformBlockSize(const std::string &blockName,
- const std::string &blockMappedName,
- size_t *sizeOut) const override;
- bool getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string &memberUniformMappedName,
- sh::BlockMemberInfo *memberInfoOut) const override;
-
void setPathFragmentInputGen(const std::string &inputName,
GLenum genMode,
GLint components,
@@ -97,6 +90,14 @@
void postLink();
void reapplyUBOBindingsIfNeeded(const gl::Context *context);
+ bool getUniformBlockSize(const std::string &blockName,
+ const std::string &blockMappedName,
+ size_t *sizeOut) const;
+ bool getUniformBlockMemberInfo(const std::string &memberUniformName,
+ const std::string &memberUniformMappedName,
+ sh::BlockMemberInfo *memberInfoOut) const;
+ void linkResources(const gl::ProgramLinkedResources &resources);
+
// Helper function, makes it simpler to type.
GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
diff --git a/src/libANGLE/renderer/null/ProgramNULL.cpp b/src/libANGLE/renderer/null/ProgramNULL.cpp
index d312fd7..f7aeb18 100644
--- a/src/libANGLE/renderer/null/ProgramNULL.cpp
+++ b/src/libANGLE/renderer/null/ProgramNULL.cpp
@@ -183,23 +183,6 @@
{
}
-bool ProgramNULL::getUniformBlockSize(const std::string &blockName,
- const std::string &blockMappedName,
- size_t *sizeOut) const
-{
- // TODO(geofflang): Compute reasonable sizes?
- *sizeOut = 0;
- return true;
-}
-
-bool ProgramNULL::getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string &memberUniformMappedName,
- sh::BlockMemberInfo *memberInfoOut) const
-{
- // TODO(geofflang): Compute reasonable values?
- return true;
-}
-
void ProgramNULL::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode,
GLint components,
diff --git a/src/libANGLE/renderer/null/ProgramNULL.h b/src/libANGLE/renderer/null/ProgramNULL.h
index 61ff61b..4dc8097 100644
--- a/src/libANGLE/renderer/null/ProgramNULL.h
+++ b/src/libANGLE/renderer/null/ProgramNULL.h
@@ -89,17 +89,6 @@
// TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
- // May only be called after a successful link operation.
- // Return false for inactive blocks.
- bool getUniformBlockSize(const std::string &blockName,
- const std::string &blockMappedName,
- size_t *sizeOut) const override;
-
- // May only be called after a successful link operation.
- // Returns false for inactive members.
- bool getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string &memberUniformMappedName,
- sh::BlockMemberInfo *memberInfoOut) const override;
// CHROMIUM_path_rendering
// Set parameters to control fragment shader input variable interpolation
void setPathFragmentInputGen(const std::string &inputName,
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.cpp b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
index ee2d7c0..c464641 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.cpp
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.cpp
@@ -528,22 +528,6 @@
UNIMPLEMENTED();
}
-bool ProgramVk::getUniformBlockSize(const std::string &blockName,
- const std::string &blockMappedName,
- size_t *sizeOut) const
-{
- UNIMPLEMENTED();
- return bool();
-}
-
-bool ProgramVk::getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string &memberUniformMappedName,
- sh::BlockMemberInfo *memberInfoOut) const
-{
- UNIMPLEMENTED();
- return bool();
-}
-
void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode,
GLint components,
diff --git a/src/libANGLE/renderer/vulkan/ProgramVk.h b/src/libANGLE/renderer/vulkan/ProgramVk.h
index e31c9f9..aa382dd 100644
--- a/src/libANGLE/renderer/vulkan/ProgramVk.h
+++ b/src/libANGLE/renderer/vulkan/ProgramVk.h
@@ -94,18 +94,6 @@
// TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
- // May only be called after a successful link operation.
- // Return false for inactive blocks.
- bool getUniformBlockSize(const std::string &blockName,
- const std::string &blockMappedName,
- size_t *sizeOut) const override;
-
- // May only be called after a successful link operation.
- // Returns false for inactive members.
- bool getUniformBlockMemberInfo(const std::string &memberUniformName,
- const std::string &memberUniformMappedName,
- sh::BlockMemberInfo *memberInfoOut) const override;
-
void setPathFragmentInputGen(const std::string &inputName,
GLenum genMode,
GLint components,
diff --git a/src/tests/gl_tests/UniformBufferTest.cpp b/src/tests/gl_tests/UniformBufferTest.cpp
index 05fa369..be525e3 100644
--- a/src/tests/gl_tests/UniformBufferTest.cpp
+++ b/src/tests/gl_tests/UniformBufferTest.cpp
@@ -1156,6 +1156,46 @@
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
+// Tests the detaching shaders from the program and using uniform blocks works.
+// This covers a bug in ANGLE's D3D back-end.
+TEST_P(UniformBufferTest, DetachShaders)
+{
+ GLuint vertexShader = CompileShader(GL_VERTEX_SHADER, mVertexShaderSource);
+ ASSERT_NE(0u, vertexShader);
+ GLuint fragmentShader = CompileShader(GL_FRAGMENT_SHADER, mFragmentShaderSource);
+ ASSERT_NE(0u, fragmentShader);
+
+ GLuint program = glCreateProgram();
+ glAttachShader(program, vertexShader);
+ glAttachShader(program, fragmentShader);
+
+ ASSERT_TRUE(LinkAttachedProgram(program));
+
+ glDetachShader(program, vertexShader);
+ glDetachShader(program, fragmentShader);
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ float floatData[4] = {0.5f, 0.75f, 0.25f, 1.0f};
+
+ glBindBuffer(GL_UNIFORM_BUFFER, mUniformBuffer);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(float) * 4, floatData, GL_STATIC_DRAW);
+
+ glBindBufferBase(GL_UNIFORM_BUFFER, 0, mUniformBuffer);
+
+ GLint uniformBufferIndex = glGetUniformBlockIndex(mProgram, "uni");
+ ASSERT_NE(uniformBufferIndex, -1);
+
+ glUniformBlockBinding(program, uniformBufferIndex, 0);
+ drawQuad(program, "position", 0.5f);
+
+ ASSERT_GL_NO_ERROR();
+ EXPECT_PIXEL_NEAR(0, 0, 128, 191, 64, 255, 1);
+
+ glDeleteProgram(program);
+}
+
// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(UniformBufferTest,
ES3_D3D11(),