Commit 6db1c2e8 by Jamie Madill

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/753521Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 8f8edd6e
...@@ -871,7 +871,7 @@ Error Program::link(const gl::Context *context) ...@@ -871,7 +871,7 @@ Error Program::link(const gl::Context *context)
} }
gatherAtomicCounterBuffers(); gatherAtomicCounterBuffers();
gatherInterfaceBlockInfo(context); initInterfaceBlockBindings();
setUniformValuesFromBindingQualifiers(); setUniformValuesFromBindingQualifiers();
...@@ -2874,55 +2874,8 @@ void Program::gatherAtomicCounterBuffers() ...@@ -2874,55 +2874,8 @@ void Program::gatherAtomicCounterBuffers()
// TODO(jie.a.chen@intel.com): Get the actual BUFFER_DATA_SIZE from backend for each buffer. // 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. // Set initial bindings from shader.
for (unsigned int blockIndex = 0; blockIndex < mState.mUniformBlocks.size(); blockIndex++) for (unsigned int blockIndex = 0; blockIndex < mState.mUniformBlocks.size(); blockIndex++)
{ {
......
...@@ -640,9 +640,7 @@ class Program final : angle::NonCopyable, public LabeledObject ...@@ -640,9 +640,7 @@ class Program final : angle::NonCopyable, public LabeledObject
void setUniformValuesFromBindingQualifiers(); void setUniformValuesFromBindingQualifiers();
void gatherAtomicCounterBuffers(); void gatherAtomicCounterBuffers();
void gatherUniformBlockInfo(const gl::Context *context); void initInterfaceBlockBindings();
void gatherShaderStorageBlockInfo(const gl::Context *context);
void gatherInterfaceBlockInfo(const Context *context);
// Both these function update the cached uniform values and return a modified "count" // Both these function update the cached uniform values and return a modified "count"
// so that the uniform update doesn't overflow the uniform. // so that the uniform update doesn't overflow the uniform.
......
...@@ -637,6 +637,8 @@ void InterfaceBlockLinker::addShaderBlocks(GLenum shader, ...@@ -637,6 +637,8 @@ void InterfaceBlockLinker::addShaderBlocks(GLenum shader,
void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize, void InterfaceBlockLinker::linkBlocks(const GetBlockSize &getBlockSize,
const GetBlockMemberInfo &getMemberInfo) const const GetBlockMemberInfo &getMemberInfo) const
{ {
ASSERT(mBlocksOut->empty());
std::set<std::string> visitedList; std::set<std::string> visitedList;
for (const auto &shaderBlocks : mShaderBlocks) for (const auto &shaderBlocks : mShaderBlocks)
......
...@@ -83,17 +83,6 @@ class ProgramImpl : angle::NonCopyable ...@@ -83,17 +83,6 @@ class ProgramImpl : angle::NonCopyable
// TODO: synchronize in syncState when dirty bits exist. // TODO: synchronize in syncState when dirty bits exist.
virtual void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) = 0; 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 // CHROMIUM_path_rendering
// Set parameters to control fragment shader input variable interpolation // Set parameters to control fragment shader input variable interpolation
virtual void setPathFragmentInputGen(const std::string &inputName, virtual void setPathFragmentInputGen(const std::string &inputName,
......
...@@ -63,10 +63,6 @@ class MockProgramImpl : public rx::ProgramImpl ...@@ -63,10 +63,6 @@ class MockProgramImpl : public rx::ProgramImpl
MOCK_CONST_METHOD3(getUniformuiv, void(const gl::Context *, GLint, GLuint *)); MOCK_CONST_METHOD3(getUniformuiv, void(const gl::Context *, GLint, GLuint *));
MOCK_METHOD2(setUniformBlockBinding, void(GLuint, 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, MOCK_METHOD4(setPathFragmentInputGen,
void(const std::string &, GLenum, GLint, const GLfloat *)); void(const std::string &, GLenum, GLint, const GLfloat *));
......
...@@ -199,6 +199,97 @@ void GetMatrixUniform(GLint columns, GLint rows, NonFloatT *dataOut, const NonFl ...@@ -199,6 +199,97 @@ void GetMatrixUniform(GLint columns, GLint rows, NonFloatT *dataOut, const NonFl
UNREACHABLE(); 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 } // anonymous namespace
// D3DUniform Implementation // D3DUniform Implementation
...@@ -1028,10 +1119,6 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream ...@@ -1028,10 +1119,6 @@ void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream
stream->writeInt(uniform->registerElement); stream->writeInt(uniform->registerElement);
} }
// Ensure we init the uniform block structure data if we should.
// http://anglebug.com/1637
ensureUniformBlocksInitialized();
stream->writeInt(mD3DUniformBlocks.size()); stream->writeInt(mD3DUniformBlocks.size());
for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks) for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
{ {
...@@ -1505,8 +1592,6 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1505,8 +1592,6 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
infoLog << "Failed to create D3D compute shader."; infoLog << "Failed to create D3D compute shader.";
return result; return result;
} }
initUniformBlockInfo(context, computeShader);
} }
else else
{ {
...@@ -1582,11 +1667,10 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context, ...@@ -1582,11 +1667,10 @@ gl::LinkResult ProgramD3D::link(const gl::Context *context,
infoLog << "Failed to create D3D shaders."; infoLog << "Failed to create D3D shaders.";
return result; return result;
} }
initUniformBlockInfo(context, vertexShader);
initUniformBlockInfo(context, fragmentShader);
} }
linkResources(context, resources);
return true; return true;
} }
...@@ -1596,29 +1680,15 @@ GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLo ...@@ -1596,29 +1680,15 @@ GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLo
return GL_TRUE; 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 (mState.getUniformBlocks().empty())
{
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())
{ {
return; return;
} }
ASSERT(mD3DUniformBlocks.empty());
// Assign registers and update sizes. // Assign registers and update sizes.
const ShaderD3D *vertexShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedVertexShader()); const ShaderD3D *vertexShaderD3D = SafeGetImplAs<ShaderD3D>(mState.getAttachedVertexShader());
const ShaderD3D *fragmentShaderD3D = const ShaderD3D *fragmentShaderD3D =
...@@ -1731,8 +1801,6 @@ void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps, ...@@ -1731,8 +1801,6 @@ void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps,
return; return;
} }
ensureUniformBlocksInitialized();
mVertexUBOCache.clear(); mVertexUBOCache.clear();
mFragmentUBOCache.clear(); mFragmentUBOCache.clear();
...@@ -2278,30 +2346,6 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location, ...@@ -2278,30 +2346,6 @@ void ProgramD3D::setUniformMatrixfvInternal(GLint location,
} }
} }
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() void ProgramD3D::assignAllSamplerRegisters()
{ {
for (D3DUniform *d3dUniform : mD3DUniforms) for (D3DUniform *d3dUniform : mD3DUniforms)
...@@ -2595,40 +2639,6 @@ const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const ...@@ -2595,40 +2639,6 @@ const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const
return mD3DUniforms[mState.getUniformLocations()[location].index]; 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, void ProgramD3D::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
...@@ -2720,4 +2730,56 @@ void ProgramD3D::updateCachedPixelExecutableIndex() ...@@ -2720,4 +2730,56 @@ void ProgramD3D::updateCachedPixelExecutableIndex()
} }
} }
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 } // namespace rx
...@@ -196,12 +196,6 @@ class ProgramD3D : public ProgramImpl ...@@ -196,12 +196,6 @@ class ProgramD3D : public ProgramImpl
gl::InfoLog &infoLog) override; gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, 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, void setPathFragmentInputGen(const std::string &inputName,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
...@@ -428,16 +422,15 @@ class ProgramD3D : public ProgramImpl ...@@ -428,16 +422,15 @@ class ProgramD3D : public ProgramImpl
void initAttribLocationsToD3DSemantic(const gl::Context *context); void initAttribLocationsToD3DSemantic(const gl::Context *context);
void reset(); void reset();
void ensureUniformBlocksInitialized(); void initializeUniformBlocks();
void initUniformBlockInfo(const gl::Context *context, gl::Shader *shader);
size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock);
void updateCachedInputLayoutFromShader(const gl::Context *context); void updateCachedInputLayoutFromShader(const gl::Context *context);
void updateCachedOutputLayoutFromShader(); void updateCachedOutputLayoutFromShader();
void updateCachedVertexExecutableIndex(); void updateCachedVertexExecutableIndex();
void updateCachedPixelExecutableIndex(); void updateCachedPixelExecutableIndex();
void linkResources(const gl::Context *context, const gl::ProgramLinkedResources &resources);
RendererD3D *mRenderer; RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL; DynamicHLSL *mDynamicHLSL;
...@@ -498,9 +491,6 @@ class ProgramD3D : public ProgramImpl ...@@ -498,9 +491,6 @@ class ProgramD3D : public ProgramImpl
bool mFragmentUniformsDirty; bool mFragmentUniformsDirty;
bool mComputeUniformsDirty; bool mComputeUniformsDirty;
std::map<std::string, sh::BlockMemberInfo> mBlockInfo;
std::map<std::string, size_t> mBlockDataSizes;
static unsigned int issueSerial(); static unsigned int issueSerial();
static unsigned int mCurrentSerial; static unsigned int mCurrentSerial;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "common/string_utils.h" #include "common/string_utils.h"
#include "common/utilities.h" #include "common/utilities.h"
#include "libANGLE/Context.h" #include "libANGLE/Context.h"
#include "libANGLE/ProgramLinkedResources.h"
#include "libANGLE/Uniform.h" #include "libANGLE/Uniform.h"
#include "libANGLE/renderer/gl/ContextGL.h" #include "libANGLE/renderer/gl/ContextGL.h"
#include "libANGLE/renderer/gl/FunctionsGL.h" #include "libANGLE/renderer/gl/FunctionsGL.h"
...@@ -212,6 +213,7 @@ gl::LinkResult ProgramGL::link(const gl::Context *context, ...@@ -212,6 +213,7 @@ gl::LinkResult ProgramGL::link(const gl::Context *context,
mStateManager->forceUseProgram(mProgramID); mStateManager->forceUseProgram(mProgramID);
} }
linkResources(resources);
postLink(); postLink();
return true; return true;
...@@ -805,4 +807,35 @@ void ProgramGL::markUnusedUniformLocations(std::vector<gl::VariableLocation> *un ...@@ -805,4 +807,35 @@ void ProgramGL::markUnusedUniformLocations(std::vector<gl::VariableLocation> *un
} }
} }
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 } // namespace rx
...@@ -71,13 +71,6 @@ class ProgramGL : public ProgramImpl ...@@ -71,13 +71,6 @@ class ProgramGL : public ProgramImpl
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; 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, void setPathFragmentInputGen(const std::string &inputName,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
...@@ -97,6 +90,14 @@ class ProgramGL : public ProgramImpl ...@@ -97,6 +90,14 @@ class ProgramGL : public ProgramImpl
void postLink(); void postLink();
void reapplyUBOBindingsIfNeeded(const gl::Context *context); 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. // Helper function, makes it simpler to type.
GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; } GLint uniLoc(GLint glLocation) const { return mUniformRealLocationMap[glLocation]; }
......
...@@ -183,23 +183,6 @@ void ProgramNULL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint unifor ...@@ -183,23 +183,6 @@ void ProgramNULL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint unifor
{ {
} }
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, void ProgramNULL::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
......
...@@ -89,17 +89,6 @@ class ProgramNULL : public ProgramImpl ...@@ -89,17 +89,6 @@ class ProgramNULL : public ProgramImpl
// TODO: synchronize in syncState when dirty bits exist. // TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; 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 // CHROMIUM_path_rendering
// Set parameters to control fragment shader input variable interpolation // Set parameters to control fragment shader input variable interpolation
void setPathFragmentInputGen(const std::string &inputName, void setPathFragmentInputGen(const std::string &inputName,
......
...@@ -528,22 +528,6 @@ void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformB ...@@ -528,22 +528,6 @@ void ProgramVk::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformB
UNIMPLEMENTED(); 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, void ProgramVk::setPathFragmentInputGen(const std::string &inputName,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
......
...@@ -94,18 +94,6 @@ class ProgramVk : public ProgramImpl ...@@ -94,18 +94,6 @@ class ProgramVk : public ProgramImpl
// TODO: synchronize in syncState when dirty bits exist. // TODO: synchronize in syncState when dirty bits exist.
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; 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, void setPathFragmentInputGen(const std::string &inputName,
GLenum genMode, GLenum genMode,
GLint components, GLint components,
......
...@@ -1156,6 +1156,46 @@ TEST_P(UniformBufferTest, Std140UniformBlockInstanceWithNestedStructsContainingV ...@@ -1156,6 +1156,46 @@ TEST_P(UniformBufferTest, Std140UniformBlockInstanceWithNestedStructsContainingV
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); 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. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(UniformBufferTest, ANGLE_INSTANTIATE_TEST(UniformBufferTest,
ES3_D3D11(), ES3_D3D11(),
......
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