选择一个物理设备

创建VkInstance后,我们需要查询系统中的显卡设备,选择一个支持我们需要的特性的设备使用。Vulkan允许我们选择任意数量的显卡设备,并能够同时使用它们,但在这里,我们只使用第一个满足我们需求的显卡设备。

我们首先添加一个叫做pickPhysicalDevice的函数,然后在initVulkan函数中调用它:

void initVulkan() {
    createInstance();
    setupDebugCallback();
    pickPhysicalDevice();
}

void pickPhysicalDevice() {

}

我们使用VkPhysicalDevice对象来存储我们选择使用的显卡信息。这一对象可以在VkInstance进行清除操作时,自动清除自己,所以我们不需要再cleanup函数中对它进行清除。

VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;

请求显卡列表和请求扩展列表的操作类似,首先需要请求显卡的数量。

uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);

如果可用的显卡设备数量为0,显然应用程序无法继续运行。

if (deviceCount == 0) {
    throw std::runtime_error("failed to find GPUs with Vulkan support!");
}

获取完设备数量后,我们就可以分配数组来存储VkPhysicalDevice对象。

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

现在,让我们检查获取的设备能否满足我们的需求:

bool isDeviceSuitable(VkPhysicalDevice device) {
    return true;
}

我们检查设备,并选择使用第一个满足需求的设备:

for (const auto& device : devices) {
    if (isDeviceSuitable(device)) {
        physicalDevice = device;
        break;
    }
}

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

下一节,我们开始具体说明isDeviceSuitable函数所进行的检查,随着我们使用的特性增多,这一函数所包含的检查也越来越多。