Where is the alignment problem in my GLSL push constant block?

The relevant GLSL code:

layout(std430, buffer_reference) readonly buffer VertexBuffer{
    Vertex vertices[];
};

layout(std430, buffer_reference) readonly buffer JointMatrixBuffer{
    mat4 jointMatrices[];
};

layout(std430, push_constant) uniform constants
{
    VertexBuffer vertexBuffer;
    mat4 transform;
    JointMatrixBuffer jointMatrixBuffer;
    uint16_t jointMatrixBufferIndices[64];
} push;

The corresponding C++ push constant struct:

  struct SkinnedPushConstant {
    VkDeviceAddress vertexBufferAddress = 0;
    glm::mat4 transform = glm::identity<glm::mat4>();
    VkDeviceAddress jointMatricesBufferAddress = 0;
    uint16_t jointMatrixBufferIndices[64];
  };

I get the following validation error when creating a graphics pipeline with this shader module:

validation layer: Validation Error: [ VUID-VkGraphicsPipelineCreateInfo-layout-07987 ] Object 0: handle = 0x2723ba0000000037, type = VK_OBJECT_TYPE_SHADER_MODULE; Object 1: handle = 0xa43473000000002d, type = VK_OBJECT_TYPE_PIPELINE_LAYOUT; | MessageID = 0xfbdd4d2e | vkCreateGraphicsPipelines(): pCreateInfos[0].pStages[0] SPIR-V (VK_SHADER_STAGE_VERTEX_BIT) has a push constant buffer Block with range [0, 216] which outside the pipeline layout range of [0, 208].
The Vulkan spec states: If a push constant block is declared in a shader, a push constant range in layout must match the shader stage (https://vulkan.lunarg.com/doc/view/1.3.296.0/linux/1.3-extensions/vkspec.html#VUID-VkGraphicsPipelineCreateInfo-layout-07987)

This error is telling me the push constant block has a range of 216, whereas the size of my C++ push constant struct is 208. I am assuming due to std430 alignment rules an extra 8 bytes of padding are being added somewhere to the GLSL push constant block, but I can’t figure out where (or why). I would greatly appreciate if someone could explain what I am doing wrong.

I didn’t realize the default buffer reference alignment is 16, which is where the extra 8 bytes came from. Adding alignas(16) in frront of all VkDeviceAddress members of the SkinnedPushConstant strruct fixed the validation error.

You can use Nsight to debug those problems especially for the alignment issues. The memory distribution will be clearly showed in the tool. :grinning: