mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 18:10:35 +00:00
Check top-level stride of buffers to know if we need to pad. Refs #485
This commit is contained in:
@@ -757,6 +757,13 @@ void ReconstructVarTree(const GLHookSet &gl, GLenum query, GLuint sepProg, GLuin
|
||||
else
|
||||
var.type.descriptor.elements = 0;
|
||||
|
||||
GLint topLevelStride = 0;
|
||||
if(query == eGL_BUFFER_VARIABLE)
|
||||
{
|
||||
GLenum propName = eGL_TOP_LEVEL_ARRAY_STRIDE;
|
||||
gl.glGetProgramResourceiv(sepProg, query, varIdx, 1, &propName, 1, NULL, &topLevelStride);
|
||||
}
|
||||
|
||||
vector<DynShaderConstant> *parentmembers = defaultBlock;
|
||||
|
||||
if(values[3] != -1 && values[3] < numParentBlocks)
|
||||
@@ -833,6 +840,7 @@ void ReconstructVarTree(const GLHookSet &gl, GLenum query, GLuint sepProg, GLuin
|
||||
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.arrayStride = topLevelStride;
|
||||
|
||||
bool found = false;
|
||||
|
||||
@@ -1534,6 +1542,54 @@ void MakeShaderReflection(const GLHookSet &gl, GLenum shadType, GLuint sepProg,
|
||||
for(size_t ssbo = 0; ssbo < ssbos.size(); ssbo++)
|
||||
{
|
||||
sort(members[ssbo]);
|
||||
|
||||
// account for padding for std430 layout, if we have a root array of
|
||||
// structs, we need to pad the struct up to have the correct alignment
|
||||
if(members[ssbo].size() == 1 && !members[ssbo][0].type.members.empty() &&
|
||||
members[ssbo][0].type.descriptor.arrayStride != 0)
|
||||
{
|
||||
// now that we're sorted, see what the tightly packed stride would be by looking at the last
|
||||
// member
|
||||
uint32_t desiredStride = members[ssbo][0].type.descriptor.arrayStride;
|
||||
|
||||
DynShaderConstant *last = &members[ssbo][0].type.members.back();
|
||||
while(!last->type.members.empty())
|
||||
last = &last->type.members.back();
|
||||
|
||||
// start from the offset
|
||||
uint32_t stride = last->reg.vec * 16 + last->reg.comp * 4;
|
||||
|
||||
// add its size
|
||||
uint32_t size = last->type.descriptor.rows * last->type.descriptor.cols * 4;
|
||||
if(last->type.descriptor.type == eVar_Double)
|
||||
size *= 2;
|
||||
|
||||
stride += size;
|
||||
|
||||
if(stride < desiredStride)
|
||||
{
|
||||
uint32_t padding = desiredStride - stride;
|
||||
|
||||
RDCASSERT((padding % 4) == 0 && padding <= 16, padding);
|
||||
|
||||
padding /= 4;
|
||||
|
||||
DynShaderConstant paddingVar;
|
||||
paddingVar.name = "__padding";
|
||||
paddingVar.reg.vec = last->reg.vec + (size / 16);
|
||||
paddingVar.reg.comp = (last->reg.comp + size / 4) % 16;
|
||||
paddingVar.type.descriptor.type = eVar_UInt;
|
||||
paddingVar.type.descriptor.rows = 1;
|
||||
paddingVar.type.descriptor.cols = padding;
|
||||
paddingVar.type.descriptor.elements = 1;
|
||||
paddingVar.type.descriptor.rowMajorStorage = false;
|
||||
paddingVar.type.descriptor.arrayStride = 0;
|
||||
paddingVar.type.descriptor.name = StringFormat::Fmt("uint%u", padding);
|
||||
|
||||
members[ssbo][0].type.members.push_back(paddingVar);
|
||||
}
|
||||
}
|
||||
|
||||
copy(rwresources[ssbos[ssbo]].variableType.members, members[ssbo]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user