【问题标题】:Rendering to different framebuffers with multithreading rendering in Vulkan在 Vulkan 中使用多线程渲染渲染到不同的帧缓冲区
【发布时间】:2021-02-16 20:51:07
【问题描述】:

我试图重现与此视频类似的结果:https://www.youtube.com/watch?v=21UsMuFTN0k 具体来说,我想将整个场景渲染为不同的纹理,并将纹理放入 UI 中,就像视频的截图一样:@987654322 @

视频的作者正在使用 OpenGL 来执行此操作,而我试图在 Vulkan 中实现它。但是,由于我当前的程序使用第三个附件来启用 MSAA 并使用辅助命令缓冲区渲染整个场景,因此我很难将视频中执行此操作的方式转换为 Vulkan。我想我可能不仅需要更多的帧缓冲区,还需要多个渲染通道。简而言之,到目前为止,这是我尝试过的:

  1. 开始第一个渲染通道,渲染通道开始信息设置为较小的渲染区域、屏幕外渲染通道和单独的帧缓冲区。
  2. 将屏幕外渲染通道和帧缓冲区传递给继承信息,并将其传递给辅助命令缓冲区以进行绘制。
  3. 结束第一个渲染过程。
  4. 开始第二个渲染通道,将渲染通道开始信息设置为屏幕的实际大小、主渲染通道和主帧缓冲区。
  5. 将第二个渲染通道和帧缓冲区传递给继承信息,并将其传递给辅助命令缓冲区以进行绘制。
  6. vkCmdExecuteCommands
  7. 结束第二个渲染过程。
  8. 结束命令缓冲区。

然而,当程序执行时,验证层显示:

vkCmdExecuteCommands(): Cannot duplicate VkCommandBuffer 0x1c26226d2e8[] in pCommandBuffers without VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT set. The Vulkan spec states: If any element of pCommandBuffers was not recorded with the VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT flag, it
must not appear more than once in pCommandBuffers

这是否意味着我必须为所有辅助命令缓冲区设置VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT?或者有其他方法可以纠正吗?因为据我所知,设置VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT 有性能成本。 此外,如果我尝试在每个渲染通道中执行 vkExecuteCommands,验证层将显示命令缓冲区已被破坏。

我想知道在 Vulkan 中重现类似结果的正确方法是什么,以及我是否必须将它们分开以便我必须多次执行 vkQueueSubmit

【问题讨论】:

    标签: graphics 3d rendering vulkan framebuffer


    【解决方案1】:

    您正尝试在单个 CommandBuffer 中使用不同的帧缓冲区执行两个 RenderPass。

    RenderPass 执行

    在 Graphics Queue 中执行 RenderPass 可以是无序的,即)不保证 RenderPass 将根据提交顺序执行。由于您在同一个命令缓冲区中记录多遍,这可能是个问题

    使用信号量同步

    在不同的Command Buffers中记录First RenderPass和Second RenderPass,并在提交到队列时使用信号量进行同步。

    使用信号量在 vkQueueSubmit 中为 First RenderPass 发出信号。当您提交 Second RenderPass 时,请使用等待槽中的信号量。

    VKQueueSubmit 中检查 VKSubmitInfo。这用于队列中的内部同步。

    图像布局过渡

    您还必须确保您编写和读取的纹理在适当的 RenderPasses 中处于正确的布局中。

    • 第一个 RenderPass,纹理必须在 COLOR_ATTACHMENT_OPTIMAL
    • 第二个 RenderPass,纹理必须在 SHADER_READ_ONLY_OPTIMAL

    您可以使用 ImageBarrier 或制作第一个渲染通道输出来将附件布局转换为 Read_Only,从而尽早做好准备。

    一般说明

    • 使用 CommandBuffer 记录 First Pass,将纹理的最终 ImageLayout 更改为 SHADER_READ_ONLY_OPTIMAL(如果不使用 ImageBarrier)
    • 使用 CommandBuffer 记录第二遍
    • 提交First Pass并等待信号量
    • 提交 Second Pass 并带有信号 Semaphore

    如果您使用 ImageBarrier,则需要多一个信号量和一个命令缓冲区才能插入到第一和第二通道的中间。

    Command_Buffer_Simultaneous_Use_Bit

    当您需要存储一些需要多次提交到不同队列或记录到不同主缓冲区的命令时,使用同步位。

    这通常用于辅助缓冲区以存储少量命令(可能是许多进程中的通用过程)并根据需要在主缓冲区中记录。

    在你的情况下不需要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 2012-04-08
      • 2011-09-06
      相关资源
      最近更新 更多