Glsl 将RGBA8图像编写为R32UI

Glsl 将RGBA8图像编写为R32UI,glsl,vulkan,Glsl,Vulkan,我有一个格式为R8G8B8A8(Unorm)的图像 我想在上面写uint数据(以便能够使用原子函数) 因此,当我想“写”它时,我在glsl中使用: layout(set = 0, binding = 2, r32ui) restrict writeonly uniform uimage3D dst; 然而,当我在表演这样的东西时 imageStore(dst, coords, uvec4(0xffffffff)); RenderDoc(以及我的应用程序)告诉我,我的所有值都是0(而不是1.0

我有一个格式为R8G8B8A8(Unorm)的图像

我想在上面写uint数据(以便能够使用原子函数)

因此,当我想“写”它时,我在glsl中使用:

layout(set = 0, binding = 2, r32ui) restrict writeonly uniform uimage3D dst;
然而,当我在表演这样的东西时

imageStore(dst, coords, uvec4(0xffffffff));
RenderDoc(以及我的应用程序)告诉我,我的所有值都是0(而不是1.0(255 unorm))

如果我将
r32ui
替换为
rgba8
一切正常,但我不能使用原子值。所以我想知道是否有可能做这样的事情。(但是,如果我使用r32f而不是rgba8,它也可以正常工作)


您有什么解决方案吗?

Vulkan规范保证只有R32 UINT和R32 SINT格式的存储映像(VK格式、功能、存储映像、原子位)必须支持原子操作。实现也可以添加对其他格式的支持,但这不是强制性的。因此,原子操作不使用rgba8格式并不奇怪

下一个。可以使用与图像格式不同的格式创建图像视图。在这种情况下,图像视图的格式必须与图像的格式兼容。对于R8G8B8A8格式,SINT和UINT R32格式都是兼容的(具有相同的位数)。但为了能够创建具有不同格式的图像视图,必须使用VK_image_create_MUTABLE_format_BIT标志创建图像本身

最后一件事-规范中有一条关于格式兼容性/可变图像的说明:

用于一种视图格式的值可能不完全相同 通过不同格式写入或读取时保留。对于 例如,一个正好具有 当 以浮点格式写入或读取视图。 类似地,通过有符号规范化格式写入的值 完全等于-2^b的位模式可以更改为-2^b+1 如中所述

也许这就是问题所在?虽然看起来rgba8(unorm)和r32(uint)之间不应该有转换。验证层是否报告了任何警告或错误?当您尝试在图像中存储数据时,图像的布局是什么?别忘了:

对存储映像的加载和存储操作只能对映像执行 在VK_图像_布局_共享_呈现_KHR或VK_图像_布局_概述 布局


一、 实际上,不要使用CREATE_MUTABLE_FORMAT_位,也不要创建多个视图。但是,我不明白为什么下面的事情会起作用:我创建了R32F图像,并将其用作着色器内部的r32UI(使用floatBitsToUint),效果非常好。但也许我达到了一个未定义的行为,使它在这里工作,而在rgba8存储说明符中不工作。是的,我的布局是普通布局,我的图层没有告诉我任何东西。图像视图是什么格式?基础图像是R8G8B8A8_UNORM,但您需要绑定R32_UINT图像视图,因为您在着色器中使用的是r32ui格式(请参见)。