# Mat4 that is written to a storage buffer in a compute shader has an altered value when read back

I am attempting to use a compute shader to calculate joint transforms for animations.

I use a loop to calculate the global joint transforms from the local transforms. Relevant code below:

layout(set = 0, binding = 2) readonly buffer LocalTransforms {
Similarity local_transforms[];
};

layout(set = 0, binding = 3) buffer GlobalTransforms {
mat4 global_transforms[];
};

struct NodeAndParent {
uint node_index;
int parent_index;
};

layout(set = 0, binding = 4) readonly buffer DepthFirstNodes {
NodeAndParent depth_first_nodes[];
};

void main() {
uint index = gl_GlobalInvocationID.x;

uint nodes_offset = index * num_nodes;

if (nodes_offset >= global_transforms.length()) {
return;
}

for (uint i = 0; i < num_nodes; i++) {
NodeAndParent indices = depth_first_nodes[i];

uint node_index = nodes_offset + indices.node_index;
mat4 local_transform = similarity_to_mat4(local_transforms[node_index]);

if (indices.parent_index != -1) {
mat4 parent_transform = global_transforms[nodes_offset + indices.parent_index];
global_transforms[node_index] = parent_transform * local_transform;
} else {
global_transforms[node_index] = local_transform;
}
}


There is a bug somewhere and I have been attempting to use renderdoc to debug it. I have realised that on the first iteration, one matrix is written to index 3 of of the buffer (right side image), but when it is read back as the parent transform on the second iteration (left image), the values reported in renderdoc are incorrect.

Note that the section of the buffer is not being used by any other thread, and I have an early-exit for threads that would be out-of-bounds of global_transforms. I've tested other threads and they all return early.

My question is this:

• A) Is it possibly that renderdoc is reporting this incorrectly?
• B) Is the value stored in the buffer really like that in that point in time? Would using a barrier help? What kind of barrier?
• C) Is there some other problem with the code that could be causing this?

Thank you!

• Are you somehow ensuring that child bones are always processed in the same invocation as the parent bones? Otherwise, a bone could be processed in one invocation before its parent bone's transform has been computed in another invocation. Also, your indexing is confusing me—it looks like every invocation will be processing the same depth_first_nodes elements, but looking at different parts of the local_transforms and global_transforms arrays. Is it for different instances of the same model, or how does that work? – Nathan Reed Mar 14 at 5:32