【发布时间】:2021-05-02 12:56:42
【问题描述】:
我有两种类型的顶点,每种都有自己的顶点和片段着色器:
Vertex Type "A" => vertex shader "A" => fragment shader "A"
Vertex Type "B" => vertex shader "B" => fragment shader "B"
我需要将顶点和着色器分开,因为它们根本不同。
我知道我需要两个 graphicsPipelines,因为我有 4 个阶段(两个垂直,两个片段),但它们不是按顺序应用的。使用单个管道我可以做到这一点:
VkPipelineShaderStageCreateInfo shaderStages[] = {
vertShaderStageCreateInfo,
fragShaderStageCreateInfo
};
graphicsPipelineCreateInfo.pStages = shaderStages;
这是很明显的意思。但是我有 4 个着色器模块(着色器),因此有 4 个“阶段”,在一条管道上我只能定义一个“阶段序列”,如下所示:
Stage sequence: Stage 1 => Stage 2 => Stage 3 => Stage 4
这将是多通道渲染(我猜!)。
但我需要两个单独的阶段序列:
Stage sequence A: Stage 1 (vertex type A) => Stage 2 (vertex type A)
Stage sequence B: Stage 1 (vertex type B) => Stage 2 (vertex type B)
这就是为什么我需要两条管道,一个用于每个“顶点类型/着色器集”(A 和 B)。
问题:这是正确的还是我误解了管道?
现在,我必须使用两个管道(和 pipelinLayouts)来记录命令缓冲区。在单管道方法中,我绑定了管道、管道布局、描述符和顶点:
void recordCommands(
VkPipeline& graphicsPipeline,
VkPipelineLayout& pipelineLayout,
VkBuffer& vertexBuffer)
{
vkCmdBeginRenderPass(...);
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr);
vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets);
vkCmdDraw(...);
vkCmdEndRenderPass(...);
}
我可以像这样在一个 drawcall 中绘制两条管道吗?
BEGIN RENDER PASS
BIND PIPELINE A, DESCRIPTORS, VERTEX_BUFFER A
DRAW A
BIND PIPELINE B, DESCRIPTORS, VERTEX_BUFFER B
DRAW B
END RENDER PASS
这甚至可能吗?还是我必须在同一个命令缓冲区中注册两个 RENDER PASSES(这将是多通道渲染)?
或者更糟糕的是,我是否必须注册两个命令缓冲区,然后一个接一个地执行两个 VkSubmitInfo()?通过这样做,我是否必须等待第一个命令缓冲区结束('VkQueueWaitIdle' 或使用信号量),然后才能提交第二个命令缓冲区?或者我可以立即提交两个命令缓冲区(毕竟它被称为“队列”)?
【问题讨论】:
标签: vulkan