vulkano-rs / vulkano

Safe and rich Rust wrapper around the Vulkan API
Apache License 2.0
4.45k stars 435 forks source link

Push constants don't support first field offset decorations #2534

Closed chaynabors closed 1 month ago

chaynabors commented 2 months ago

Template

Issue

I have two definitions of push constants, one from my vertex shader, and one from my fragment shader. I'd like to use the types provided by the shader macro with each occupying different push constant memory. It's my understanding that to do this, I have to do something like the following:

  .push_constants(
      self.layout.clone(),
      0,
      SkinnedVertPushConstants { mvp },
  )?
  .push_constants(
      self.layout.clone(),
      std::mem::size_of::<SkinnedVertPushConstants>() as u32,
      DefaultFragPushConstants {
          fog_origin: [0.0, 0.0, 0.0, 0.0],
          fog_color: [1.0, 1.0, 1.0],
          fog_intensity: 1.0,
      },
  )?;

  ...

  let layout_create_info = PipelineDescriptorSetLayoutCreateInfo {
    flags: PipelineLayoutCreateFlags::empty(),
    set_layouts: vec![DescriptorSetLayoutCreateInfo {
        bindings: BTreeMap::from([(0, layout_binding)]),
        ..Default::default()
    }],
    push_constant_ranges: vec![
        PushConstantRange {
            stages: ShaderStages::VERTEX,
            offset: 0,
            size: std::mem::size_of::<SkinnedVertPushConstants>() as u32,
        },
        PushConstantRange {
            stages: ShaderStages::FRAGMENT,
            offset: std::mem::size_of::<SkinnedVertPushConstants>() as u32,
            size: std::mem::size_of::<DefaultFragPushConstants>() as u32,
        },
    ],
};
layout(push_constant) uniform PushConstants {
    layout(offset = 64) vec4 fog_origin;
    vec3 fog_color;
    float fog_intensity;
} constants;

note that the offset is defined for the zeroth field in this screenshot from https://docs.vulkan.org/guide/latest/push_constants.html#pc-offsets image

relevant code is here https://github.com/vulkano-rs/vulkano/blob/42e4d0b7c3ff742d81339cadfd291257ee864110/vulkano-shaders/src/structs.rs#L850

The shader macro errors out when a shader contains push constants with the zeroth field is decorated with offset. Am I misunderstanding something here or is this a bug?

chaynabors commented 2 months ago

Update: cloning and removing the check causes my code to work as written at first glance. On one hand I'd propose removing the check. On the other, the generated struct might depend on its decorations. If there's an offset on the zeroth member, you might either want padding or no padding before it. You might choose to support this offset for push constants and not other types but I don't see any way to discriminate against that