在不同的着色器阶段使用不同的推常数 [英] Using different push-constants in different shader stages

查看:87
本文介绍了在不同的着色器阶段使用不同的推常数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个顶点着色器,带有一个包含一个浮点的推常数块:

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 test2 应该是不同的.

管道布局的push-constant范围定义如下:

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

但是,在检查着色器内部的值时,两个值都为123. 似乎偏移量被完全忽略了.我使用不正确吗?

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?

推荐答案

在管道布局中,您声明了顶点着色器将访问推入常量范围中[0,4)个字节中的数据范围.您声明片段着色器将访问推入常量范围中的[4,8)中的数据范围.

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;

此定义非常清楚地表明,推动常数范围开始使用[0,4).但是您告诉Vulkan它使用[4,8). Vulkan应该相信哪个:您的着色器或管道布局?

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.

如果您打算让片段着色器真正使用[4,8),则片段着色器必须真正使用它:

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;

由于它的定义与VS版本不同,因此它的块名称也应不同. offset布局指定相关变量的偏移量.这是GLSL的标准内容,并且为Vulkan编译不会改变这一点.

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.

这篇关于在不同的着色器阶段使用不同的推常数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆