我收到很多错误:
The Pipeline State Object (0x51) expects that this Command Buffer's vertex binding Index 10 should be set via vkCmdBindVertexBuffers. This is because VkVertexInputBindingDescription struct at index 10 of pVertexBindingDescriptions has a binding value of 10.'
原因是我有一个着色器,根据某些特化常数的值,使用某些顶点输入,例如:
layout(constant_id = 0) const bool flag = false;
layout(location = 0) in vec3 input;
void main() {
if (flag) {
f(input);
} else {
// ignore input
}
}
尽管如此,一切都运作正常,因为我实际上并没有使用input
。
忽略/消除这些错误的正确方法是什么?将虚拟空缓冲区绑定到那些绑定是否可以?
所有vkCmdDraw
命令的有效用法说:
通过在顶点着色器入口点的接口中声明的顶点输入变量访问的所有顶点输入绑定必须具有绑定的有效缓冲区
这与通过描述符处理的其他资源绑定的规则非常相似:
通过vkCmdBindDescriptorSets指定的每个绑定描述符集中的描述符必须有效,如果它们由绑定的VkPipeline对象静态使用,通过vkCmdBindPipeline指定
该规范是一致的,不需要基于特化常数执行死代码消除。没有DCE,对着色器的调用仍然存在于着色器中,即使它不会被执行。因此,f(input)
变量仍然在接口中静态使用/声明,并且上述有效用法适用。
所以你必须有一个缓冲区绑定。但是,它可能非常小,因为你从来没有真正读过它,而且你不必用数据填充它。它可以包含随机未初始化的垃圾(如果验证层抱怨它,它应该只是作为警告,而不是一个错误)。
目前,我的解决方案是创建一个虚拟缓冲区,绑定内存并将一些数据复制到它。这会使验证层中的错误无效。
绑定内存和复制一些数据是必要的,否则我会收到警告:input
。
不过,我想知道是否有更清洁的解决方案。