Commit 4a3c2341 by Jamie Madill

Program: Clean up UBO info gathering.

The data size & block member info was getting messy, so clean up how we query this from the Impl layer. Also remove the register information from gl::UniformBlock, moving it into the D3D-only world. BUG=angleproject:1172 Change-Id: I40af658ebbd6b7c1a4251906a387ebcbb621cf77 Reviewed-on: https://chromium-review.googlesource.com/304150Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Tryjob-Request: Jamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent e826b9f7
...@@ -639,8 +639,24 @@ std::string ParseUniformName(const std::string &name, size_t *outSubscript) ...@@ -639,8 +639,24 @@ std::string ParseUniformName(const std::string &name, size_t *outSubscript)
return name.substr(0, open); return name.substr(0, open);
} }
unsigned int ParseAndStripArrayIndex(std::string *name)
{
unsigned int subscript = GL_INVALID_INDEX;
// Strip any trailing array operator and retrieve the subscript
size_t open = name->find_last_of('[');
size_t close = name->find_last_of(']');
if (open != std::string::npos && close == name->length() - 1)
{
subscript = atoi(name->c_str() + open + 1);
name->erase(open);
}
return subscript;
} }
} // namespace gl
namespace egl namespace egl
{ {
static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1, static_assert(EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR - EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR == 1,
......
...@@ -68,7 +68,9 @@ bool IsTriangleMode(GLenum drawMode); ...@@ -68,7 +68,9 @@ bool IsTriangleMode(GLenum drawMode);
template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); } template <typename outT> outT iround(GLfloat value) { return static_cast<outT>(value > 0.0f ? floor(value + 0.5f) : ceil(value - 0.5f)); }
template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); } template <typename outT> outT uiround(GLfloat value) { return static_cast<outT>(value + 0.5f); }
} unsigned int ParseAndStripArrayIndex(std::string *name);
} // namespace gl
namespace egl namespace egl
{ {
......
...@@ -26,27 +26,10 @@ ...@@ -26,27 +26,10 @@
namespace gl namespace gl
{ {
const char * const g_fakepath = "C:\\fakepath";
namespace namespace
{ {
unsigned int ParseAndStripArrayIndex(std::string* name)
{
unsigned int subscript = GL_INVALID_INDEX;
// Strip any trailing array operator and retrieve the subscript
size_t open = name->find_last_of('[');
size_t close = name->find_last_of(']');
if (open != std::string::npos && close == name->length() - 1)
{
subscript = atoi(name->substr(open + 1).c_str());
name->erase(open);
}
return subscript;
}
void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var) void WriteShaderVar(BinaryOutputStream *stream, const sh::ShaderVariable &var)
{ {
stream->writeInt(var.type); stream->writeInt(var.type);
...@@ -70,40 +53,6 @@ void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var) ...@@ -70,40 +53,6 @@ void LoadShaderVar(BinaryInputStream *stream, sh::ShaderVariable *var)
var->structName = stream->readString(); var->structName = stream->readString();
} }
template <typename VarT>
void DefineUniformBlockMembers(const std::vector<VarT> &fields,
const std::string &prefix,
int blockIndex,
std::vector<LinkedUniform> *uniformsOut)
{
for (const VarT &field : fields)
{
const std::string &fieldName = (prefix.empty() ? field.name : prefix + "." + field.name);
if (field.isStruct())
{
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
{
const std::string uniformElementName =
fieldName + (field.isArray() ? ArrayString(arrayElement) : "");
DefineUniformBlockMembers(field.fields, uniformElementName, blockIndex,
uniformsOut);
}
}
else
{
// TODO(jmadill): record row-majorness?
// Block layout is recorded in the Impl.
LinkedUniform newUniform(field.type, field.precision, fieldName, field.arraySize,
blockIndex, sh::BlockMemberInfo::getDefaultBlockInfo());
// Since block uniforms have no location, we don't need to store them in the uniform
// locations list.
uniformsOut->push_back(newUniform);
}
}
}
// This simplified cast function doesn't need to worry about advanced concepts like // This simplified cast function doesn't need to worry about advanced concepts like
// depth range values, or casting to bool. // depth range values, or casting to bool.
template <typename DestT, typename SrcT> template <typename DestT, typename SrcT>
...@@ -187,6 +136,8 @@ bool UniformInList(const std::vector<LinkedUniform> &list, const std::string &na ...@@ -187,6 +136,8 @@ bool UniformInList(const std::vector<LinkedUniform> &list, const std::string &na
} // anonymous namespace } // anonymous namespace
const char *const g_fakepath = "C:\\fakepath";
AttributeBindings::AttributeBindings() AttributeBindings::AttributeBindings()
{ {
} }
...@@ -521,7 +472,7 @@ Error Program::link(const gl::Data &data) ...@@ -521,7 +472,7 @@ Error Program::link(const gl::Data &data)
} }
gatherTransformFeedbackVaryings(mergedVaryings); gatherTransformFeedbackVaryings(mergedVaryings);
mProgram->gatherUniformBlockInfo(&mData.mUniformBlocks, &mData.mUniforms); gatherInterfaceBlockInfo();
mLinked = true; mLinked = true;
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
...@@ -670,10 +621,6 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt ...@@ -670,10 +621,6 @@ Error Program::loadBinary(GLenum binaryFormat, const void *binary, GLsizei lengt
uniformBlock.memberUniformIndexes.push_back(stream.readInt<unsigned int>()); uniformBlock.memberUniformIndexes.push_back(stream.readInt<unsigned int>());
} }
// TODO(jmadill): Make D3D-only
stream.readInt(&uniformBlock.psRegisterIndex);
stream.readInt(&uniformBlock.vsRegisterIndex);
mData.mUniformBlocks.push_back(uniformBlock); mData.mUniformBlocks.push_back(uniformBlock);
} }
...@@ -764,10 +711,6 @@ Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, G ...@@ -764,10 +711,6 @@ Error Program::saveBinary(GLenum *binaryFormat, void *binary, GLsizei bufSize, G
{ {
stream.writeInt(memberUniformIndex); stream.writeInt(memberUniformIndex);
} }
// TODO(jmadill): make D3D-only
stream.writeInt(uniformBlock.psRegisterIndex);
stream.writeInt(uniformBlock.vsRegisterIndex);
} }
stream.writeInt(mData.mTransformFeedbackBufferMode); stream.writeInt(mData.mTransformFeedbackBufferMode);
...@@ -1894,8 +1837,6 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps) ...@@ -1894,8 +1837,6 @@ bool Program::linkUniformBlocks(InfoLog &infoLog, const Caps &caps)
} }
} }
gatherInterfaceBlockInfo();
return true; return true;
} }
...@@ -2334,11 +2275,58 @@ void Program::gatherInterfaceBlockInfo() ...@@ -2334,11 +2275,58 @@ void Program::gatherInterfaceBlockInfo()
} }
} }
template <typename VarT>
void Program::defineUniformBlockMembers(const std::vector<VarT> &fields,
const std::string &prefix,
int blockIndex)
{
for (const VarT &field : fields)
{
const std::string &fullName = (prefix.empty() ? field.name : prefix + "." + field.name);
if (field.isStruct())
{
for (unsigned int arrayElement = 0; arrayElement < field.elementCount(); arrayElement++)
{
const std::string uniformElementName =
fullName + (field.isArray() ? ArrayString(arrayElement) : "");
defineUniformBlockMembers(field.fields, uniformElementName, blockIndex);
}
}
else
{
// If getBlockMemberInfo returns false, the uniform is optimized out.
sh::BlockMemberInfo memberInfo;
if (!mProgram->getUniformBlockMemberInfo(fullName, &memberInfo))
{
continue;
}
LinkedUniform newUniform(field.type, field.precision, fullName, field.arraySize,
blockIndex, memberInfo);
// Since block uniforms have no location, we don't need to store them in the uniform
// locations list.
mData.mUniforms.push_back(newUniform);
}
}
}
void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType) void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType)
{ {
int blockIndex = static_cast<int>(mData.mUniformBlocks.size()); int blockIndex = static_cast<int>(mData.mUniformBlocks.size());
size_t blockSize = 0;
// Don't define this block at all if it's not active in the implementation.
if (!mProgram->getUniformBlockSize(interfaceBlock.name, &blockSize))
{
return;
}
// Track the first and last uniform index to determine the range of active uniforms in the
// block.
size_t firstBlockUniformIndex = mData.mUniforms.size(); size_t firstBlockUniformIndex = mData.mUniforms.size();
DefineUniformBlockMembers(interfaceBlock.fields, "", blockIndex, &mData.mUniforms); defineUniformBlockMembers(interfaceBlock.fields, "", blockIndex);
size_t lastBlockUniformIndex = mData.mUniforms.size(); size_t lastBlockUniformIndex = mData.mUniforms.size();
std::vector<unsigned int> blockUniformIndexes; std::vector<unsigned int> blockUniformIndexes;
...@@ -2365,6 +2353,15 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu ...@@ -2365,6 +2353,15 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu
block.fragmentStaticUse = interfaceBlock.staticUse; block.fragmentStaticUse = interfaceBlock.staticUse;
} }
// TODO(jmadill): Determine if we can ever have an inactive array element block.
size_t blockElementSize = 0;
if (!mProgram->getUniformBlockSize(block.nameWithArrayIndex(), &blockElementSize))
{
continue;
}
ASSERT(blockElementSize == blockSize);
block.dataSize = static_cast<unsigned int>(blockElementSize);
mData.mUniformBlocks.push_back(block); mData.mUniformBlocks.push_back(block);
} }
} }
...@@ -2383,6 +2380,7 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu ...@@ -2383,6 +2380,7 @@ void Program::defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenu
block.fragmentStaticUse = interfaceBlock.staticUse; block.fragmentStaticUse = interfaceBlock.staticUse;
} }
block.dataSize = static_cast<unsigned int>(blockSize);
mData.mUniformBlocks.push_back(block); mData.mUniformBlocks.push_back(block);
} }
} }
......
...@@ -405,6 +405,11 @@ class Program : angle::NonCopyable ...@@ -405,6 +405,11 @@ class Program : angle::NonCopyable
std::vector<LinkedUniform> *samplerUniforms); std::vector<LinkedUniform> *samplerUniforms);
void gatherInterfaceBlockInfo(); void gatherInterfaceBlockInfo();
template <typename VarT>
void defineUniformBlockMembers(const std::vector<VarT> &fields,
const std::string &prefix,
int blockIndex);
void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType); void defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, GLenum shaderType);
template <typename T> template <typename T>
......
...@@ -121,13 +121,7 @@ const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const ...@@ -121,13 +121,7 @@ const uint8_t *LinkedUniform::getDataPtrToElement(size_t elementIndex) const
} }
UniformBlock::UniformBlock() UniformBlock::UniformBlock()
: isArray(false), : isArray(false), arrayElement(0), dataSize(0), vertexStaticUse(false), fragmentStaticUse(false)
arrayElement(0),
dataSize(0),
vertexStaticUse(false),
fragmentStaticUse(false),
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX)
{ {
} }
...@@ -137,10 +131,19 @@ UniformBlock::UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned i ...@@ -137,10 +131,19 @@ UniformBlock::UniformBlock(const std::string &nameIn, bool isArrayIn, unsigned i
arrayElement(arrayElementIn), arrayElement(arrayElementIn),
dataSize(0), dataSize(0),
vertexStaticUse(false), vertexStaticUse(false),
fragmentStaticUse(false), fragmentStaticUse(false)
psRegisterIndex(GL_INVALID_INDEX),
vsRegisterIndex(GL_INVALID_INDEX)
{ {
} }
std::string UniformBlock::nameWithArrayIndex() const
{
std::stringstream fullNameStr;
fullNameStr << name;
if (isArray)
{
fullNameStr << "[" << arrayElement << "]";
}
return fullNameStr.str();
}
} }
...@@ -54,6 +54,8 @@ struct UniformBlock ...@@ -54,6 +54,8 @@ struct UniformBlock
UniformBlock(const UniformBlock &other) = default; UniformBlock(const UniformBlock &other) = default;
UniformBlock &operator=(const UniformBlock &other) = default; UniformBlock &operator=(const UniformBlock &other) = default;
std::string nameWithArrayIndex() const;
std::string name; std::string name;
bool isArray; bool isArray;
unsigned int arrayElement; unsigned int arrayElement;
...@@ -63,10 +65,6 @@ struct UniformBlock ...@@ -63,10 +65,6 @@ struct UniformBlock
bool fragmentStaticUse; bool fragmentStaticUse;
std::vector<unsigned int> memberUniformIndexes; std::vector<unsigned int> memberUniformIndexes;
// TODO(jmadill): Make D3D-only.
unsigned int psRegisterIndex;
unsigned int vsRegisterIndex;
}; };
} }
......
...@@ -66,9 +66,14 @@ class ProgramImpl : angle::NonCopyable ...@@ -66,9 +66,14 @@ 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;
// Gather uniform block active uniform indices, and uniform block offset info. // May only be called after a successful link operation.
virtual void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks, // Return false for inactive blocks.
std::vector<gl::LinkedUniform> *uniforms) = 0; virtual bool getUniformBlockSize(const std::string &blockName, 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,
sh::BlockMemberInfo *memberInfoOut) const = 0;
protected: protected:
const gl::Program::Data &mData; const gl::Program::Data &mData;
......
...@@ -68,6 +68,18 @@ struct D3DUniform : angle::NonCopyable ...@@ -68,6 +68,18 @@ struct D3DUniform : angle::NonCopyable
unsigned int registerElement; unsigned int registerElement;
}; };
struct D3DUniformBlock
{
D3DUniformBlock() : vsRegisterIndex(GL_INVALID_INDEX), psRegisterIndex(GL_INVALID_INDEX) {}
bool vertexStaticUse() const { return vsRegisterIndex != GL_INVALID_INDEX; }
bool fragmentStaticUse() const { return psRegisterIndex != GL_INVALID_INDEX; }
unsigned int vsRegisterIndex;
unsigned int psRegisterIndex;
};
class ProgramD3D : public ProgramImpl class ProgramD3D : public ProgramImpl
{ {
public: public:
...@@ -99,8 +111,9 @@ class ProgramD3D : public ProgramImpl ...@@ -99,8 +111,9 @@ class ProgramD3D : public ProgramImpl
LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override; LinkResult link(const gl::Data &data, gl::InfoLog &infoLog) override;
GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override; GLboolean validate(const gl::Caps &caps, gl::InfoLog *infoLog) override;
void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks, bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override;
std::vector<gl::LinkedUniform> *uniforms) override; bool getUniformBlockMemberInfo(const std::string &memberUniformName,
sh::BlockMemberInfo *memberInfoOut) const override;
void initializeUniformStorage(); void initializeUniformStorage();
gl::Error applyUniforms(); gl::Error applyUniforms();
...@@ -197,7 +210,6 @@ class ProgramD3D : public ProgramImpl ...@@ -197,7 +210,6 @@ class ProgramD3D : public ProgramImpl
}; };
typedef std::map<std::string, D3DUniform *> D3DUniformMap; typedef std::map<std::string, D3DUniform *> D3DUniformMap;
typedef std::map<std::string, sh::BlockMemberInfo> BlockInfoMap;
void defineUniformsAndAssignRegisters(); void defineUniformsAndAssignRegisters();
void defineUniformBase(const gl::Shader *shader, void defineUniformBase(const gl::Shader *shader,
...@@ -217,8 +229,6 @@ class ProgramD3D : public ProgramImpl ...@@ -217,8 +229,6 @@ class ProgramD3D : public ProgramImpl
std::vector<Sampler> &outSamplers, std::vector<Sampler> &outSamplers,
GLuint *outUsedRange); GLuint *outUsedRange);
size_t defineUniformBlock(const sh::InterfaceBlock &interfaceBlock, BlockInfoMap *blockInfoOut);
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);
...@@ -237,6 +247,10 @@ class ProgramD3D : public ProgramImpl ...@@ -237,6 +247,10 @@ class ProgramD3D : public ProgramImpl
void initAttributesByLayout(); void initAttributesByLayout();
void reset(); void reset();
void assignUniformBlockRegisters();
void initUniformBlockInfo();
size_t getUniformBlockInfo(const sh::InterfaceBlock &interfaceBlock);
RendererD3D *mRenderer; RendererD3D *mRenderer;
DynamicHLSL *mDynamicHLSL; DynamicHLSL *mDynamicHLSL;
...@@ -279,6 +293,10 @@ class ProgramD3D : public ProgramImpl ...@@ -279,6 +293,10 @@ class ProgramD3D : public ProgramImpl
std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings; std::vector<gl::LinkedVarying> mTransformFeedbackLinkedVaryings;
std::vector<D3DUniform *> mD3DUniforms; std::vector<D3DUniform *> mD3DUniforms;
std::vector<D3DUniformBlock> mD3DUniformBlocks;
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;
......
...@@ -289,13 +289,29 @@ void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean t ...@@ -289,13 +289,29 @@ void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean t
void ProgramGL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) void ProgramGL::setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{ {
mFunctions->uniformBlockBinding(mProgramID, mUniformBlockRealLocationMap[uniformBlockIndex], // Lazy init
uniformBlockBinding); if (mUniformBlockRealLocationMap.empty())
{
mUniformBlockRealLocationMap.reserve(mData.getUniformBlocks().size());
for (const gl::UniformBlock &uniformBlock : mData.getUniformBlocks())
{
const std::string &nameWithIndex = uniformBlock.nameWithArrayIndex();
GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, nameWithIndex.c_str());
mUniformBlockRealLocationMap.push_back(blockIndex);
}
}
GLuint realBlockIndex = mUniformBlockRealLocationMap[uniformBlockIndex];
if (realBlockIndex != GL_INVALID_INDEX)
{
mFunctions->uniformBlockBinding(mProgramID, realBlockIndex, uniformBlockBinding);
}
} }
void ProgramGL::reset() void ProgramGL::reset()
{ {
mUniformRealLocationMap.clear(); mUniformRealLocationMap.clear();
mUniformBlockRealLocationMap.clear();
mSamplerBindings.clear(); mSamplerBindings.clear();
mUniformIndexToSamplerIndex.clear(); mUniformIndexToSamplerIndex.clear();
} }
...@@ -310,105 +326,50 @@ const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() cons ...@@ -310,105 +326,50 @@ const std::vector<SamplerBindingGL> &ProgramGL::getAppliedSamplerUniforms() cons
return mSamplerBindings; return mSamplerBindings;
} }
void ProgramGL::gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks, bool ProgramGL::getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const
std::vector<gl::LinkedUniform> *uniforms)
{ {
mUniformBlockRealLocationMap.resize(uniformBlocks->size(), 0); ASSERT(mProgramID != 0u);
for (int i = 0; i < static_cast<int>(uniformBlocks->size()); i++) GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, blockName.c_str());
if (blockIndex == GL_INVALID_INDEX)
{ {
auto &uniformBlock = uniformBlocks->at(i); *sizeOut = 0;
return false;
std::stringstream fullNameStr;
fullNameStr << uniformBlock.name;
if (uniformBlock.isArray)
{
fullNameStr << "[" << uniformBlock.arrayElement << "]";
}
GLuint blockIndex = mFunctions->getUniformBlockIndex(mProgramID, fullNameStr.str().c_str());
if (blockIndex != GL_INVALID_INDEX)
{
mUniformBlockRealLocationMap[i] = blockIndex;
GLint dataSize = 0;
mFunctions->getActiveUniformBlockiv(mProgramID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
&dataSize);
uniformBlock.dataSize = dataSize;
}
else
{
// Remove this uniform block
uniformBlocks->erase(uniformBlocks->begin() + i);
i--;
}
} }
for (int uniformIdx = 0; uniformIdx < static_cast<int>(uniforms->size()); uniformIdx++) GLint dataSize = 0;
{ mFunctions->getActiveUniformBlockiv(mProgramID, blockIndex, GL_UNIFORM_BLOCK_DATA_SIZE,
auto &uniform = uniforms->at(uniformIdx); &dataSize);
if (uniform.isInDefaultBlock()) *sizeOut = static_cast<size_t>(dataSize);
{ return true;
continue; }
}
const GLchar *uniformName = uniform.name.c_str(); bool ProgramGL::getUniformBlockMemberInfo(const std::string &memberUniformName,
GLuint uniformIndex = 0; sh::BlockMemberInfo *memberInfoOut) const
mFunctions->getUniformIndices(mProgramID, 1, &uniformName, &uniformIndex); {
GLuint uniformIndex;
const GLchar *memberNameGLStr = memberUniformName.c_str();
mFunctions->getUniformIndices(mProgramID, 1, &memberNameGLStr, &uniformIndex);
if (uniformIndex == GL_INVALID_INDEX) if (uniformIndex == GL_INVALID_INDEX)
{ {
// Uniform member has been optimized out, remove it from the list *memberInfoOut = sh::BlockMemberInfo::getDefaultBlockInfo();
// TODO: Clean this up by using a class to wrap around the uniforms so manual removal is return false;
// not needed.
for (size_t uniformBlockIdx = 0; uniformBlockIdx < uniformBlocks->size();
uniformBlockIdx++)
{
auto &uniformBlock = uniformBlocks->at(uniformBlockIdx);
for (int memberIndex = 0;
memberIndex < static_cast<int>(uniformBlock.memberUniformIndexes.size());
memberIndex++)
{
if (uniformBlock.memberUniformIndexes[memberIndex] ==
static_cast<unsigned int>(uniformIdx))
{
uniformBlock.memberUniformIndexes.erase(
uniformBlock.memberUniformIndexes.begin() + memberIndex);
memberIndex--;
}
else if (uniformBlock.memberUniformIndexes[memberIndex] >
static_cast<unsigned int>(uniformIdx))
{
uniformBlock.memberUniformIndexes[memberIndex]--;
}
}
}
uniforms->erase(uniforms->begin() + uniformIdx);
uniformIdx--;
}
else
{
GLint offset = 0;
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_OFFSET,
&offset);
uniform.blockInfo.offset = offset;
GLint arrayStride = 0;
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE,
&arrayStride);
uniform.blockInfo.arrayStride = arrayStride;
GLint matrixStride = 0;
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE,
&matrixStride);
uniform.blockInfo.matrixStride = matrixStride;
// TODO: determine this at the gl::Program level.
GLint isRowMajorMatrix = 0;
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
&isRowMajorMatrix);
uniform.blockInfo.isRowMajorMatrix = isRowMajorMatrix != GL_FALSE;
}
} }
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_OFFSET,
&memberInfoOut->offset);
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_ARRAY_STRIDE,
&memberInfoOut->arrayStride);
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_MATRIX_STRIDE,
&memberInfoOut->matrixStride);
// TODO(jmadill): possibly determine this at the gl::Program level.
GLint isRowMajorMatrix = 0;
mFunctions->getActiveUniformsiv(mProgramID, 1, &uniformIndex, GL_UNIFORM_IS_ROW_MAJOR,
&isRowMajorMatrix);
memberInfoOut->isRowMajorMatrix = isRowMajorMatrix != GL_FALSE;
return true;
} }
}
} // namespace rx
...@@ -61,8 +61,9 @@ class ProgramGL : public ProgramImpl ...@@ -61,8 +61,9 @@ class ProgramGL : public ProgramImpl
void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override; void setUniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) override;
void gatherUniformBlockInfo(std::vector<gl::UniformBlock> *uniformBlocks, bool getUniformBlockSize(const std::string &blockName, size_t *sizeOut) const override;
std::vector<gl::LinkedUniform> *uniforms) override; bool getUniformBlockMemberInfo(const std::string &memberUniformName,
sh::BlockMemberInfo *memberInfoOut) const override;
GLuint getProgramID() const; GLuint getProgramID() const;
const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const; const std::vector<SamplerBindingGL> &getAppliedSamplerUniforms() const;
......
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