【问题标题】:Vulkan ignoring GLSL image format qualifierVulkan 忽略 GLSL 图像格式限定符
【发布时间】:2021-02-17 01:54:09
【问题描述】:

我有一个计算着色器,它使用imageLoad 读取带符号的标准化整数图像。

图像本身(包含正值和负值)被创建为R16G16_SNORM,并由片段着色器在之前的 gpass 中写入。 在计算着色器中绑定到descriptorsetlayout 绑定的imageview 也使用相同的R16G16_SNORM 格式创建。

一切都按预期进行。

昨天我意识到在计算着色器中我使用了错误的图像格式限定符rg16。 有点困惑(我无法理解它如何在读取无符号归一化值时正常工作)我更正为 rg16_snorm,然后.. 没有任何改变。

我进行了几次测试(我什至指定了rg16f)并且总是得到相同的(正确,[-1,1] 签名)结果。

似乎 Vulkan(至少我的实现)默默地忽略了任何图像格式限定符,并退回到(我猜)绑定到描述符集的图像视图格式。

这似乎符合有关创建图像视图格式的规范

format 是一个 VkFormat,描述了用于解释图像中的纹素块的格式和类型

但是在附录 A(SPIR-V 的 Vulkan 环境 - “SPIR-V 图像格式和 Vulkan 格式之间的兼容性”)中,Rg16 和 Rg16Snorm 之间有明显的区别。所以:

这是错误还是功能?

我正在使用 ubuntu 20.04 下的 Nvidia 2070 Super

更新

初始图像写入操作是片段着色器颜色附件输出的结果,因此没有描述符集布局绑定声明。片段着色器将vec2 输出到由活动帧缓冲区和渲染通道指定的R16G16_SNORM 颜色附件。

生成的图像(在相关障碍之后)然后由计算着色器作为图像/图像加载操作读取(正确,尽管布局限定符错误)。

请注意,验证层已启用且处于静默状态。

另请注意,使用rg16rg16frg16_snorm,生成的值远非随机,并且与预期值(正数和负数)完全匹配。

【问题讨论】:

    标签: vulkan


    【解决方案1】:

    你得到的是未定义的行为。

    对图像写入操作进行了验证检查,以防止 OpTypeImage 的格式(相当于 GLSL 中的 layout 格式说明符)与支持 VkImageView 的格式不兼容:

    如果OpTypeImage的图像格式与VkImageView的格式不兼容,写入会导致图像内存的内容变得不确定。

    请注意,当它说“兼容”时,并不意味着图像视图兼容;这意味着"exactly match"。您的 OpTypeImage 格式与着色器的格式不完全匹配,因此您的写入未定义。而“未定义”可以表示“就像您指定了正确的格式一样工作”。

    【讨论】:

    • 谢谢 Nicol Bolas,我担心我错过了一些有用的信息,所以我在问题中添加了一个更新,这应该会影响你的回答,对此感到抱歉。请看更新部分。谢谢
    • 我在第 15.3.1 节中发现:“在许多情况下,SPIR-V 指令可能与采样器、图像视图或两者不匹配。[...]情况下,返回的纹素的值是未定义的。”可能的原因之一是:“SPIR-V 图像格式与图像视图的格式不兼容”。会不会是布局声明与实际图像格式不兼容(即完全相等),而产生的读取,至少在这个实现中,使用了 imageview 格式?
    • 但是具有错误布局限定符的 imageLoad 可以算作 SPIR-V 指令不匹配吗?
    猜你喜欢
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多