回答您的问题:
通常,在渲染某些内容之前,您会在帧开始时清除。
beginRenderpass 只能由主 commandbuffer 调用,辅助 commandbuffer 不能调用此调用。
基本上,您正在主命令缓冲区中启动一个渲染通道实例(只有您可以提交到队列的命令缓冲区),
这就是您将在每一帧上执行的操作。
但您可以通过调用清除渲染通道实例内的一个或多个颜色和深度/模板附件区域
vkCmdClearAttachments 无论是 LOAD_OP_CLEAR / LOAD_OP_DONT_CARE,
或者如果你想在渲染通道之外使用 vkCmdClearColor/DepthStencilImage。
这可以由主命令缓冲区或辅助命令缓冲区调用。
提示:使用 LOAD_OP_DONT_CARE 可能会在某些驱动程序上进行优化,如果您确定会覆盖前一帧写入的整个屏幕。
因此驱动程序不必为当前的渲染通道从演示缓冲区加载/复制内存来清除它。
您可以在辅助命令缓冲区中使用 vkCmdClearAttachment 命令来清除任何附件。
但是你不能自己提交它们,它必须放在主命令缓冲区中。
这是否意味着每个提交的命令缓冲区都会启动一个新的渲染通道,从而清除附件?
是对 vkCmdBeginRenderPass 的误解吗?
是的,每个提交命令缓冲区都会启动渲染通道并清除 fbo 附件。
当已经运行了一个渲染通道时,它实际上不是开始一个新的渲染通道吗?
Renderpass 包含帧缓冲区的执行顺序。它有状态。
状态在每一帧上被重用。您可以使用具有相同 fbo 的另一个渲染通道(不同状态)。
所以第一个渲染通道可以清除它,而第二个渲染通道在帧开始时不会清除。
您不能在渲染通道实例中调用另一个渲染通道。
您在下面看到的内容无效
Commandbuffer.beginRenderpass(renderpass1, fbo, ClearValues);
Commandbuffer.beginRenderpass(renderpass2, fbo, ClearValues);// ERROR
Commandbuffer.end;
您必须在开始第二个渲染过程之前结束 renderpass1 实例。
应该是这样的
Commandbuffer.beginRenderpass(renderpass1, fbo, ClearValues);
// draw scene
Commandbuffer.end;// renderpass is ended
Commandbuffer.beginRenderpass(renderpass2, fbo, ClearValues);
// draw full screen quad
Commandbuffer.end;
Commandbuffer.beginRenderpass(renderpass3, fbo, ClearValues);
// draw full screen quad
Commandbuffer.end;
假设在上面的例子中,fbo 有 3 个附件。我们在这里使用 3 个渲染通道。
首先:使用 renderpass1 将场景渲染到附件 1。
第二:从附件 1 中读取并进行垂直模糊,然后使用 renderpass2 写入附件 2。
第三:从附件 2 中读取并进行水平模糊并使用 renderpass3 写入交换链图像。
(注意:对于这个特殊的技术,我们不能使用多个子通道,这就是为什么我对同一个 fbo 使用 3 个渲染通道。)