在不同的着色器阶段使用不同的 push-constants
Using different push-constants in different shader stages
我有一个顶点着色器,它的 push-constant 块包含一个浮点数:
layout(push_constant) uniform pushConstants {
float test1;
} u_pushConstants;
还有一个带有另一个具有不同浮点值的推送常量块的片段着色器:
layout(push_constant) uniform pushConstants {
float test2;
} u_pushConstants;
test1 和 test2 应该是不同的。
管道布局的推送常数范围定义如下:
std::array<vk::PushConstantRange,2> ranges = {
vk::PushConstantRange{
vk::ShaderStageFlagBits::eVertex,
0,
sizeof(float)
},
vk::PushConstantRange{
vk::ShaderStageFlagBits::eFragment,
sizeof(float), // Push-constant range offset (Start after vertex push constants)
sizeof(float)
}
};
然后在渲染过程中像这样推送实际常量:
std::array<float,1> constants = {123.f};
commandBufferDraw.pushConstants(
pipelineLayout,
vk::ShaderStageFlagBits::eVertex,
0,
sizeof(float),
constants.data()
);
std::array<float,1> constants = {456.f};
commandBufferDraw.pushConstants(
pipelineLayout,
vk::ShaderStageFlagBits::eFragment,
sizeof(float), // Offset in bytes
sizeof(float),
constants.data()
);
但是,当检查着色器内部的值时,两者的值都是 123。
似乎完全忽略了偏移量。我是不是用错了?
在您的管道布局中,您声明您的顶点着色器将访问推送常量范围内 [0, 4) 字节的数据范围。您声明您的片段着色器将访问推送常量范围内 [4, 8) 的数据范围。
但是您的着色器讲述了一个不同的故事。
layout(push_constant) uniform pushConstants {
float test2;
} u_pushConstants;
这个定义很明确的说push constant range starts uses [0, 4).但是你告诉 Vulkan 它使用 [4, 8)。 Vulkan 应该相信哪个:您的着色器,还是您的管线布局?
要记住的一般经验法则是:您的着色器意味着它所说的。为管道创建提供的参数不能改变代码的含义。
如果你打算让片段着色器真正使用[4, 8),那么片段着色器必须真正使用它:
layout(push_constant) uniform fragmentPushConstants {
layout(offset = 4) float test2;
} u_pushConstants;
由于它与VS版本的定义不同,所以它也应该有不同的块名。 offset
布局指定相关变量的偏移量。这是 GLSL 的标准内容,compiling for Vulkan 不会改变这一点。
我有一个顶点着色器,它的 push-constant 块包含一个浮点数:
layout(push_constant) uniform pushConstants {
float test1;
} u_pushConstants;
还有一个带有另一个具有不同浮点值的推送常量块的片段着色器:
layout(push_constant) uniform pushConstants {
float test2;
} u_pushConstants;
test1 和 test2 应该是不同的。
管道布局的推送常数范围定义如下:
std::array<vk::PushConstantRange,2> ranges = {
vk::PushConstantRange{
vk::ShaderStageFlagBits::eVertex,
0,
sizeof(float)
},
vk::PushConstantRange{
vk::ShaderStageFlagBits::eFragment,
sizeof(float), // Push-constant range offset (Start after vertex push constants)
sizeof(float)
}
};
然后在渲染过程中像这样推送实际常量:
std::array<float,1> constants = {123.f};
commandBufferDraw.pushConstants(
pipelineLayout,
vk::ShaderStageFlagBits::eVertex,
0,
sizeof(float),
constants.data()
);
std::array<float,1> constants = {456.f};
commandBufferDraw.pushConstants(
pipelineLayout,
vk::ShaderStageFlagBits::eFragment,
sizeof(float), // Offset in bytes
sizeof(float),
constants.data()
);
但是,当检查着色器内部的值时,两者的值都是 123。 似乎完全忽略了偏移量。我是不是用错了?
在您的管道布局中,您声明您的顶点着色器将访问推送常量范围内 [0, 4) 字节的数据范围。您声明您的片段着色器将访问推送常量范围内 [4, 8) 的数据范围。
但是您的着色器讲述了一个不同的故事。
layout(push_constant) uniform pushConstants {
float test2;
} u_pushConstants;
这个定义很明确的说push constant range starts uses [0, 4).但是你告诉 Vulkan 它使用 [4, 8)。 Vulkan 应该相信哪个:您的着色器,还是您的管线布局?
要记住的一般经验法则是:您的着色器意味着它所说的。为管道创建提供的参数不能改变代码的含义。
如果你打算让片段着色器真正使用[4, 8),那么片段着色器必须真正使用它:
layout(push_constant) uniform fragmentPushConstants {
layout(offset = 4) float test2;
} u_pushConstants;
由于它与VS版本的定义不同,所以它也应该有不同的块名。 offset
布局指定相关变量的偏移量。这是 GLSL 的标准内容,compiling for Vulkan 不会改变这一点。