我写了一个非常简单的计算着色器,它读取一个大小正好为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] 删除。
我来说两句