matchUniformBlocks function Debugging and profiling
List<List<ShaderUniformBlockInfo> >
matchUniformBlocks(
- List<
ShaderUniformBlockInfo> declared, - List<
int> lengths
Matches emplaced uniform buffers, by byte length, to the blocks a draw's shaders declare. Returns one candidate list per length, in order.
An exact size match wins. The engine also binds a block's leading members
only (a FrameInfo written to 80 of its 128 bytes), so a shorter buffer
matches a block when its length lands on a member boundary, among the
blocks no other buffer already claimed; a buffer with one candidate claims
it, which narrows the rest until nothing changes. More than one candidate
left means the buffer cannot be named.
Implementation
List<List<ShaderUniformBlockInfo>> matchUniformBlocks(
List<ShaderUniformBlockInfo> declared,
List<int> lengths,
) {
final result = <List<ShaderUniformBlockInfo>>[];
final claimed = <ShaderUniformBlockInfo>{};
for (final length in lengths) {
final exact = [
for (final block in declared)
if (block.sizeBytes == length) block,
];
result.add(exact);
if (exact.length == 1) claimed.add(exact.single);
}
for (var i = 0; i < lengths.length; i++) {
if (result[i].isNotEmpty) continue;
final length = lengths[i];
result[i] = [
for (final block in declared)
if (!claimed.contains(block) &&
block.sizeBytes > length &&
_endsOnMemberBoundary(block, length))
block,
];
}
var changed = true;
while (changed) {
changed = false;
for (final candidates in result) {
if (candidates.length == 1) {
if (claimed.add(candidates.single)) changed = true;
continue;
}
final before = candidates.length;
candidates.removeWhere(claimed.contains);
if (candidates.length != before) changed = true;
}
}
return result;
}