source: opengl-game/vulkan-utils.cpp@ a0da009

feature/imgui-sdl points-test
Last change on this file since a0da009 was 6fc24c7, checked in by Dmitry Portnoy <dmitry.portnoy@…>, 5 years ago

In vulkangame, add code to create a render pass

  • Property mode set to 100644
File size: 7.3 KB
Line 
1#include "vulkan-utils.hpp"
2
3#include <algorithm>
4#include <set>
5#include <stdexcept>
6#include <string>
7
8bool VulkanUtils::checkValidationLayerSupport(const vector<const char*> &validationLayers) {
9 uint32_t layerCount;
10 vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
11
12 vector<VkLayerProperties> availableLayers(layerCount);
13 vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
14
15 for (const char* layerName : validationLayers) {
16 bool layerFound = false;
17
18 for (const auto& layerProperties : availableLayers) {
19 if (strcmp(layerName, layerProperties.layerName) == 0) {
20 layerFound = true;
21 break;
22 }
23 }
24
25 if (!layerFound) {
26 return false;
27 }
28 }
29
30 return true;
31}
32
33VkResult VulkanUtils::createDebugUtilsMessengerEXT(VkInstance instance,
34 const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
35 const VkAllocationCallbacks* pAllocator,
36 VkDebugUtilsMessengerEXT* pDebugMessenger) {
37 auto func = (PFN_vkCreateDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
38
39 if (func != nullptr) {
40 return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
41 } else {
42 return VK_ERROR_EXTENSION_NOT_PRESENT;
43 }
44}
45
46void VulkanUtils::destroyDebugUtilsMessengerEXT(VkInstance instance,
47 VkDebugUtilsMessengerEXT debugMessenger,
48 const VkAllocationCallbacks* pAllocator) {
49 auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
50
51 if (func != nullptr) {
52 func(instance, debugMessenger, pAllocator);
53 }
54}
55
56QueueFamilyIndices VulkanUtils::findQueueFamilies(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) {
57 QueueFamilyIndices indices;
58
59 uint32_t queueFamilyCount = 0;
60 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, nullptr);
61
62 vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
63 vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &queueFamilyCount, queueFamilies.data());
64
65 int i = 0;
66 for (const auto& queueFamily : queueFamilies) {
67 if (queueFamily.queueCount > 0 && queueFamily.queueFlags & VK_QUEUE_GRAPHICS_BIT) {
68 indices.graphicsFamily = i;
69 }
70
71 VkBool32 presentSupport = false;
72 vkGetPhysicalDeviceSurfaceSupportKHR(physicalDevice, i, surface, &presentSupport);
73
74 if (queueFamily.queueCount > 0 && presentSupport) {
75 indices.presentFamily = i;
76 }
77
78 if (indices.isComplete()) {
79 break;
80 }
81
82 i++;
83 }
84
85 return indices;
86}
87
88bool VulkanUtils::checkDeviceExtensionSupport(VkPhysicalDevice physicalDevice, const vector<const char*>& deviceExtensions) {
89 uint32_t extensionCount;
90 vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, nullptr);
91
92 vector<VkExtensionProperties> availableExtensions(extensionCount);
93 vkEnumerateDeviceExtensionProperties(physicalDevice, nullptr, &extensionCount, availableExtensions.data());
94
95 set<string> requiredExtensions(deviceExtensions.begin(), deviceExtensions.end());
96
97 for (const auto& extension : availableExtensions) {
98 requiredExtensions.erase(extension.extensionName);
99 }
100
101 return requiredExtensions.empty();
102}
103
104SwapChainSupportDetails VulkanUtils::querySwapChainSupport(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) {
105 SwapChainSupportDetails details;
106
107 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &details.capabilities);
108
109 uint32_t formatCount;
110 vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, nullptr);
111
112 if (formatCount != 0) {
113 details.formats.resize(formatCount);
114 vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, details.formats.data());
115 }
116
117 uint32_t presentModeCount;
118 vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, nullptr);
119
120 if (presentModeCount != 0) {
121 details.presentModes.resize(presentModeCount);
122 vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, details.presentModes.data());
123 }
124
125 return details;
126}
127
128VkSurfaceFormatKHR VulkanUtils::chooseSwapSurfaceFormat(const vector<VkSurfaceFormatKHR>& availableFormats) {
129 for (const auto& availableFormat : availableFormats) {
130 if (availableFormat.format == VK_FORMAT_B8G8R8A8_UNORM && availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
131 return availableFormat;
132 }
133 }
134
135 return availableFormats[0];
136}
137
138VkPresentModeKHR VulkanUtils::chooseSwapPresentMode(const vector<VkPresentModeKHR>& availablePresentModes) {
139 VkPresentModeKHR bestMode = VK_PRESENT_MODE_FIFO_KHR;
140
141 for (const auto& availablePresentMode : availablePresentModes) {
142 if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
143 return availablePresentMode;
144 }
145 else if (availablePresentMode == VK_PRESENT_MODE_IMMEDIATE_KHR) {
146 bestMode = availablePresentMode;
147 }
148 }
149
150 return bestMode;
151}
152
153VkExtent2D VulkanUtils::chooseSwapExtent(const VkSurfaceCapabilitiesKHR& capabilities, int width, int height) {
154 if (capabilities.currentExtent.width != numeric_limits<uint32_t>::max()) {
155 return capabilities.currentExtent;
156 } else {
157 VkExtent2D actualExtent = {
158 static_cast<uint32_t>(width),
159 static_cast<uint32_t>(height)
160 };
161
162 actualExtent.width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actualExtent.width));
163 actualExtent.height = std::max(capabilities.minImageExtent.height, std::min(capabilities.maxImageExtent.height, actualExtent.height));
164
165 return actualExtent;
166 }
167}
168
169VkImageView VulkanUtils::createImageView(VkDevice device, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags) {
170 VkImageViewCreateInfo viewInfo = {};
171 viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
172 viewInfo.image = image;
173 viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
174 viewInfo.format = format;
175
176 viewInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
177 viewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
178 viewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
179 viewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
180
181 viewInfo.subresourceRange.aspectMask = aspectFlags;
182 viewInfo.subresourceRange.baseMipLevel = 0;
183 viewInfo.subresourceRange.levelCount = 1;
184 viewInfo.subresourceRange.baseArrayLayer = 0;
185 viewInfo.subresourceRange.layerCount = 1;
186
187 VkImageView imageView;
188 if (vkCreateImageView(device, &viewInfo, nullptr, &imageView) != VK_SUCCESS) {
189 throw runtime_error("failed to create image view!");
190 }
191
192 return imageView;
193}
194
195VkFormat VulkanUtils::findSupportedFormat(VkPhysicalDevice physicalDevice, const vector<VkFormat>& candidates,
196 VkImageTiling tiling, VkFormatFeatureFlags features) {
197 for (VkFormat format : candidates) {
198 VkFormatProperties props;
199 vkGetPhysicalDeviceFormatProperties(physicalDevice, format, &props);
200
201 if (tiling == VK_IMAGE_TILING_LINEAR &&
202 (props.linearTilingFeatures & features) == features) {
203 return format;
204 } else if (tiling == VK_IMAGE_TILING_OPTIMAL &&
205 (props.optimalTilingFeatures & features) == features) {
206 return format;
207 }
208 }
209
210 throw runtime_error("failed to find supported format!");
211}
Note: See TracBrowser for help on using the repository browser.