使用 Vulkan 绘制到多个窗口

问题描述

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

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

这需要 VkSurfaceKHR 以及特定窗口的 HWNDHINSTANCE,但我不确定当前队列系列是否可能在由相同的操作系统,或者我是否可以安全地为每个窗口使用相同的操作系统。

类似地,在查看 swap chain recreation within the vulkan-tutorial 时,我了解到 VKSurfaceFormatKHR::format 在窗口调整大小期间很少发生变化,这是在窗口调整大小操作期间需要重新构建 渲染通道 的唯一原因。在窗口调整大小期间跳过此步骤中的渲染通道重新创建有多安全,以及相同的渲染通道如何用于不同的窗口?

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

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

解决方法

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

同样,在 vulkan-tutorial 中查看交换链娱乐时,我读到 VKSurfaceFormatKHR::format 在窗口调整大小期间很少发生变化,这是需要重建渲染通道的唯一原因

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

如果每个窗口使用相似的图形管道,更具体地说,使用相同的同步对象,那么将每个窗口附加到相同的命令缓冲区并使用单个 vkQueueSubmit 是否是典型的?

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

顺便说一句,使用 Vulkan 绘制到多个窗口的资源似乎相当稀缺

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