Расширения

Последнее обновление: 04.04.2025

Расширения позволяют подключить различную дополнительную функциональность в приложении. Например, поскольку Vulkan — это API, который не зависит от конкретной платформы, то нам нужны расширения для взаимодействия с оконной системой. Для различных задач в Vulkan API есть свои расширения. Вообще расширения представляют структуру , которая имеет два поля:

typedef struct VkExtensionProperties {
    char        extensionName[VK_MAX_EXTENSION_NAME_SIZE];  // имя расширения
    uint32_t    specVersion;                                // версия расширения
} VkExtensionProperties;

Чтобы получить список поддерживаемых расширений перед созданием объекта VKInstance, можно использовать функцию vkEnumerateInstanceExtensionProperties():

VkResult vkEnumerateInstanceExtensionProperties(
    const char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties);

Эта функция принимает следующие параметры:

  • pLayerName: указатель на строку с имем слоя, из которого нужно извлечь расширения. Может быть NULL

  • pPropertyCount: количество расширений

  • pProperties: массив VkExtensionProperties для хранения сведений о расширениях. Может быть NULL

Например, получим все доступные расширения:

#include <vulkan/vulkan.h>
#include <iostream>
#include <vector>

int main() {

    uint32_t extensionCount = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);

    std::vector<VkExtensionProperties> extensions(extensionCount);

    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());

    std::cout << "Available extensions:\n";

    for (const auto& extension : extensions) {
        std::cout << extension.extensionName << std::endl;
    }

    return 0;
}

Разберем код. Вначале получаем количество расширений, оставив все остальные параметры пустыми:

uint32_t extensionCount = 0;
vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);

Далее выделяем вектор для хранения данных расширения (для этого требуется подключить <vector>):

std::vector<VkExtensionProperties> extensions(extensionCount);

Затем мы можем запросить данные расширения:

vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());

Каждая структура VkExtensionProperties содержит имя и версию расширения. Мы можем перебрать их с помощью цикла:

std::cout << "Available extensions:\n";

for (const auto& extension : extensions) {
    std::cout << extension.extensionName << std::endl;
}

В итоге у нас получится вывод типа следующего:

Available extensions:
VK_KHR_device_group_creation
VK_KHR_display
VK_KHR_external_fence_capabilities
VK_KHR_external_memory_capabilities
VK_KHR_external_semaphore_capabilities
VK_KHR_get_display_properties2
VK_KHR_get_physical_device_properties2
VK_KHR_get_surface_capabilities2
VK_KHR_surface
VK_KHR_swapchain
VK_KHR_wayland_surface
VK_KHR_xcb_surface
VK_KHR_xlib_surface
VK_EXT_acquire_drm_display
VK_EXT_acquire_xlib_display
VK_EXT_debug_report
VK_EXT_debug_utils
VK_EXT_direct_mode_display
VK_EXT_display_surface_counter
VK_EXT_headless_surface
VK_EXT_surface_maintenance1
VK_EXT_swapchain_colorspace
VK_KHR_portability_enumeration
VK_LUNARG_direct_driver_loading

Установка расширений

При создании объекта VkInstance можно установить необходимые расширения и их количество. В данном случае мы пока не взаимодействуем ни с какой оконнной системой. Но ради примера приведу работу с библиотекой GLFW для создания оконных приложений, которая имеет удобную встроенную функцию glfwGetRequiredInstanceExtensions(). Эта функция возвращает расширения, необходимые для взаимодействия Vulkan с оконной системой GLFW. Пример установки подобных расширений:

#define GLFW_INCLUDE_VULKAN
// #include <vulkan/vulkan.h>  // макрос GLFW_INCLUDE_VULKAN уже подключает Vulkan
#include <GLFW/glfw3.h>

#include <iostream>

int main() {

    uint32_t glfwExtensionCount = 0;
    const char** glfwExtensions;
    // 1) получаем расширения библиотеки GLFW для Vulkan
    glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);

    VkInstance instance; // объект, который надо создать

    VkInstanceCreateInfo createInfo{};
    createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;

    // 2) устанавливаем расширения
    createInfo.enabledExtensionCount = glfwExtensionCount;
    createInfo.ppEnabledExtensionNames = glfwExtensions;

    // создаем объект VkInstance
    if(vkCreateInstance(&createInfo, nullptr, &instance)!= VK_SUCCESS){
        std::cout << "Unable to create VKInstance" << std::endl;
        return 1;
    }
    else(vkCreateInstance(&createInfo, nullptr, &instance)!= VK_SUCCESS){
        std::cout << "VKInstance created" << std::endl;
    }
    // удаление VKInstance
    vkDestroyInstance(instance, nullptr);

    return 0;
}

Следует отметить, что если расширение по тем или иным причинам не поддерживается, то функция vkCreateInstance возвратит значение VK_ERROR_EXTENSION_NOT_PRESENT.

Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850