I have two types of vertices, each with it's own vertex and fragment shaders:
Vertex Type "A" => vertex shader "A" => fragment shader "A"
Vertex Type "B" => vertex shader "B" => fragment shader "B"
I need to keep vertices and shaders separate because they are fundamentally different.
I understand that I need two graphicsPipelines, because I have 4 stages (two vert, two frag) but they are not applied sequentially. With a single pipeline I can do this:
VkPipelineShaderStageCreateInfo shaderStages[] = {
vertShaderStageCreateInfo,
fragShaderStageCreateInfo
};
graphicsPipelineCreateInfo.pStages = shaderStages;
This is pretty obvious what it means. But I have 4 shader modules (shaders) and therefore 4 "stages", and on one pipeline I can only define one "stage sequence", like so:
Stage sequence: Stage 1 => Stage 2 => Stage 3 => Stage 4
This would be multipass rendering (I guess!).
But I need two separate stage sequences:
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)
So that's why I need two pipelines, one for each "vertex type/shader set" (A and B).
QUESTION: Is this correct or am I misunderstanding pipelines?
Now, with the two pipelines (and pipelinLayouts) I have to record command buffers. In the single-pipeline approach I bind pipeline, pipelineLayout, descriptors and vertices:
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(...);
}
Can I draw two pipelines in one drawcall, like this?
BEGIN RENDER PASS
BIND PIPELINE A, DESCRIPTORS, VERTEX_BUFFER A
DRAW A
BIND PIPELINE B, DESCRIPTORS, VERTEX_BUFFER B
DRAW B
END RENDER PASS
Is this even possible? Or do I have to register two RENDER PASSES in the same command buffer (would this be multipass rendering)?
Or worse, do I have to register two command buffers and then do two VkSubmitInfo() one after the other? And by doing so, will I have to wait for the first command buffer to end ('VkQueueWaitIdle' or use semaphores), before I can submit the second command buffer? Or can I submit both command buffers immediately (it is called "queue" after all)?