Vulkan API — урок 5. Создание объекта

В самом начале необходимо инициализировать библиотеку Вулкан при помощи создания instance (Вообще instance — экземпляр класса, объекта, какой-то образец или пример. Но впредь я буду использовать английское слово, т.к. если вы еще не изучали англоязычную литературу — рано или поздно придется, постепенно будете привыкать, и читать предоставленный в уроках код будет проще, что самое важное, а если изучали — то проблем не возникнет). Instance – связь между вашим приложением и библиотекой Vulkan, и его создание включает в себя передачу некоторых параметров вашего приложения драйверу.

Итак, добавим функцию createInstance в initVulkan:

void initVulkan() {
    createInstance();
}

 Еще добавим член класса для связи дескриптора и instance, по аналогии с управлением ресурсов в предыдущей главе:

private:
VDeleter<VkInstance> instance {vkDestroyInstance};

Функция vkDestroyInstance, как вы могли догадаться, будет очищать instance, которые мы будем создавать. Второй параметр опционален и позволяет вам указать функцию обратного вызова для модифицированного аллокатора. Вы увидите, что большинство функций создания и удаления имеют функцию обратного вызова и мы всегда будем передавать nullptr в качестве параметра.

Итак, что бы создать instance мы в первую очередь должны заполнить структуру с некоторой информацией о нашем приложении. Эти данные технически не обязательны, но они могут оказаться полезными для драйвера для оптимизации конкретного приложения. Данная структура зовется  VkApplicationInfo:

VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Hello Triangle";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "No Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_API_VERSION_1_0;

 Как сказано ранее, большинство структур в Вулкане требуют, что бы вы явно указывали типы в элементах sType. Это так же одна из множества структур с элементом pNext, который указывает на возможное расширение в будущем. Мы же используем стандартную инициализацию и оставляем его значение nullptr.

Большая часть информации в Vulkan проходит через структуры, а не через параметры функций, и нам необходимо заполнить еще одну структуру для создания instance. Эти несколько структур обязательны и передают драйверу Vulkan’a какие глобальные расширения и слои валидации мы хотим использовать. «Глобальные» здесь означает, что они применяются ко всей программе, а не к конкретному устройству, об устройствах мы будем говорить в других уроках.

Первые два параметра понятны (первый блок кода). Следующие два определяют глобальные расширения. Как упоминалось ранее – Vulkan’у требуется расширение для работы с окном, а как раз совершенно случайно GLFW имеет удобную встроенную функцию, которая возвращает необходимые расширения, которые мы и передаем структуре (второй блок кода). Последние два элемента структуры включают глобальные слои проверки. Мы будем говорить о них более подробно через урок, так что оставим их пока пустыми (Третий блок кода).

VkInstanceCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
createInfo.pApplicationInfo = &appInfo;
unsigned int glfwExtensionCount = 0;
const char** glfwExtensions;

glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);

createInfo.enabledExtensionCount = glfwExtensionCount;
createInfo.ppEnabledExtensionNames = glfwExtensions;
createInfo.enabledLayerCount = 0;

 Ну что же, теперь все необходимое указано и мы наконец можем использовать vkCreateInstance:

VkResult result = vkCreateInstance(&createInfo, nullptr, instance.replace());

 Как вы видите, основная структура создания параметров функционирования объекта в Vulkan’e следующая:

  • Указатель на структуру с информацией о создании.
  • Указатель на пользовательсякие функции обратного вызова для аллокатора (все будут равны nullptr в базовых уроках).
  • Указатель на переменную, хранящую дескриптор для нового объекта

 Если все прошло хорошо, то дескриптор instance будет храниться в обертке VkInstance. Почти все функции Vulkan’a возвращают значение типа VkResult, которое содержит значение VK_SUCCESS или код ошибки. Для проверки успешности создания instance просто добавим код:

if (vkCreateInstance(&createInfo, nullptr, instance.replace()) != VK_SUCCESS) {
    throw std::runtime_error("failed to create instance!");
}

Вот и все, таким образом мы создаем объект Vulkan’a. В следующей главе будет описана Проверка Поддержки Расширений и предоставлен общий код двух уроков.

Main Admin

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

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