Vulkan计算着色器只读取统一缓冲区

时间:2017-11-10 15:21:38

标签: c++ shader vulkan memory-layout

我编写了一个非常简单的计算着色器,它读取一个大小为 1KB 的统一缓冲区,并绑定到描述符集,然后将其作为 256 {{1然后对于每个元素,加倍该值并将结果写入绑定到描述符集的另一个存储缓冲区(当然也在着色器中定义):

uint

输入数据通过统一缓冲区提供,在运行着色器之前,该缓冲区的内存已分配并写入。我只是使用 3

的值覆盖每个字节
#version 450 core

layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;

layout(set = 0, binding = 0) uniform InputBuffer
{
    uint values[256];
} inputBuffer;

layout(set = 0, binding = 1) buffer OutputBuffer
{
    uint values[256];
} outputBuffer;

void main(void)
{
    for(int i = 0; i < 256; i++) {
        outputBuffer.values[i] = inputBuffer.values[i] * 2;
    }

    return;
}

着色器写入存储缓冲区的结果值很奇怪,四分之一的数据似乎是正确的,结果用 0s 填充: enter image description here

我检查了代码中的几个点,其中为Vulkan函数提供了大小或偏移量,所有这些点分别是 1024(1KB) 0

我想这可能是因为Vulkan计算着色器如何从统一缓冲存储器读取数据,而std140数据布局可能是此问题的根源,但据我所知,教程/规范没有提及任何内容中间抵消要求!

1 个答案:

答案 0 :(得分:1)

您忘记了std140布局的工作原理。基本类型数组中的元素始终大小为16字节。因此,uint values[256]; 确实uvec4 values[256];

您应该使用uvec4 values[64];数组,并将其编入索引:

outputBuffer.values[i] = inputBuffer.values[i / 4][i % 4] * 2;