Search code examples
graphicsrenderingrendervulkan

Vulkan can you do nested render passes?


Is it possible to call a render pass to a different target while a render pass is already being recorded?

In pseudo code (using the hpp header) something like this:

cmd1.beginRenderPass(&render_pass_info, vk::SubpassContents::eInline); // main fb
cmd2.beginRenderPass(&render_pass_info, vk::SubpassContents::eInline); // off screen fb
// Render to off screen target
cmd2.endRenderPass();

// Render to main target
cmd1.endRenderPass();

Solution

  • I'm not sure how your pseudo-code pertains to the question in your title. See, you start a render pass using cmd1, which presumably represents a command buffer. Then you start a render pass using cmd2, which presumably represents a separate command buffer. Since both of these commands are expected to execute correctly, that means both of them are primary command buffers (since you cannot begin a render pass in a secondary command buffer).

    Coupled with that is the fact that, if you start a render pass in a command buffer, you must terminate that render pass in the same CB. So there's no way for render passes in different primary command buffers to overlap in terms of submission order of commands.

    So... what's the question? The only order of commands that matters to Vulkan is submission order: the order in which command buffers are submitted to a queue, and the order of the commands within each buffer. Vulkan does not care about the order in which commands in one CB are recorded relative to another CB.

    So the queue will see one of the render passes start, then it ends, then the next starts, then it ends. The code in your question does not "nest" render passes.

    The only possible "nesting" of render passes that could happen would be if you're doing it to the same CB. And no, you cannot nest them.

    And it would serve no purpose if you could.

    If your "render to main target" operation requires that "render to off screen target" is complete, then that's identical to two sequential render pass operations with appropriate barriers/dependencies in place. And if neither depends on the other then that's identical to two sequential render pass operations with no barriers/dependencies between them.

    The only place where that might make sense is if you're rendering to the "main target" for a while, then want to render to "off screen target" in a way that uses the results of "main target," then want to go back to "main target"in a way that uses the results of "off screen target". But that's just one render pass, with 3 subpasses which use different attachments, along with appropriate dependencies/input targets between them.