在 HLSL 中指定推送常量块偏移

Specifying push constant block offset in HLSL

我正在尝试编写一个 Vulkan 渲染器,我将 glslangValidator 与 HLSL 一起用于着色器,并正在尝试实现推送常量。

[[vk::push_constant]]
cbuffer cbFragment {
    float4 imageColor;
    float4 aaaa;
};
 
[[vk::push_constant]]
cbuffer cbMatrices {
    float4 bbbb;
};

注释“[[vk::push_constant]]”有效,我使用 spirv_reflect 进行反射,并且两个推送常量都显示出来并且按预期工作。 我遇到的问题是它们似乎重叠,如果我为“bbbb”分配一个值,“imageColor”会以完全相同的方式受到影响,反之亦然。在反射数据中,两个推送常量块的偏移量都为 0,这就解释了这个问题。但是,我似乎完全无法更改任何一个推送常量的偏移量。 [[vk::offset(x)]] 根本不起作用,它既不影响单个成员偏移量也不影响推送常量的偏移量。唯一有效的偏移量是 HLSL 内置的“packoffset”,它仅适用于缓冲区成员。虽然它实际上可能是一个解决方案,只是将一个推送常量的成员偏移到另一个推送常量的范围之外,但我几乎不认为这是一个明智的解决方案,因为它也会导致验证层失败,因为偏移了个人成员只是不必要地增加了推送常量的大小,重叠本身仍然存在。

我将不胜感激任何对此事的帮助,并愿意提供任何必要的澄清,非常感谢!

推送常量存在于单个连续内存块中。编译器不会尝试将多个块附加到该内存中;与 GLSL syntax 一样,它旨在只有一个块包含所有推送常量数据。

这与编译器必须将变量打包到一个块中的其他地方是一致的:它只在一个块内打包,而不是跨多个块打包。两个独立的非 pushconstant cbuffers 将引用内存中的两个不同的缓冲区,其内容从它们各自缓冲区中的偏移量零开始。只有一个“推送常量缓冲区”,因此你应该只用 vk::push_constant.

装饰一个 cbuffer