vkEnumeratePhysicalDevices() 未找到所有 GPU

Bra*_*ano 8 c++ vulkan

我的系统具有以下规格:

GPU:

  • AMD Radeon(TM) 显卡
  • 采用 Max-Q 设计的 NVIDIA GeForce RTX 2060

中央处理器:

  • AMD Ryzen 9 4900HS 搭载 Radeon 显卡

当我运行 vkEnumeratePhysicalDevices() 时,它仅返回 1 个设备,即我的集成显卡(AMD Radeon(TM) Graphics)。但我发现,如果我使用 Windows 设置中的图形设置(设置 > 系统 > 显示 > 图形设置,然后浏览查找 Vulkan 项目的 build .exe 并将选项设置为高性能)。然而,当我现在运行 Vulkan 项目时,它仍然只在系统上显示 1 个 GPU,只是切换为仅显示 RTX 2060。

这显然不是一个没有代码经验的游戏玩家会做的事情(如果我要使用 Vulkan 完成一款游戏的话)。我推断这可能会发生,因为我使用的是笔记本电脑,所以我尝试禁用所有省电设置,但没有任何改变。

所以我想知道是否有一种方法可以找到 Vulkan 之外系统上的所有 GPU,并将物理设备设置在该列表之外,因为 Vulkan 似乎无法立即找到所有 GPU?

编辑: 我发现如果我在设备管理器中关闭集成 GPU,然后重新打开它,我可以让它看到专用 GPU。

我也收到错误:validation layer: setupLoaderTrampPhysDevs: Failed during dispatch call of 'vkEnumeratePhysicalDevices' to lower layers or loader to get count.

编辑2: 我像这样调用 vkEnumeratePhysicalDevices() :

    void pickPhysicalDevice() {
        uint32_t deviceCount = 0;
        vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
        std::vector<VkPhysicalDevice> devices1(deviceCount);
        
        vkEnumeratePhysicalDevices(instance, &deviceCount, devices1.data());
        if (deviceCount == 0) {
            throw std::runtime_error("Failed to find GPUs with Vulkan support.");
        }

        std::vector<VkPhysicalDevice> devices(deviceCount);
        vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());

        std::cout << "Physical Devices(" << deviceCount << "):\n";

        for (const auto& device : devices) {
            //get the device properties
            VkPhysicalDeviceProperties props;
            vkGetPhysicalDeviceProperties(device, &props);
            //print the device and whether it is suitable or not
            std::cout << props.deviceName << " -- " <<  (isDeviceSuitable(device) && props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU ? "suitable GPU" : "unsuitable GPU") << std::endl;

            if (isDeviceSuitable(device) && props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
                std::cout << "Device ^ accepted" << std::endl;
                physicalDevice = device;
                break;
            }
        }

        if (physicalDevice == VK_NULL_HANDLE) {
            throw std::runtime_error("Failed to find a suitable GPU.");
        }


    }
Run Code Online (Sandbox Code Playgroud)

我的基本 Vulkan 代码是根据以下网站建模的:https ://vulkan-tutorial.com/Drawing_a_triangle/Setup/Physical_devices_and_queue_families

Bra*_*ano 10

在大量阅读了互联网上基本上每个包含函数名称 vkEnumeratePhysicalDevices() 的论坛之后,并且在这个问题长达一周的赏金仍未得到解答之后,我找到了答案。它位于 AMD 和 Nvidia 驱动程序之间的互操作中,至少对于我的笔记本电脑 (ROG Zephyrus G14) 来说是这样。隐藏答案的论坛在这里:https ://github.com/KhronosGroup/Vulkan-Loader/issues/552

\n

根据我从他们在 GitHub 上所说的话了解到,正如 @pdaniel-nv 所描述的那样,验证层 VK_LAYER_AMD_swichable_graphics 和 VK_LAYER_NV_optimus 都希望选择高性能 GPU,但他们只想过滤 AMD 或 Nvidia GPU分别。(VK_LAYER_AMD_swichable_graphics 希望使用 AMD 专用 GPU,而 VK_LAYER_NV_optimus 希望使用 Nvidia 专用 GPU)因此,当使用这些层时,AMD 和 Nvidia 的驱动程序都会过滤掉彼此的 GPU,因此可用 GPU 列表最终什么也没有。

\n

因此,基本上解决方案是通过 Vulkan 配置器禁用其中一层或两层,或者更好的是在代码中禁用这些层。唯一的缺点是开发人员现在必须编写自定义代码来确定哪个 GPU 最适合他们的程序\xe2\x80\x94,老实说在我看来这没什么大不了的。

\n