From 8a9ef1b0cf8fe0632b7dae86631d42a431ddbef8 Mon Sep 17 00:00:00 2001 From: "re.kovalev" Date: Thu, 10 Feb 2022 17:15:22 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B8=20=D1=81=D0=BB=D0=BE=D0=B8=20=D1=83?= =?UTF-8?q?=D1=81=D1=82=D1=80=D0=BE=D0=B9=D1=81=D1=82=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/vk.h | 4 +-- src/vk.cpp | 97 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/include/vk.h b/include/vk.h index a0304a6..1bb1f45 100644 --- a/include/vk.h +++ b/include/vk.h @@ -24,8 +24,8 @@ class Vulkan void createInstance(); // Создание экземпяра Vulkan - void selectPhysicalDevice(); // Выбор физического устройства - void createLogicalDevice(); // Создание логического устройства + void selectPhysicalDevice(std::vector &deviceExtensions); // Выбор физического устройства + void createLogicalDevice(std::vector &deviceExtensions); // Создание логического устройства }; #endif // VK_H \ No newline at end of file diff --git a/src/vk.cpp b/src/vk.cpp index 1b72a22..997cae0 100644 --- a/src/vk.cpp +++ b/src/vk.cpp @@ -8,8 +8,10 @@ void Vulkan::init() { createInstance(); // Создание экземпяра - selectPhysicalDevice(); // Выбор физического устройства - createLogicalDevice(); // Создание физического устройства + + std::vector deviceExtensions({""}); + selectPhysicalDevice(deviceExtensions); // Выбор физического устройства + createLogicalDevice(deviceExtensions); // Создание физического устройства } // завершение работы @@ -59,6 +61,45 @@ bool checkValidationLayerSupport(std::vector requestedLayers, std: return unavailableLayers.size() == 0; } +// Проверка слоев устройства на доступность. Возвращает true, если все слои доступны +// по ссылке заполняет вектор недоступных слоев +bool checkDeviceLayerSupport(VkPhysicalDevice physicalDevice, std::vector requestedLayers, std::vector & unavailableLayers) +{ + bool layerAvailable; // флаг доступности слоя для цикла + + // Первым вызовом определим кол-во доступных слоев + uint32_t layerCount; + vkEnumerateDeviceLayerProperties(physicalDevice, &layerCount, nullptr); + + // Вторым вызовом запишем в вектор доступные слои + std::vector availableLayers(layerCount); + vkEnumerateDeviceLayerProperties(physicalDevice, &layerCount, availableLayers.data()); + + // Цикл по запрошенным слоям + for (const char* layerName : requestedLayers) + { + layerAvailable = false; + + // Цикл по доступным слоям + for (const auto& layerProperties : availableLayers) + { + // Сравнение строк + if (strcmp(layerName, layerProperties.layerName) == 0) + { + layerAvailable = true; + break; + } + } + + // Если слой не найден то заносим в массив недоступных + if (!layerAvailable) { + unavailableLayers.push_back(layerName); + } + } + + return unavailableLayers.size() == 0; +} + void Vulkan::createInstance() { // Структура с данными о приложении @@ -120,8 +161,9 @@ void Vulkan::createInstance() } } +#include // Выбор физического устройства на основании требований -PhysicalDevice selectPhysicalDeviceByProperties(std::vector & devices) +PhysicalDevice selectPhysicalDeviceByProperties(std::vector & devices, std::vector &requestedExtensions) { int i; PhysicalDevice result; // физическое устройство (PhysicalDevice.h) @@ -140,8 +182,26 @@ PhysicalDevice selectPhysicalDeviceByProperties(std::vector & result.queueFamilyProperties.resize(queueFamilyPropertiesCount); vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyPropertiesCount, result.queueFamilyProperties.data()); + // Данные по расширениям + uint32_t extensionsCount = 0; + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionsCount, nullptr); + std::vector extensions(extensionsCount); + vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionsCount, extensions.data()); + + int availableExtensionsCount = 0; + // подсчитаем совпадающие расширения + for (auto extension1 : requestedExtensions) + for (auto extension2 : extensions) + if (strcmp(extension1, extension2.extensionName) == 0) + { + availableExtensionsCount++; + break; + } + + // Производим оценку - if (result.features.geometryShader + if (availableExtensionsCount == requestedExtensions.size() + && result.features.geometryShader && 4000 < result.memory.memoryHeaps[0].size / 1000 / 1000) return result; } @@ -150,7 +210,7 @@ PhysicalDevice selectPhysicalDeviceByProperties(std::vector & } // Выбор физического устройства -void Vulkan::selectPhysicalDevice() +void Vulkan::selectPhysicalDevice(std::vector &deviceExtensions) { // Узнаем количество доступных устройств uint32_t deviceCount = 0; @@ -167,7 +227,7 @@ void Vulkan::selectPhysicalDevice() vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); // Выбор физического устройства на основании требований - physicalDevice = selectPhysicalDeviceByProperties(devices); + physicalDevice = selectPhysicalDeviceByProperties(devices, deviceExtensions); // Если не удалось выбрать подходящее требованием устройство - выдадим исключение if (!physicalDevice.device) @@ -176,7 +236,7 @@ void Vulkan::selectPhysicalDevice() } } -void Vulkan::createLogicalDevice() +void Vulkan::createLogicalDevice(std::vector &deviceExtensions) { // Приоритеты очередей float priority[1] = {1}; @@ -186,14 +246,33 @@ void Vulkan::createLogicalDevice() queueCreateInfo.queueFamilyIndex = physicalDevice.pickQueueFamily(VK_QUEUE_GRAPHICS_BIT); queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = priority; + + // слои для логического устройства + std::vector layers; + // Подключение других слоев + // layers.push_back(ИМЯ_СЛОЯ); + + // Проверим доступность слоев + std::vector unavailableLayers; + if (!checkDeviceLayerSupport(physicalDevice.device, layers, unavailableLayers)) + { + std::cout << "Запрошены недоступные слои:\n"; + // Цикл по недоступным слоям + for (const char* layer : unavailableLayers) + std::cout << layer << "\n"; + // Отправим исключение об отсутствующем слое + throw std::runtime_error("Requested layer unavailable"); + } // Данные о создаваемом логическом устройстве VkDeviceCreateInfo createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.pQueueCreateInfos = &queueCreateInfo; createInfo.queueCreateInfoCount = 1; - createInfo.enabledExtensionCount = 0; - createInfo.enabledLayerCount = 0; + createInfo.enabledExtensionCount = deviceExtensions.size(); + createInfo.ppEnabledExtensionNames = deviceExtensions.data(); + createInfo.enabledLayerCount = layers.size(); + createInfo.ppEnabledLayerNames = layers.data(); createInfo.pEnabledFeatures = nullptr;//&physicalDevice.features; // Создание логического устройства