Commit 86db89b0 authored by Philip Trettner's avatar Philip Trettner

Merge branch 'feature/fix-uniform-names' into 'develop'

Fix uniform access and warnings for arrays and UBOs

Closes #105

See merge request !32
parents a045f0cc 103c2f99
......@@ -151,6 +151,21 @@ GLint Program::useUniformLocationAndVerify(const std::string& name, GLint size,
{
auto info = getUniformInfo(name);
if (!info)
{
// This uniform might be missing from the cache because it's name is formatted differently
// by the user, vs the output from glGetActiveUniform that was used to build the cache.
// Retry with glGetUniformLocation
auto loc = glGetUniformLocation(mObjectName, name.c_str());
if (loc != -1)
{
mUniformCache.emplace_back(name, loc, size, type);
info = &mUniformCache.back();
}
}
if (info)
{
if (info->size != size || info->type != type)
......@@ -417,20 +432,70 @@ void Program::link(bool saveUniformState)
mUniformCache.clear();
GLint cnt;
glGetProgramiv(mObjectName, GL_ACTIVE_UNIFORMS, &cnt);
mUniformCache.reserve(size_t(cnt));
// Receive all indices of uniforms that are inside uniform blocks (and thus do not need to get cached)
auto constexpr maxUboUniformIndices = 2048;
std::array<GLint, maxUboUniformIndices> uboUniformIndices;
size_t numUboUniformIndices = 0;
{
GLint activeUniformBlocks;
glGetProgramiv(mObjectName, GL_ACTIVE_UNIFORM_BLOCKS, &activeUniformBlocks);
for (auto i = 0; i < activeUniformBlocks; ++i)
{
GLint numUboParameters;
glGetActiveUniformBlockiv(mObjectName, GLuint(i), GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &numUboParameters);
// Skip empty UBOs
if (numUboParameters <= 0)
continue;
if (numUboUniformIndices + GLuint(numUboParameters) >= maxUboUniformIndices)
{
// The indices buffer would overflow, stop caching
glow::warning() << "Shader UBOs contains high number of UBO parameters, exceeding cache size " << to_string(this);
glow::warning() << "False-positive unchanged uniform warnings might follow";
break;
}
// Write the indices into the buffer
glGetActiveUniformBlockiv(mObjectName, GLuint(i), GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, &uboUniformIndices[numUboUniformIndices]);
numUboUniformIndices += GLuint(numUboParameters);
}
}
GLchar uniformName[2048];
for (auto i = 0; i < cnt; ++i)
{
// Skip this uniform if it is part of a UBO
{
bool uniformIsInUbo = false;
for (auto j = 0u; j < numUboUniformIndices; ++j)
{
if (i == uboUniformIndices[j])
{
uniformIsInUbo = true;
break;
}
}
if (uniformIsInUbo)
continue;
}
GLsizei length;
GLint size;
GLenum type;
glGetActiveUniform(mObjectName, i, sizeof(uniformName), &length, &size, &type, uniformName);
UniformInfo info;
info.location = glGetUniformLocation(mObjectName, uniformName);
info.name = uniformName;
info.size = size;
info.type = type;
mUniformCache.push_back(info);
glGetActiveUniform(mObjectName, GLuint(i), sizeof(uniformName), &length, &size, &type, uniformName);
std::string uniformNameStd = uniformName;
// Cut down uArray[0] to uArray
auto const bracketPos = uniformNameStd.find('[');
if (bracketPos != std::string::npos)
uniformNameStd = uniformNameStd.substr(0, bracketPos);
mUniformCache.emplace_back(uniformNameStd, glGetUniformLocation(mObjectName, uniformNameStd.c_str()), size, type);
}
// restore uniforms
......@@ -460,10 +525,8 @@ void Program::checkUnchangedUniforms()
return; // warning disabled
for (auto const& info : mUniformCache)
if (!info.wasSet //
&& !isImageUniform(info.type) // not an image
&& info.name.find('[') == std::string::npos // not an array
&& info.name.find('.') == std::string::npos // not an UBO
if (!info.wasSet //
&& !isImageUniform(info.type) // not an image
)
{
warning() << "Uniform `" << info.name << "' is used in the shader but was not set via GLOW. " << to_string(this);
......
......@@ -45,6 +45,12 @@ public:
GLint size = -1;
GLenum type = GL_INVALID_ENUM;
bool wasSet = false;
UniformInfo() = default;
UniformInfo(std::string const& name, GLint location, GLint size, GLenum type)
: name(name), location(location), size(size), type(type), wasSet(false)
{
}
};
private:
......
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