在 Vulkan 中,如何将每个单独的视频卡与它们直接连接的显示器相关联

In Vulkan how can you associate each individual video card with monitors they're directly connected to

我有两台显示器,每台都连接到不同的 GPU。两个 GPU 都在一台机器上,我想 运行 一个应用程序。我有两个独立的视图,我想使用 GPU/Monitor 集来渲染每个视图。我可以创建多个表面和设备,但我想确保我将每个表面与其显示器插入的 GPU 相关联,否则我怀疑我会遇到性能问题,因为帧缓冲区需要在卡之间来回复制。

我正在使用全屏界面,我想这是 vkGetPhysicalDeviceSurfaceSupportKHR 会告诉我的。但是,VkSurfaceKHR 似乎都是每个 VkPhysicalDevice 的有效目标,所以我猜这是 OS 和 GPU 驱动程序可以处理的事情,但是是否有关于哪个表面最适合关联的提示使用设备?

据我所知,扩展 VK_KHR_display 是实现此目的的一种方法,但它在我的 Windows 10 机器或 Nvidia GPU 上不可用。它似乎仅适用于嵌入式平台。但是,它可以让您列出每个设备的附加显示器,这正是我正在寻找的:https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch29s03.html

docs 中的这句话让我相信 Windows 可能不支持它:

Issues

1) Does Win32 need a way to query for compatibility between a particular physical device and a specific screen? Compatibility between a physical device and a window generally only depends on what screen the window is on. However, there is not an obvious way to identify a screen without already having a window on the screen.

RESOLVED: No. While it may be useful, there is not a clear way to do this on Win32. However, a method was added to query support for presenting to the windows desktop as a whole.

但是,我仍然有兴趣了解是否有解决方法可以达到类似的效果。

有两个扩展可用于此类事情:您提到的一个 VK_KHR_display 和第二个称为 VK_KHR_display_swapchain,它允许您直接在设备的显示器上创建交换链,而无需任何底层 window 系统。

但是 Windows 很少支持这些扩展。在核心 Vulkan API 中,无法实现您想要的。而且恐怕您需要使用 OS 特定的功能(在这种情况下您需要依赖 WinAPI 功能)。

[编辑]

你看到这个问题了吗? How can you get the display adapter used for a particular monitor in Windows? 如果没有,也许它会帮助你开始你的研究。

正如您已经发现的,在 Win32 上您需要使用 OS 窗口系统来选择您想要使用的显示器,使用 Window API。可以直截了当

但是,如果您打算编写简单且不可知的 OS 代码,请检查 GLFW 项目。它具有高级功能来处理所有主要 OS 上的 windows。

检查:

GLFW monitor Guide

GLFW Vulkan integration

GLFW on its own words:

GLFW is a free, Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan application development. It provides a simple, platform-independent API for creating windows, contexts and surfaces, reading input, handling events, etc.

终于想出一个解决办法:

Direct X 实际上通过使用 IDXGIAdapter::EnumOutputs 函数来支持这一点。这使您可以列出连接到每个 GPU 的显示器。然后使用这两个扩展,您可以将此信息重新映射到 Vulkan:

您可以使用这些从 VkPhysicalDeviceIDPropertiesKHR 获取 deviceLUID。 然后可以将其与 Direct X DXGI_ADAPTER_DESC

中此结构的 Luid 进行比较

您也可以使用glfwGetWin32Window 来获取显示器的HWND。这使您可以将 vulkan 表面与直接 x 监视器相关联。

您现在拥有将 vulkan 表面与其实际连接到的设备相关联所需的所有信息。

至少在我的应用程序中,正确设置会导致性能的显着差异。

如果 Windows 只支持 VK_KHR_displayVK_KHR_display_swapchain 扩展作为 Linux does.

,这一切都会更简单(并且跨平台)