mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-01 04:10:58 +00:00
Fix handling of multi-dimensional arrays in GL uniforms
This commit is contained in:
@@ -1908,6 +1908,11 @@ void GLReplay::FillCBufferVariables(GLuint prog, bool bufferBacked, std::string
|
||||
{
|
||||
const ShaderVariableDescriptor &desc = variables[i].type.descriptor;
|
||||
|
||||
// remove implicit '.' for recursing through "structs" if it's actually a multi-dimensional
|
||||
// array.
|
||||
if(!prefix.empty() && prefix.back() == '.' && variables[i].name[0] == '[')
|
||||
prefix.pop_back();
|
||||
|
||||
ShaderVariable var;
|
||||
var.name = variables[i].name;
|
||||
var.rows = desc.rows;
|
||||
@@ -1985,7 +1990,12 @@ void GLReplay::FillCBufferVariables(GLuint prog, bool bufferBacked, std::string
|
||||
for(uint32_t a = 0; a < desc.elements; a++)
|
||||
{
|
||||
ShaderVariable el = var;
|
||||
el.name = StringFormat::Fmt("%s[%u]", var.name.c_str(), a);
|
||||
|
||||
// if this is the last part of a multidimensional array, don't include the variable name
|
||||
if(var.name[0] != '[')
|
||||
el.name = StringFormat::Fmt("%s[%u]", var.name.c_str(), a);
|
||||
else
|
||||
el.name = StringFormat::Fmt("[%u]", a);
|
||||
|
||||
FillCBufferValue(prog, bufferBacked, values[0] + values[2] * a, values[1], data, el);
|
||||
|
||||
|
||||
@@ -751,6 +751,9 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
|
||||
|
||||
char *nm = &var.name[0];
|
||||
|
||||
bool multiDimArray = false;
|
||||
int arrayIdx = 0;
|
||||
|
||||
// reverse figure out structures and structure arrays
|
||||
while(strchr(nm, '.') || strchr(nm, '['))
|
||||
{
|
||||
@@ -764,7 +767,7 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
|
||||
*nm = 0;
|
||||
nm++;
|
||||
|
||||
int arrayIdx = 0;
|
||||
arrayIdx = 0;
|
||||
|
||||
// if it's an array, get the index used
|
||||
if(isarray)
|
||||
@@ -789,15 +792,8 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
|
||||
}
|
||||
else
|
||||
{
|
||||
// we strip any trailing [0] above (which is useful for non-structure variables),
|
||||
// so we should not hit this path unless two variables exist like:
|
||||
// structure.member[0]
|
||||
// structure.member[1]
|
||||
// The program introspection should only return the first for a basic type,
|
||||
// and we should not hit this case
|
||||
parentmembers = NULL;
|
||||
RDCWARN("Unexpected naked array as member (expected only one [0], which should be trimmed");
|
||||
break;
|
||||
// if there's no . after the array index, this is a multi-dimensional array.
|
||||
multiDimArray = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -811,7 +807,8 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
|
||||
parentVar.type.descriptor.columns = 0;
|
||||
parentVar.type.descriptor.rowMajorStorage = false;
|
||||
parentVar.type.descriptor.type = var.type.descriptor.type;
|
||||
parentVar.type.descriptor.elements = isarray ? RDCMAX(1U, uint32_t(arrayIdx + 1)) : 0;
|
||||
parentVar.type.descriptor.elements =
|
||||
isarray && !multiDimArray ? RDCMAX(1U, uint32_t(arrayIdx + 1)) : 0;
|
||||
parentVar.type.descriptor.arrayByteStride = topLevelStride;
|
||||
|
||||
bool found = false;
|
||||
@@ -842,6 +839,61 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
|
||||
parentmembers = &(parentmembers->back().type.members);
|
||||
}
|
||||
|
||||
if(multiDimArray)
|
||||
{
|
||||
// if this is a multi-dimensional array, we've now selected the root array.
|
||||
// We now iterate all the way down to the last element, then break out of the list so it can
|
||||
// be added as an array.
|
||||
//
|
||||
// Note: this means that for float foo[4][3] we won't iterate here - we've already selected
|
||||
// foo, and outside of the loop we'll push back a float[3] for each of foo[0], foo[1], foo[2],
|
||||
// foo[3] that we encounter in this iteration process.
|
||||
//
|
||||
// For bar[4][3][2] we've selected bar, we'll then push back a [4] member and then outside of
|
||||
// the loop we'll push back each of bar[.][0], bar[.][1], etc as a float[2]
|
||||
|
||||
while(*nm)
|
||||
{
|
||||
parentVar.name = StringFormat::Fmt("[%d]", arrayIdx);
|
||||
|
||||
found = false;
|
||||
for(size_t i = 0; i < parentmembers->size(); i++)
|
||||
{
|
||||
if((*parentmembers)[i].name == parentVar.name)
|
||||
{
|
||||
parentmembers = &((*parentmembers)[i].type.members);
|
||||
found = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
{
|
||||
parentmembers->push_back(parentVar);
|
||||
parentmembers = &(parentmembers->back().type.members);
|
||||
}
|
||||
|
||||
arrayIdx = 0;
|
||||
|
||||
RDCASSERT(*nm == '[');
|
||||
nm++;
|
||||
|
||||
while(*nm >= '0' && *nm <= '9')
|
||||
{
|
||||
arrayIdx *= 10;
|
||||
arrayIdx += int(*nm) - int('0');
|
||||
nm++;
|
||||
}
|
||||
|
||||
RDCASSERT(*nm == ']');
|
||||
*nm = 0;
|
||||
nm++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// the 0th element of each array fills out the actual members, when we
|
||||
// encounter an index above that we only use it to increase the type.descriptor.elements
|
||||
// member (which we've done by this point) and can stop recursing
|
||||
@@ -858,6 +910,10 @@ void ReconstructVarTree(GLenum query, GLuint sepProg, GLuint varIdx, GLint numPa
|
||||
string n = nm;
|
||||
var.name = n;
|
||||
|
||||
// for multidimensional arrays there will be no proper name, so name the variable by the index
|
||||
if(multiDimArray)
|
||||
var.name = StringFormat::Fmt("[%d]", arrayIdx);
|
||||
|
||||
parentmembers->push_back(var);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user