使用 Vulkan 绘制多个 Windows

Drawing to Multiple Windows Using Vulkan

我正在尝试创建一个可以动态创建额外 windows 的应用程序。每个 window 都会被 Vulkan 吸引,我知道这意味着每个 window 都必须包含它自己的 SwapChain 资源(图像视图、帧缓冲区等)和图形管道(因为它是引用交换链的范围)。我想知道每个 window 是否也必须记住自己的当前队列系列,或者我是否可以假设每个 window 都可以使用相同的队列系列。具体来说,要查找当前队列系列,您需要使用以下方法查明特定队列系列是否支持表面呈现:

VkResult vkGetPhysicalDeviceSurfaceSupportKHR(
    VkPhysicalDevice physicalDevice, 
    uint32_t queueFamilyIndex, 
    VkSurfaceKHR surface, 
    VkBool32* pSupported);

这需要 VkSurfaceKHR,因此需要特定 window 的 HWNDHINSTANCE,但我不确定目前的队列系列是否可能在同一操作系统创建的不同 windows 之间切换,或者如果我可以安全地为每个 window.

使用相同的 windows

同样,在查看 swap chain recreation within the vulkan-tutorial 时,我读到 VKSurfaceFormatKHR::format 在 window 调整大小期间很少更改,这是 render pass 需要的唯一原因在 window 调整大小操作期间重建。在 window 调整大小时跳过此步骤中的渲染通道重新创建有多安全?同一渲染通道用于不同 windows 的效果如何?

如果每个 window 使用相似的图形管道,更具体地说,使用相同的同步对象,将每个 window 附加到相同的命令缓冲区并使用单个 vkQueueSubmit?我问是因为你需要为飞行中的每一帧创建一个命令缓冲区,因此所需的命令缓冲区数量将是 numWindows * numFramesInFlight 感觉过多,但我不确定它是否与飞行中每帧单个大型命令缓冲区(由每个 window 附加)。

顺便说一句,使用 Vulkan 绘制多个 windows 的资源似乎相当稀缺,所以如果有人知道任何好的资源,我将不胜感激。

在 Windows 上,您可以在很大程度上假设一切都可以渲染到一切。但是无论如何你应该检查一下。 vkGetPhysicalDeviceWin32PresentationSupportKHR 不需要表层,并强烈暗示 device\queue 是一种展示能力,而不是例如计算加速器什么的。

Similarly while reviewing swap chain recreation within the vulkan-tutorial I read that VKSurfaceFormatKHR::format rarely changes during window resize and that is the only reason the render pass needs to be reconstructed

它不应该在物理设备和表面的生命周期内改变。如果它可以改变,那将是一个 TOCTOU 问题。

If each window uses a similar graphics pipeline, more specifically uses the same synchronization objects, would it be typical to have each window append to the same command buffer and use a single vkQueueSubmit?

为什么不呢。我的意思是这没有什么“典型”的。但如果可以做到,那么它应该可以做到。否则,如果 windows 不相关,那么它们可能应该拥有自己的私有逻辑设备(甚至实例)。

As an aside, the resources for drawing to multiple windows using Vulkan seems to be fairly scarce

Vulkan 的很多资源都“稀缺”。那是因为 Vulkan 就像乐高积木。一旦你知道了各个部分的作用,那么你就可以在不需要外部帮助的情况下构建任何东西。绘制到多个 windows 与绘制到单个 window 没有什么不同,除非你多次绘制。