Vulkan 计算着色器仅读取统一缓冲区的一部分

查克梅什马

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

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

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

memset(*mappedMemory, 3, 1024);

着色器写入存储缓冲区的结果值很奇怪,四分之一的数据似乎是正确的,结果,填充了0在此处输入图片说明

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

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

尼可波拉斯

你已经忘记了std140布局是如何工作的。基本类型数组中的元素大小始终为16 字节。所以,你uint values[256];真正的一个uvec4 values[256];

你应该使用一个uvec4 values[64];数组,并像这样索引它:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章