【发布时间】:2016-08-27 10:29:02
【问题描述】:
我一直在阅读 Vulkan 规范和来自 Khronos 的一些示例,但我一般找不到关于不可变采样器的大量信息。
我想要做的是设置一个充满不可变采样器的描述符集(类型为 VK_DESCRIPTOR_TYPE_SAMPLER,而不是 ...COMBINED_IMAGE_SAMPLER),当我想对纹理进行采样时,我会在我的着色器中像这样访问采样器:
layout (location = 0) out vec4 out_color;
layout (set = 0, binding = 0) uniform sampler immutableSampler;
layout (set = 3, binding = 0) uniform texture2D color;
void main()
{
vec4 textureColor = texture(sampler2D(color, immutableSampler), in_uv);
out_color = textureColor;
}
使用这个着色器的想法是:
- 在管道布局中,我在 set 0 中的绑定点 0 处有一个不可变采样器
- 我还有一个描述符集 (3),其中包含在绑定点 0 处描述的图像,我将其绑定为我的命令缓冲区的一部分
- 我将不可变采样器应用于着色器中的图像
- 然后以
sampler2D的身份实际访问图像
但是,我在 Khronos 示例中看到的做法是:
- 在管道布局的绑定点处描述 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER 的不可变采样器(仅提供采样器)
- 创建图像并将其绑定到相同的绑定点(无需采样器)
- 在着色器中以
sampler2D访问图像;您绑定的图像与该绑定处的不可变采样器配对
在 Vulkan 规范中,它没有说明哪种方式是“正确的”,只是指出:
如果
descriptorType指定VK_DESCRIPTOR_TYPE_SAMPLER或VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER类型描述符,则pImmutableSamplers可用于初始化一组不可变采样器。
现在,如果我的着色器按我预期的方式工作,我就不会问这个问题了。我遇到的问题是,在验证后,Vulkan 层抱怨我的 VkPipeline 正在使用从未绑定过的描述符集(设置 0,绑定 0 采样器所在的位置)!即使我在那里绑定垃圾数据,我仍然必须(至少一次)用垃圾更新描述符集,以抑制另一个验证错误。然而与此同时,Vulkan 规范说:
不可变采样器被永久绑定到集合布局中;以后不允许将采样器绑定到描述符集中的不可变采样器槽
因此,甚至不允许将数据绑定到该绑定点!
我现在非常不确定我对不可变采样器的方法是否应该有效,因为它有点模棱两可。规范说我可以绑定一个没有图像的采样器,但是当我这样做时会抱怨,我发现的几个例子是绑定一个组合图像采样器。我只是做错了吗?
如果我的方法假定是有效的并且可以工作,我真的很喜欢这样,因为我正在尝试为 DirectX 12 和 Vulkan 构建一个系统。 DX12 在其“根布局”(管道布局)中占有一席之地,所有不可变采样器都绑定在一起,没有与之关联的图像。我想模仿这种行为以保持渲染器之间的奇偶性,但我非常不确定 Vulkan 是否真的可以做到这一点,而且它在规范中非常模棱两可。
【问题讨论】:
-
您是否使用与构建管道相同的集合布局为集合 0 创建了描述符集合?您在那里谈论使用“垃圾数据”创建一个,但不清楚这意味着什么。由于仅包含不可变采样器的描述符集将没有任何数据。那么“垃圾”从何而来?简而言之,给我们看一些实际的代码。
-
很抱歉给您带来了困惑。在这个例子中,我没有绑定任何设置为 0 的描述符,因为没有什么要绑定的,对吧?我所说的绑定“垃圾数据”实际上是绑定任何描述符集。如果我绑定一个描述符集并且不更新它,尽管我会在验证中遇到另一个错误,所以我需要将它与某种数据绑定以避免这种情况。但还有其他问题;设置 0,绑定 0 是采样器,但规范明确说我不应该在那里绑定采样器。