I want to use different push constants for my vertex and fragment shader stages.
For the vertex shader I use this c++ struct
struct vertex_push_constant {
matrix4x4 model{};
matrix4x4 normal{};
};
And for the fragment shader this struct
struct fragment_push_constant {
vector4 camera_position{};
vector4 light_position{};
vector4 light_color{};
};
To combine the push constants I just put them in a struct together
struct push_constant {
vertex_push_constant vertex{};
fragment_push_constant fragment{};
};
In the shaders I use the same structs e.g. the vertex shader
struct vertex_push_constant_data {
mat4 model;
mat4 normal;
};
layout(push_constant) uniform push_constant {
vertex_push_constant_data data;
} push;
and the fragment shader is nearly identical
struct fragment_push_constant_data {
vec4 camera_position{};
vec4 light_position{};
vec4 light_color{};
};
layout(push_constant) uniform push_constant {
fragment_push_constant_data data;
} push;
When I set up my pipeline I use the following push constant ranges
const auto push_constant_ranges = std::array<VkPushConstantRange, 2>{
VkPushConstantRange{
.stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
.offset = offsetof(push_constant, vertex_push_constant),
.size = sizeof(vertex_push_constant)
},
VkPushConstantRange{
.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
.offset = offsetof(push_constant, fragment_push_constant),
.size = sizeof(fragment_push_constant)
},
};
I now want to populate the push constants in my render call by using vkCmdPushConstants
but I get an error when using
vkCmdPushConstants(command_buffer, layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(push_constant), &push_constant_data)
Error
Validation Error: [ VUID-vkCmdPushConstants-offset-01795 ] Object 0: handle = 0x1f66f6c4000, type = VK_OBJECT_TYPE_COMMAND_BUFFER; | MessageID = 0x27bc88c6 | vkCmdPushConstants(): VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT, VkPushConstantRange in VkPipelineLayout 0x301e6c0000000022[] overlapping offset = 0 and size = 176, do not contain VK_SHADER_STAGE_VERTEX_BIT|VK_SHADER_STAGE_FRAGMENT_BIT. The Vulkan spec states: For each byte in the range specified by offset and size and for each shader stage in stageFlags, there must be a push constant range in layout that includes that byte and that stage (https://vulkan.lunarg.com/doc/view/1.3.204.1/windows/1.3-extensions/vkspec.html#VUID-vkCmdPushConstants-offset-01795)
Then I tried to set the push constants for each shader steage seperate
vkCmdPushConstants(command_buffer, layout, VK_SHADER_STAGE_VERTEX_BIT, offsetof(push_constant, vertex_push_constant), sizeof(vertex_push_constant), &push_constant_data)
vkCmdPushConstants(command_buffer, layout, VK_SHADER_STAGE_FRAGMENT_BIT, offsetof(push_constant, fragment_push_constant), sizeof(fragment_push_constant), &push_constant_data)
But then I just get a different runtime error.
How can I set up different push constant data for the different shader stages?
I dont want to use a single push constant data block for both because I dont need the model matrix in the fragment shader or the camera position in the vertex shader.
EDIT: Ive added the shader code for the push constants