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.