提问人:alagris 提问时间:8/14/2021 更新时间:8/14/2021 访问量:674
Vulkan 从整数解包 uvec4
Vulkan unpack uvec4 from integer
问:
我观察到一些奇怪的行为。我有一个无符号的 32 位整数数组。 我使用一个整数对 4 个值进行编码,每个值的大小为 1 个字节。然后我想将这样的缓冲区传递给顶点着色器
layout (location = 0) in uvec4 coords;
为了实现这一点,我使用 with set to .我已经定义了这样一个方便的结构VkVertexInputAttributeDescription
format
VK_FORMAT_R8G8B8A8_UINT
struct PackedUVec4{
unsigned char x;
unsigned char y;
unsigned char z;
unsigned char w;
};
然后我构建我的缓冲区,然后将该缓冲区发送到 GPU。但是,我观察到的是字节的顺序被交换了。例如,如果我有PackedUVec4[]
layout (location = 0) in uvec4 coords;
void main(){
debugPrintfEXT("%v4d", coords);
}
它似乎打印了正确的输出。但是,如果将格式更改为并尝试运行VK_FORMAT_R32_UINT
layout (location = 0) in uint coords;
void main(){
uint w = coords & 255u;
uint z = coords/256 & 255u;
uint y = coords/(256*256) & 255u;
uint x = coords/(256*256*256) & 255u;
debugPrintfEXT("%v4d", uvec4(x,y,z,w));
}
我以相反的顺序获取字节。向量类型是否使用不同的字节序?
答:
问题不在于 Vulkan,而在于你的代码对正在发生的事情的解释。发送和接收。
回想一下,字节序是关于多字节值中字节的逻辑位置与多字节值中字节的相对地址之间的(潜在)差异。在 little endian 中,如果将一个四字节的值写入内存,则第一个字节将是该值中最低有效字节。
字节序适用于读取和写入,但仅在将多字节值作为多字节值读取/写入时。您不是多字节值;它是一个包含具有特定布局的字节的结构。因此,如果写入 的组件,则无论 CPU 的字节序如何,您都是在写入该结构的第一个字节。PackedUVec4
x
PackedUVec4
当您告诉 Vulkan 将此数据作为单个 4 字节值 () 读取时,它会按照 CPU 的字节序定义进行读取。但是您的代码没有按照 CPU 的字节序生成该数据;它根据 .所以内存中的第一个字节是 。如果 GPU 将这 4 个字节读取为小字节序 4 字节值,则第一个字节将映射到 4 字节值的最低有效字节。VK_FORMAT_R32_UINT
PackedUVec4
x
但是手动解码数据的代码解码错误。它期望最低有效字节为 。w
如果您希望您的代码与字节序无关,那么您需要 GPU 按照存储在内存中的顺序将数据读取为 4 个单独的字节。这就是所代表的。如果您希望 GPU 将其读取为单个 32 位整数内基于字节序的排序,则需要由 CPU 以这种方式写入它。VK_FORMAT_R8G8B8A8_UINT
评论