Using different push-constants in different shader stages

一个人想着一个人 提交于 2019-12-23 07:03:48

问题


I have a vertex shader with a push-constant block containing one float:

layout(push_constant) uniform pushConstants {
    float test1;
} u_pushConstants;

And a fragment shader with another push-constant block with a different float value:

layout(push_constant) uniform pushConstants {
    float test2;
} u_pushConstants;

test1 and test2 are supposed to be different.

The push-constant ranges for the pipeline layout are defined like this:

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)
    }
};

The actual constants are then pushed during rendering like this:

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()
);

However, when checking the values inside the shaders, both have the value 123. It seems that the offsets are completely ignored. Am I using them incorrectly?


回答1:


In your pipeline layout, you stated that your vertex shader would access the range of data from [0, 4) bytes in the push constant range. You stated that your fragment shader would access the range of data from [4, 8) in the push constant range.

But your shaders tell a different story.

layout(push_constant) uniform pushConstants {
    float test2;
} u_pushConstants;

This definition very clearly says that the push constant range starts uses [0, 4). But you told Vulkan it uses [4, 8). Which should Vulkan believe: your shader, or your pipeline layout?

A general rule of thumb to remember is this: your shader means what it says it means. Parameters given to pipeline creation cannot change the meaning of your code.

If you intend to have the fragment shader really use [4, 8), then the fragment shader must really use it:

layout(push_constant) uniform fragmentPushConstants {
    layout(offset = 4) float test2;
} u_pushConstants;

Since it has a different definition from the VS version, it should have a different block name too. The offset layout specifies the offset of the variable in question. That's standard stuff from GLSL, and compiling for Vulkan doesn't change that.



来源:https://stackoverflow.com/questions/37056159/using-different-push-constants-in-different-shader-stages

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!