Detect struct array strides from BDA pointer decorations

This commit is contained in:
baldurk
2026-08-07 16:26:33 +01:00
parent d3a366e759
commit 62b088319a
4 changed files with 38 additions and 9 deletions
@@ -1197,7 +1197,7 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
rdcarray<sortedsamp> samplers;
rdcarray<sortedres> roresources, rwresources;
// for pointer types, mapping of inner type ID to index in list (assigned sequentially)
// for pointer types, mapping of pointer type ID to index in list (assigned sequentially)
SparseIdMap<uint16_t> pointerTypes;
// $Globals gathering - for GL global values
@@ -1216,7 +1216,7 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
if(it->second.type == DataType::PointerType &&
it->second.pointerType.storage == rdcspv::StorageClass::PhysicalStorageBuffer)
{
pointerTypes.insert(std::make_pair(it->second.InnerType(), (uint16_t)pointerTypes.size()));
pointerTypes.insert(std::make_pair(it->first, (uint16_t)pointerTypes.size()));
}
}
@@ -1938,24 +1938,39 @@ void Reflector::MakeReflection(const GraphicsAPI sourceAPI, const ShaderStage st
{
ShaderConstant dummy;
MakeConstantBlockVariable(dummy, pointerTypes, dataTypes[id].pointerType.storage,
dataTypes[id], rdcstr(), Decorations(), false, specInfo);
dataTypes[dataTypes[id].InnerType()], rdcstr(), Decorations(),
false, specInfo);
}
// continue if we generated some more
} while(pointerTypes.size() != numPointerTypes);
// see if we have different pointer types to the same struct, to give them unique names
SparseIdMap<int> dupeInners;
for(auto it = pointerTypes.begin(); it != pointerTypes.end(); ++it)
{
dupeInners[dataTypes[it->first].InnerType()]++;
}
// populate the pointer types
reflection.pointerTypes.reserve(pointerTypes.size());
for(auto it = pointerTypes.begin(); it != pointerTypes.end(); ++it)
{
ShaderConstant dummy;
const DataType &innerType = dataTypes[dataTypes[it->first].InnerType()];
MakeConstantBlockVariable(dummy, pointerTypes, dataTypes[it->first].pointerType.storage,
dataTypes[it->first], rdcstr(), Decorations(), false, specInfo);
innerType, rdcstr(), decorations[it->first], false, specInfo);
if(it->second >= reflection.pointerTypes.size())
reflection.pointerTypes.resize(it->second + 1);
// use the pointer type to disambiguate if there's multiple pointers to the same struct - since
// it could e.g. have different strides
if(innerType.type == DataType::StructType && dupeInners[innerType.id] > 1)
dummy.type.name += StringFormat::Fmt("_%u", it->first.value());
reflection.pointerTypes[it->second] = dummy.type;
}
@@ -2129,6 +2144,10 @@ void Reflector::MakeConstantBlockVariable(ShaderConstant &outConst,
const DataType *curType = &type;
// for pointers to structs, the pointer itself has an array stride which we should pay attention to
if(curType->type == DataType::StructType && varDecorations.arrayStride != ~0U)
outConst.type.arrayByteStride = varDecorations.arrayStride;
// if the type is an array, set array size and strides then unpeel the array
if(curType->type == DataType::ArrayType)
{
@@ -2192,8 +2211,7 @@ void Reflector::MakeConstantBlockVariable(ShaderConstant &outConst,
// try to insert the inner type ID into the map. If it succeeds, it gets the next available
// pointer type index (size of the map), if not then we just get the previously added index
auto it =
pointerTypes.insert(std::make_pair(curType->InnerType(), (uint16_t)pointerTypes.size()));
auto it = pointerTypes.insert(std::make_pair(curType->id, (uint16_t)pointerTypes.size()));
outConst.type.pointerTypeID = it.first->second;
return;