0

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

Symlink
  • 383
  • 2
  • 12
  • Minimal is a variable. Sometimes it's 5 lines. Sometimes it's 500. Even when you know exactly what's wrong it could take a few hundred lines to burn through the set-up boilerplate and force the error. If that's minimal, so be it. The point is do what you can to isolate the problem and often you reduce the noise enough that the question goes away. If it doesn't you can be pretty sure you have a bad mother of a question. – user4581301 Sep 01 '22 at 00:44
  • @Symlink: "*its also has a different background than this one*" I see no functional difference between them. They both seem to be asking the same thing. – Nicol Bolas Sep 01 '22 at 01:23
  • By "I get an error" do you mean a validation layer error? If so, I think I spotted something wrong in your code, but for that to confirm, the actual error message is important. – Sascha Willems Sep 01 '22 at 05:10
  • @SaschaWillems I added the error message. I get this vaidation error every frame printed. – Symlink Sep 01 '22 at 13:53
  • @NicolBolas Not to be rude, but this isnt a duplicate. The answer in the link does not solve my problem / answer my questions..... – Symlink Sep 01 '22 at 13:58
  • @NicolBolas I already came acros this answer when researching but as it didnt answer the things i was asking i asked this new question. – Symlink Sep 01 '22 at 13:59
  • @Symlink: Then please explain how it doesn't solve the problem. From what I can tell, the error you're getting is the same error you got previously, and it's the same error as in the duplicate. Your shader exhibits the same problem (lack of offset) as the duplicate. From everything I can see, your question is just a differently-worded version of the same problem: not using offsets in the shader. What is the difference? – Nicol Bolas Sep 01 '22 at 14:00
  • @Symlink: At the very least, add your shader and pipeline layout code. – Nicol Bolas Sep 01 '22 at 14:08
  • In your push constant range struct, did you intend to set both stage flags to vertex? – Karl Schultz Sep 01 '22 at 15:01
  • @Symlink: Your code has the *exact same problem* as the duplicate (again, a lack of an `offset`). Now, your code might have other problems, but that's definitely a problem that should be fixed. – Nicol Bolas Sep 01 '22 at 16:04
  • @NicolBolas Maybe you could explain how I would change the code that doesnt work so that i does. – Symlink Sep 01 '22 at 16:06

0 Answers0