From 873a4762ef8c0d73b2ea979df160f6b1bd5a0dca Mon Sep 17 00:00:00 2001 From: "re.kovalev" Date: Wed, 16 Feb 2022 19:09:55 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5=20=D0=BE?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=B2=D0=B5=D1=80=D1=85=D0=BD=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/Surface.h | 16 ++++++++++++++++ include/vk.h | 6 ++++-- src/vk.cpp | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 include/Surface.h diff --git a/include/Surface.h b/include/Surface.h new file mode 100644 index 0000000..d1cdd25 --- /dev/null +++ b/include/Surface.h @@ -0,0 +1,16 @@ +#ifndef SURFACE_H +#define SURFACE_H + +#include + +#include + +typedef struct _Surface +{ + VkSurfaceKHR surface; // Поверхность окна + VkSurfaceCapabilitiesKHR capabilities; // общая информация + std::vector formats; // формат поверхности + std::vector presentModes; // режим показа +} Surface; + +#endif // SURFACE_H \ No newline at end of file diff --git a/include/vk.h b/include/vk.h index 9ff39ab..2d81d85 100644 --- a/include/vk.h +++ b/include/vk.h @@ -5,6 +5,7 @@ #include #include "PhysicalDevice.h" +#include "Surface.h" class Vulkan { @@ -16,7 +17,8 @@ class Vulkan PhysicalDevice physicalDevice; // Физическое устройство VkDevice logicalDevice; // логическое устройство VkQueue graphicalQueue; // очередь для работы с графикой - VkSurfaceKHR surface; // Поверхность окна + Surface surface; // Поверхность окна + // Структура для хранения флагов struct { @@ -28,6 +30,6 @@ class Vulkan void selectPhysicalDevice(std::vector &deviceExtensions); // Выбор физического устройства void createLogicalDevice(std::vector &deviceExtensions); // Создание логического устройства void createWindowSurface(GLFWwindow* window); // Создание поверхности окна -}; +}; #endif // VK_H \ No newline at end of file diff --git a/src/vk.cpp b/src/vk.cpp index 016b0db..8c42de9 100644 --- a/src/vk.cpp +++ b/src/vk.cpp @@ -10,7 +10,7 @@ void Vulkan::init(GLFWwindow* window) createInstance(); // Создание экземпяра createWindowSurface(window); // Создание поверхности // Расширения для устройства: имена задаются внутри фигурных скобок в кавычках - std::vector deviceExtensions({}); + std::vector deviceExtensions({"VK_KHR_swapchain"}); selectPhysicalDevice(deviceExtensions); // Выбор физического устройства createLogicalDevice(deviceExtensions); // Создание физического устройства } @@ -18,7 +18,7 @@ void Vulkan::init(GLFWwindow* window) // завершение работы void Vulkan::destroy() { - vkDestroySurfaceKHR(instance, surface, nullptr); + vkDestroySurfaceKHR(instance, surface.surface, nullptr); vkDestroyDevice(logicalDevice, nullptr); // Уничтожение логического устройства vkDestroyInstance(instance, nullptr); // Уничтожение экземпляра Vulkan } @@ -165,7 +165,7 @@ void Vulkan::createInstance() #include // Выбор физического устройства на основании требований -PhysicalDevice selectPhysicalDeviceByProperties(std::vector & devices, std::vector &requestedExtensions) +PhysicalDevice selectPhysicalDeviceByProperties(std::vector & devices, Surface & surface, std::vector &requestedExtensions) { int i; PhysicalDevice result; // физическое устройство (PhysicalDevice.h) @@ -200,12 +200,38 @@ PhysicalDevice selectPhysicalDeviceByProperties(std::vector & break; } + // Получение информации о поверхности + VkSurfaceCapabilitiesKHR capabilities; + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface.surface, &capabilities); + + // Получение форматов поверхности + uint32_t formatCount; + vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface.surface, &formatCount, nullptr); + std::vector formats(formatCount); + vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface.surface, &formatCount, formats.data()); + + // Получение данных о поддерживаемых режимах показа + uint32_t presentModeCount; + vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface.surface, &presentModeCount, nullptr); + std::vector presentModes(presentModeCount); + vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface.surface, &presentModeCount, presentModes.data()); + + // Если есть форматы и режимы показа, то на данном устройстве можно создать список показа + bool swapchainSupport = formatCount && presentModeCount; // Производим оценку if (availableExtensionsCount == requestedExtensions.size() && result.features.geometryShader - && 4000 < result.memory.memoryHeaps[0].size / 1000 / 1000) + && 4000 < result.memory.memoryHeaps[0].size / 1000 / 1000 + && swapchainSupport) + { + // Заполним данные о поверхности + surface.capabilities = capabilities; + surface.formats = formats; + surface.presentModes = presentModes; + // Вернем устройство return result; + } } // Если устройство не найдено - вернем пустую структуру return PhysicalDevice(); @@ -229,7 +255,7 @@ void Vulkan::selectPhysicalDevice(std::vector &deviceExtensions) vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); // Выбор физического устройства на основании требований - physicalDevice = selectPhysicalDeviceByProperties(devices, deviceExtensions); + physicalDevice = selectPhysicalDeviceByProperties(devices, surface, deviceExtensions); // Если не удалось выбрать подходящее требованием устройство - выдадим исключение if (!physicalDevice.device) @@ -291,7 +317,7 @@ void Vulkan::createLogicalDevice(std::vector &deviceExtensions) // Создание поверхности окна void Vulkan::createWindowSurface(GLFWwindow* window) { - if (glfwCreateWindowSurface(instance, window, nullptr, &surface) != VK_SUCCESS) + if (glfwCreateWindowSurface(instance, window, nullptr, &surface.surface) != VK_SUCCESS) { throw std::runtime_error("Unable to create window surface"); }