Vulkan API — урок 11. Семейства очередей (+листинг)

Семейства очередей – некая возможность для разработчиков железа при необходимости разбить выполняемые задачи на типы, тем самым оптимизировав работу этих самых операций. Конечно далеко не факт, что нужные нам операции (например рендеринг и вывод) будут выполняться разными семействами очередей, но в итоге мы учтем все возможные ситуации.

Нам нужно проверить какие семейства очередей поддерживаются устройством и какие их них поддерживают нужные нам (в данный момент) команды. Для этого добавим новую функцию findQueueFamilies , которая и разыщет все нужные нам семейства. Сейчас мы ищи только очереди, поддерживающие графические команды, но со временем сможет расширять функцию для поиска всего, что может понадобится.

Эта функция будет возвращать индекс нужного семейства. И как и раньше — воспользуемся структурой, в которой значение «-1» будет означать «не найдено»:

struct QueueFamilyIndices {
    int graphicsFamily = -1;

    bool isComplete() {
        return graphicsFamily >= 0;
    }
};

И сама функция.

QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) {
    QueueFamilyIndices indices;

    ...

    return indices;
};

Процесс получения списка семей аналогичен большинству других аналогичных процессов в Vulkan’e:

uint32_t queueFamilyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);

std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());

Структура VkQueueFamilyProperties содержит некоторые детали о семействе очередей, включая тип поддерживаемых опреаций и максимальное количество очередей, которые можно создать для данного семейства. Нам необходимо найти как минимум одну очередь с поддержкой VK_QUEUE_GRAPHICS_BIT.

int i = 0;
for (const auto& queueFamily : queueFamilies) {
    if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
        indices.graphicsFamily = i;
    }

    if (indices.isComplete()) {
        break;
    }

    i++;
}

Теперь, когда нужная очередь была найдена, мы можем использовать все вышеописанное для определения, а подходит ли нам выбранное устройство, ведь устройство должно поддерживать необходимый функционал, о чем говорилось ранее.

bool isDeviceSuitable(VkPhysicalDevice device) {
    QueueFamilyIndices indices = findQueueFamilies(device);

    return indices.isComplete();
}

Великолепно, в следующих уроках мы поговорим о том, как создать логическое устройство и работать с очередями, созданными на базе выбранного семейства очередей.

Листинг всего пройденного.

Main Admin

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *