在Vulkan中,如何将每个独立的显卡与直接连接的显示器关联起来?

4
我有两个显示器,分别连接到不同的GPU。这两个GPU都在一台机器上,我想运行一个应用程序。我有两个独立的视图,并且我想使用一个GPU/显示器集合来渲染每个视图。我可以创建多个表面和设备,但我想确保将每个表面与其所连接的GPU的监视器相关联,否则我怀疑我会遇到性能问题,因为帧缓冲区需要在卡之间来回复制。
我正在使用全屏表面,我认为这是vkGetPhysicalDeviceSurfaceSupportKHR会告诉我的内容。然而,每个VkPhysicalDevice似乎都是每个VkSurfaceKHR的有效目标,所以我猜这是操作系统和GPU驱动程序可以处理的事情,但是否有任何提示可以将哪个表面与设备关联起来?
据我所知,扩展VK_KHR_display是实现此目的的一种方法,但它在我的Windows 10机器或Nvidia GPU上不可用。它似乎只适用于嵌入式平台。但它允许您列出每个设备附加的显示器,这正是我要寻找的:https://vulkan.lunarg.com/doc/view/1.0.30.0/linux/vkspec.chunked/ch29s03.html 这段引用来自文档,让我相信这可能不支持Windows:

问题

1)Win32需要一种方法来查询特定物理设备和特定屏幕之间的兼容性吗?物理设备与窗口之间的兼容性通常仅取决于窗口所在的屏幕。但是,没有明显的方法来识别屏幕,而不必已经在屏幕上拥有窗口。

解决:否。虽然它可能很有用,但在Win32上没有清晰的方法来执行此操作。但是,添加了一种方法来查询对整个Windows桌面进行呈现的支持。

但是,我仍然有兴趣听听是否有解决方法可以实现类似的效果。

你打算如何确保特定的窗口停留在特定的显示器上? - Nicol Bolas
1
通过创建无边框全屏窗口。我还没有确认是否可以创建两个真正的全屏窗口(每个显示器一个),但对于此应用程序,我不关心传统的窗口化,将视图锁定在同一位置非常适合我的目的。 - Lockyer
3个回答

6

最终找到了这个问题的解决方法:

实际上,DirectX通过使用IDXGIAdapter :: EnumOutputs函数支持此功能。这使您可以列出连接到每个GPU的监视器。然后使用这两个扩展,您可以将此信息重新映射到Vulkan中:

您可以使用这些来从VkPhysicalDeviceIDPropertiesKHR获取deviceLUID。 然后可以将其与DirectX中此结构中的Luid进行比较DXGI_ADAPTER_DESC

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

你现在已经拥有了所有必要的信息,可以将Vulkan表面与实际连接的设备进行关联。
至少在我的应用程序中,正确设置这一点会导致性能显著提高。
如果Windows像Linux一样支持VK_KHR_display和VK_KHR_display_swapchain扩展,那么这一切都会更加简单(且跨平台)。

1
有两个扩展非常适合这样的事情:你提到的一个叫做VK_KHR_display,另一个叫做VK_KHR_display_swapchain,它允许您在设备的显示器上直接创建交换链,而无需任何底层窗口系统。

但是这些扩展在Windows上很少被支持。在核心Vulkan API中,没有办法实现您想要的功能。恐怕您需要使用特定于操作系统的函数(在这种情况下,您需要依赖WinAPI函数)。

[编辑]

您看到这个问题了吗?如何在Windows中获取用于特定监视器的显示适配器?如果没有,也许它可以帮助您开始研究。


0

正如你已经发现的那样,在 Win32 上,你需要使用操作系统窗口系统来选择你想要使用的显示器,使用 Window API。它可以很简单直接。

但是,如果你打算编写简单而不受限制的操作系统代码,请查看 GLFW 项目。它具有高级功能,可处理所有主要操作系统上的窗口。

请查看:

GLFW 监视器指南

GLFW Vulkan 集成

GLFW 的原话:

GLFW 是一个用于 OpenGL、OpenGL ES 和 Vulkan 应用程序开发的免费、开源、多平台库。它提供了一个简单、平台无关的 API 来创建窗口、上下文和表面、读取输入、处理事件等。


是的,我已经在使用GLFW了,但如果它不能处理我的特殊情况,我也愿意放弃这种抽象。这里的特定问题不是创建窗口和选择显示器,而是将这些显示器与它们物理连接的GPU关联起来。如果您能做到这一点,您应该能够避免在卡之间来回复制帧缓冲区时产生的一些开销,假设每个卡的输出是独立的。 - Lockyer
明白了。您有一个非常特殊的情况,其中有两个不同的GPU具有独立输出,并且有一些可能发生交叉显示的机会。我想主要问题是应用程序使用弱卡(内置Intel)而不是强大的卡(离散AMD / Nvidia)。交叉显示可能不是一个大问题,因为它们都被转换为2D图像并由窗口系统绘制。请注意,这些是我的假设,请查看文档并在必要时进行测试。 - Alex Byrth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接