我的图像格式为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,它也能正常工作。)
你有解决方案吗?
答案 0 :(得分:1)
Vulkan规范保证只有R32_UINT和R32_SINT格式的存储映像(VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT)必须支持原子操作。实现可能也会为其他格式添加此类支持,但这不是强制性的。因此,原子操作不适用于rgba8格式并不奇怪。
下一步。您可以使用与图像格式不同的格式创建图像视图。在这种情况下,图像视图的格式必须与图像的格式兼容。对于R8G8B8A8格式,SINT和UINT R32格式兼容(具有相同的位数)。但是为了能够创建具有不同格式的图像视图,必须使用VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT标志创建图像本身。
最后一件事 - 规范中有关于格式兼容性/可变图像的注释:
旨在与一种视图格式一起使用的值可能不完全正确 通过不同格式书写或阅读时保留。对于 例如,恰好具有a的位模式的整数值 当浮点数或NaN可以被刷新或标准化时 通过浮点格式的视图写入或读取。 同样,通过已签名的规范化格式写入的值 一个完全等于-2 ^ b 的位模式可以改为-2 ^ b + 1 as 在Conversion from Normalized Fixed-Point to Floating-Point中描述。
也许这就是问题所在?虽然似乎rgba8(unorm)和r32(uint)之间不应该有转换。验证层是否报告了任何警告或错误?当您尝试在其中存储数据时,您的图像是什么布局?别忘了:
只能在图像上对存储图像进行加载和存储操作 在VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR或 VK_IMAGE_LAYOUT_GENERAL 布局。