畏惧Vulkan吧

最近在跟着官方的Tutorial学Vulkan,不得不说深感其琐碎与复杂,画一个完整设置的三角形就需要大概1000行代码,这在传统的图形API上是难以想象的。但另一方面在画完三角形后,我又感觉自己打通了任督二脉,觉得自己好像抓住了这套渲染流程的精髓。于是在我加入Depth Buffer进入到3D世界时,就发现了一个奇妙的问题。

你可能会问,你这是传了个什么图上来,怎么是全黑的。是的,我也想问,为什么是全黑的,为什么我加了个深度测试后就变成全黑了,起初我是以为我的pipeline的配置写的有问题。

1
2
3
4
5
6
7
8
9
10
vk::PipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo;
depthStencilStateCreateInfo.setDepthTestEnable(true)
.setDepthWriteEnable(true)
.setDepthBoundsTestEnable(false)
.setStencilTestEnable(false)
.setMinDepthBounds(0.0f)
.setMaxDepthBounds(1.0f)
.setDepthCompareOp(vk::CompareOp::eLess);

pipelineCreateInfo.setPDepthStencilState(&depthStencilStateCreateInfo);

但我仔细一看,我寻思这也没问题啊。故我又去打开RenderDoc看了看我的每个pass的输出。

???这是什么,为什么这么糊并且没有显示到的我的屏幕上。

然后当我放大了来看之后,我发现上面满满的都是LOAD DONTCARE,于是我立马就意识到发生了什么, 是我在RenderPass建立depthAttachment出了问题。

1
2
3
4
5
6
7
8
9
vk::AttachmentDescription depthAttachment;
depthAttachment.setFormat(vk::Format::eD32Sfloat)
.setInitialLayout(vk::ImageLayout::eUndefined)
.setFinalLayout(vk::ImageLayout::eDepthStencilAttachmentOptimal)
.setSamples(vk::SampleCountFlagBits::e1)
.setStencilLoadOp(vk::AttachmentLoadOp::eDontCare)
.setStencilStoreOp(vk::AttachmentStoreOp::eDontCare)
.setLoadOp(vk::AttachmentLoadOp::eClear) // 万恶之首,应该写成eClear,并在后面的渲染流程中传入ClearValue
.setStoreOp(vk::AttachmentStoreOp::eDontCare);

在改为eClear并设置完clearValue之后,我们就可以重新看到图像了。

image.png

真不错,鼓掌鼓掌,但是另一方面更让我体会到Vulkan里面稍微写错一点,就能让自己排查半天,而且很明显这种错误是完全不可能被验证层找到,只能通过外部工具来Debug,唉,还是得畏惧Vulkan啊,更别说这里还没涉及到什么内存管理和同步之类的复杂话题。感觉好日子还在后头了。