vengine  0.0.1
3D graphics engine
Loading...
Searching...
No Matches
device.cpp
Go to the documentation of this file.
1#include <cstring>
2#include <iostream>
3#include <set>
4#include <unordered_set>
5
7
8static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(const VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, const VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData)
9{
10 (void) pUserData; (void) messageSeverity; (void) messageType;
11
12 std::cerr << "validation layer: " << pCallbackData->pMessage << '\n';
13 return VK_FALSE;
14}
15
16VkResult CreateDebugUtilsMessengerEXT(const VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pDebugMessenger)
17{
18 if (const auto func = reinterpret_cast<PFN_vkCreateDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT")); func != nullptr) {
19 return func(instance, pCreateInfo, pAllocator, pDebugMessenger);
20 }
21
22 return VK_ERROR_EXTENSION_NOT_PRESENT;
23}
24
25void DestroyDebugUtilsMessengerEXT(const VkInstance instance, const VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks *pAllocator)
26{
27 if (const auto func = reinterpret_cast<PFN_vkDestroyDebugUtilsMessengerEXT>(vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT")); func != nullptr) {
28 func(instance, debugMessenger, pAllocator);
29 }
30}
31
41
43{
44 vkDestroyCommandPool(m_device, m_commandPool, nullptr);
45 vkDestroyDevice(m_device, nullptr);
46
47 if (enableValidationLayers) {
48 DestroyDebugUtilsMessengerEXT(m_instance, m_debugMessenger, nullptr);
49 }
50
51 vkDestroySurfaceKHR(m_instance, m_surface, nullptr);
52 vkDestroyInstance(m_instance, nullptr);
53}
54
56{
57 if (enableValidationLayers && !checkValidationLayerSupport()) {
58 throw std::runtime_error("validation layers requested, but not available!");
59 }
60
61 constexpr VkApplicationInfo appInfo = {
62 .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
63 .pNext = nullptr,
64 .pApplicationName = "VEngine App",
65 .applicationVersion = VK_MAKE_VERSION(1, 0, 0),
66 .pEngineName = "VEngine",
67 .engineVersion = VK_MAKE_VERSION(1, 0, 0),
68 .apiVersion = VK_API_VERSION_1_0
69 };
70
71 VkInstanceCreateInfo createInfo = {};
72 createInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
73 createInfo.pApplicationInfo = &appInfo;
74
75 const std::vector<const char *> extensions = getRequiredExtensions();
76 createInfo.enabledExtensionCount = static_cast<uint32_t>(extensions.size());
77 createInfo.ppEnabledExtensionNames = extensions.data();
78
79 VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo;
80 if (enableValidationLayers) {
81 createInfo.enabledLayerCount = static_cast<uint32_t>(m_validationLayers.size());
82 createInfo.ppEnabledLayerNames = m_validationLayers.data();
83
84 populateDebugMessengerCreateInfo(debugCreateInfo);
85 createInfo.pNext = &debugCreateInfo;
86 } else {
87 createInfo.enabledLayerCount = 0;
88 createInfo.pNext = nullptr;
89 }
90
91 if (vkCreateInstance(&createInfo, nullptr, &m_instance) != VK_SUCCESS) {
92 throw std::runtime_error("failed to create instance!");
93 }
94
95 hasGlfwRequiredInstanceExtensions();
96}
97
99{
100 uint32_t deviceCount = 0;
101 vkEnumeratePhysicalDevices(m_instance, &deviceCount, nullptr);
102 if (deviceCount == 0) {
103 throw std::runtime_error("failed to find GPUs with Vulkan support!");
104 }
105 std::cout << "Device count: " << deviceCount << '\n';
106 std::vector<VkPhysicalDevice> devices(deviceCount);
107 vkEnumeratePhysicalDevices(m_instance, &deviceCount, devices.data());
108
109 for (const auto &device : devices) {
110 if (isDeviceSuitable(device)) {
111 m_physicalDevice = device;
112 break;
113 }
114 }
115
116 if (m_physicalDevice == VK_NULL_HANDLE) {
117 throw std::runtime_error("failed to find a suitable GPU!");
118 }
119
120 vkGetPhysicalDeviceProperties(m_physicalDevice, &m_properties);
121 std::cout << "physical device: " << m_properties.deviceName << '\n';
122}
123
125{
126 const auto [graphicsFamily, presentFamily, graphicsFamilyHasValue, presentFamilyHasValue] = findQueueFamilies(m_physicalDevice);
127
128 std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
129 const std::set<uint32_t> uniqueQueueFamilies = {graphicsFamily, presentFamily};
130 float queuePriority = 1.0F;
131
132 for (const uint32_t queueFamily : uniqueQueueFamilies) {
133 VkDeviceQueueCreateInfo queueCreateInfo = {};
134 queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
135 queueCreateInfo.queueFamilyIndex = queueFamily;
136 queueCreateInfo.queueCount = 1;
137 queueCreateInfo.pQueuePriorities = &queuePriority;
138 queueCreateInfos.push_back(queueCreateInfo);
139 }
140
141 VkPhysicalDeviceFeatures deviceFeatures = {};
142 deviceFeatures.samplerAnisotropy = VK_TRUE;
143
144 VkDeviceCreateInfo createInfo = {};
145 createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
146
147 createInfo.queueCreateInfoCount = static_cast<uint32_t>(queueCreateInfos.size());
148 createInfo.pQueueCreateInfos = queueCreateInfos.data();
149
150 createInfo.pEnabledFeatures = &deviceFeatures;
151 createInfo.enabledExtensionCount = static_cast<uint32_t>(m_deviceExtensions.size());
152 createInfo.ppEnabledExtensionNames = m_deviceExtensions.data();
153
154 // might not really be necessary anymore because device specific validation layers
155 // have been deprecated
156 if (enableValidationLayers) {
157 createInfo.enabledLayerCount = static_cast<uint32_t>(m_validationLayers.size());
158 createInfo.ppEnabledLayerNames = m_validationLayers.data();
159 } else {
160 createInfo.enabledLayerCount = 0;
161 }
162
163 if (vkCreateDevice(m_physicalDevice, &createInfo, nullptr, &m_device) != VK_SUCCESS) {
164 throw std::runtime_error("failed to create logical device!");
165 }
166
167 vkGetDeviceQueue(m_device, graphicsFamily, 0, &m_graphicsQueue);
168 vkGetDeviceQueue(m_device, presentFamily, 0, &m_presentQueue);
169}
170
172{
173 const auto [graphicsFamily, presentFamily, graphicsFamilyHasValue, presentFamilyHasValue] = findPhysicalQueueFamilies();
174
175 const VkCommandPoolCreateInfo poolInfo = {
176 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
177 .pNext = nullptr,
178 .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
179 .queueFamilyIndex = graphicsFamily
180 };
181
182 if (vkCreateCommandPool(m_device, &poolInfo, nullptr, &m_commandPool) != VK_SUCCESS) {
183 throw std::runtime_error("failed to create command pool!");
184 }
185}
186
187bool ven::Device::isDeviceSuitable(const VkPhysicalDevice device) const
188{
189 const QueueFamilyIndices indices = findQueueFamilies(device);
190 const bool extensionsSupported = checkDeviceExtensionSupport(device);
191 bool swapChainAdequate = false;
192
193 if (extensionsSupported) {
194 auto [capabilities, formats, presentModes] = querySwapChainSupport(device);
195 swapChainAdequate = !formats.empty() && !presentModes.empty();
196 }
197
198 VkPhysicalDeviceFeatures supportedFeatures;
199 vkGetPhysicalDeviceFeatures(device, &supportedFeatures);
200
201 return indices.isComplete() && extensionsSupported && swapChainAdequate && (supportedFeatures.samplerAnisotropy != 0U);
202}
203
204void ven::Device::populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT &createInfo)
205{
206 createInfo = {};
207 createInfo.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
208 createInfo.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
209 VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
210 createInfo.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
211 VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
212 VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
213 createInfo.pfnUserCallback = debugCallback;
214 createInfo.pUserData = nullptr; // Optional
215}
216
218{
219 if (!enableValidationLayers) { return; }
220 VkDebugUtilsMessengerCreateInfoEXT createInfo;
221 populateDebugMessengerCreateInfo(createInfo);
222 if (CreateDebugUtilsMessengerEXT(m_instance, &createInfo, nullptr, &m_debugMessenger) != VK_SUCCESS) {
223 throw std::runtime_error("failed to set up debug messenger!");
224 }
225}
226
228{
229 uint32_t layerCount = 0;
230 vkEnumerateInstanceLayerProperties(&layerCount, nullptr);
231
232 std::vector<VkLayerProperties> availableLayers(layerCount);
233 vkEnumerateInstanceLayerProperties(&layerCount, availableLayers.data());
234
235 for (const char *validationLayer : m_validationLayers) {
236 bool layerFound = false;
237
238 for (const auto &[layerName, specVersion, implementationVersion, description] : availableLayers) {
239 if (strcmp(layerName, validationLayer) == 0) {
240 layerFound = true;
241 break;
242 }
243 }
244 if (!layerFound) {
245 return false;
246 }
247 }
248
249 return true;
250}
251
252std::vector<const char *> ven::Device::getRequiredExtensions() const
253{
254 uint32_t glfwExtensionCount = 0;
255 const char **glfwExtensions = nullptr;
256 glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
257
258 std::vector<const char *> extensions(glfwExtensions, glfwExtensions + glfwExtensionCount);
259
260 if (enableValidationLayers) {
261 extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME);
262 }
263
264 return extensions;
265}
266
268{
269 uint32_t extensionCount = 0;
270 vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
271 std::vector<VkExtensionProperties> extensions(extensionCount);
272 vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());
273
274 std::cout << "available extensions:\n";
275 std::unordered_set<std::string> available;
276 for (const auto &[extensionName, specVersion] : extensions) {
277 std::cout << '\t' << extensionName << '\n';
278 available.insert(extensionName);
279 }
280
281 std::cout << "required extensions:\n";
282 for (const std::vector<const char *> requiredExtensions = getRequiredExtensions(); const auto &required : requiredExtensions) {
283 std::cout << "\t" << required << '\n';
284 if (!available.contains(required)) {
285 throw std::runtime_error("Missing required glfw extension");
286 }
287 }
288}
289
290bool ven::Device::checkDeviceExtensionSupport(const VkPhysicalDevice device) const
291{
292 uint32_t extensionCount = 0;
293 vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
294
295 std::vector<VkExtensionProperties> availableExtensions(extensionCount);
296 vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, availableExtensions.data());
297
298 std::set<std::string> requiredExtensions(m_deviceExtensions.begin(), m_deviceExtensions.end());
299 for (const auto &[extensionName, specVersion] : availableExtensions) {
300 requiredExtensions.erase(extensionName);
301 }
302
303 return requiredExtensions.empty();
304}
305
306ven::QueueFamilyIndices ven::Device::findQueueFamilies(const VkPhysicalDevice device) const
307{
308 QueueFamilyIndices indices;
309 uint32_t queueFamilyCount = 0;
310 uint32_t index = 0;
311 vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, nullptr);
312 std::vector<VkQueueFamilyProperties> queueFamilies(queueFamilyCount);
313 vkGetPhysicalDeviceQueueFamilyProperties(device, &queueFamilyCount, queueFamilies.data());
314
315 for (const auto &[queueFlags, queueCount, timestampValidBits, minImageTransferGranularity] : queueFamilies) {
316 if (queueCount > 0 && ((queueFlags & VK_QUEUE_GRAPHICS_BIT) != 0U)) {
317 indices.graphicsFamily = index;
318 indices.graphicsFamilyHasValue = true;
319 }
320 VkBool32 presentSupport = 0U;
321 vkGetPhysicalDeviceSurfaceSupportKHR(device, index, m_surface, &presentSupport);
322 if (queueCount > 0 && (presentSupport != 0U)) {
323 indices.presentFamily = index;
324 indices.presentFamilyHasValue = true;
325 }
326 if (indices.isComplete()) {
327 break;
328 }
329 index++;
330 }
331 return indices;
332}
333
335{
336 uint32_t formatCount = 0;
337 uint32_t presentModeCount = 0;
339 vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, m_surface, &details.capabilities);
340
341 vkGetPhysicalDeviceSurfaceFormatsKHR(device, m_surface, &formatCount, nullptr);
342 if (formatCount != 0) {
343 details.formats.resize(formatCount);
344 vkGetPhysicalDeviceSurfaceFormatsKHR(device, m_surface, &formatCount, details.formats.data());
345 }
346 vkGetPhysicalDeviceSurfacePresentModesKHR(device, m_surface, &presentModeCount, nullptr);
347 if (presentModeCount != 0) {
348 details.presentModes.resize(presentModeCount);
349 vkGetPhysicalDeviceSurfacePresentModesKHR(device, m_surface, &presentModeCount, details.presentModes.data());
350 }
351
352 return details;
353}
354
355VkFormat ven::Device::findSupportedFormat(const std::vector<VkFormat> &candidates, const VkImageTiling tiling, const VkFormatFeatureFlags features) const
356{
357 for (const VkFormat format : candidates) {
358 VkFormatProperties props;
359 vkGetPhysicalDeviceFormatProperties(m_physicalDevice, format, &props);
360 if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) {
361 return format;
362 } if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) {
363 return format;
364 }
365 }
366 throw std::runtime_error("failed to find supported format!");
367}
368
369uint32_t ven::Device::findMemoryType(const uint32_t typeFilter, const VkMemoryPropertyFlags properties) const
370{
371 VkPhysicalDeviceMemoryProperties memProperties;
372 vkGetPhysicalDeviceMemoryProperties(m_physicalDevice, &memProperties);
373
374 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
375 if (((typeFilter & (1 << i)) != 0U) &&
376 (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
377 return i;
378 }
379 }
380
381 throw std::runtime_error("failed to find suitable m_memory type!");
382}
383
384void ven::Device::createBuffer(const VkDeviceSize size, const VkBufferUsageFlags usage, const VkMemoryPropertyFlags properties, VkBuffer &buffer, VkDeviceMemory &bufferMemory) const
385{
386 VkBufferCreateInfo bufferInfo{};
387 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
388 bufferInfo.size = size;
389 bufferInfo.usage = usage;
390 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
391
392 if (vkCreateBuffer(m_device, &bufferInfo, nullptr, &buffer) != VK_SUCCESS) {
393 throw std::runtime_error("failed to create vertex m_buffer!");
394 }
395
396 VkMemoryRequirements memRequirements;
397 vkGetBufferMemoryRequirements(m_device, buffer, &memRequirements);
398
399 const VkMemoryAllocateInfo allocInfo{
400 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
401 .pNext = nullptr,
402 .allocationSize = memRequirements.size,
403 .memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties)
404 };
405
406 if (vkAllocateMemory(m_device, &allocInfo, nullptr, &bufferMemory) != VK_SUCCESS) {
407 throw std::runtime_error("failed to allocate vertex m_buffer m_memory!");
408 }
409
410 vkBindBufferMemory(m_device, buffer, bufferMemory, 0);
411}
412
414{
415 VkCommandBufferAllocateInfo allocInfo{};
416 allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
417 allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
418 allocInfo.commandPool = m_commandPool;
419 allocInfo.commandBufferCount = 1;
420
421 VkCommandBuffer commandBuffer = nullptr;
422 vkAllocateCommandBuffers(m_device, &allocInfo, &commandBuffer);
423
424 VkCommandBufferBeginInfo beginInfo{};
425 beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
426 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
427
428 vkBeginCommandBuffer(commandBuffer, &beginInfo);
429 return commandBuffer;
430}
431
432void ven::Device::endSingleTimeCommands(const VkCommandBuffer commandBuffer) const
433{
434 vkEndCommandBuffer(commandBuffer);
435
436 VkSubmitInfo submitInfo{};
437 submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
438 submitInfo.commandBufferCount = 1;
439 submitInfo.pCommandBuffers = &commandBuffer;
440
441 vkQueueSubmit(m_graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE);
442 vkQueueWaitIdle(m_graphicsQueue);
443
444 vkFreeCommandBuffers(m_device, m_commandPool, 1, &commandBuffer);
445}
446
447void ven::Device::copyBuffer(const VkBuffer srcBuffer, const VkBuffer dstBuffer, const VkDeviceSize size) const
448{
449 const VkCommandBuffer commandBuffer = beginSingleTimeCommands();
450
451 VkBufferCopy copyRegion{};
452 copyRegion.srcOffset = 0; // Optional
453 copyRegion.dstOffset = 0; // Optional
454 copyRegion.size = size;
455 vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, &copyRegion);
456
457 endSingleTimeCommands(commandBuffer);
458}
459
460void ven::Device::copyBufferToImage(const VkBuffer buffer, const VkImage image, const uint32_t width, const uint32_t height, const uint32_t layerCount) const
461{
462 const VkCommandBuffer commandBuffer = beginSingleTimeCommands();
463 const VkBufferImageCopy region{
464 .bufferOffset = 0,
465 .bufferRowLength = 0,
466 .bufferImageHeight = 0,
467 .imageSubresource = {
468 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
469 .mipLevel = 0,
470 .baseArrayLayer = 0,
471 .layerCount = layerCount
472 },
473 .imageOffset = {0, 0, 0},
474 .imageExtent = {width, height, 1}
475 };
476
477 vkCmdCopyBufferToImage(commandBuffer, buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
478 endSingleTimeCommands(commandBuffer);
479}
480
481void ven::Device::createImageWithInfo(const VkImageCreateInfo &imageInfo, const VkMemoryPropertyFlags properties, VkImage &image, VkDeviceMemory &imageMemory) const
482{
483 if (vkCreateImage(m_device, &imageInfo, nullptr, &image) != VK_SUCCESS) {
484 throw std::runtime_error("failed to create image!");
485 }
486
487 VkMemoryRequirements memRequirements;
488 vkGetImageMemoryRequirements(m_device, image, &memRequirements);
489
490 VkMemoryAllocateInfo allocInfo{};
491 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
492 allocInfo.allocationSize = memRequirements.size;
493 allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, properties);
494
495 if (vkAllocateMemory(m_device, &allocInfo, nullptr, &imageMemory) != VK_SUCCESS) {
496 throw std::runtime_error("failed to allocate image memory!");
497 }
498
499 if (vkBindImageMemory(m_device, image, imageMemory, 0) != VK_SUCCESS) {
500 throw std::runtime_error("failed to bind image memory!");
501 }
502}
503
504void ven::Device::transitionImageLayout(const VkImage image, const VkFormat format, const VkImageLayout oldLayout, const VkImageLayout newLayout, const uint32_t mipLevels, const uint32_t layerCount) const {
505 // uses an image memory barrier transition image layouts and transfer queue
506 // family ownership when VK_SHARING_MODE_EXCLUSIVE is used. There is an
507 // equivalent buffer memory barrier to do this for buffers
508 const VkCommandBuffer commandBuffer = beginSingleTimeCommands();
509
510 VkImageMemoryBarrier barrier{};
511 barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
512 barrier.oldLayout = oldLayout;
513 barrier.newLayout = newLayout;
514
515 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
516 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
517
518 barrier.image = image;
519 barrier.subresourceRange.baseMipLevel = 0;
520 barrier.subresourceRange.levelCount = mipLevels;
521 barrier.subresourceRange.baseArrayLayer = 0;
522 barrier.subresourceRange.layerCount = layerCount;
523
524 if (newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
525 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
526 if (format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT) {
527 barrier.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
528 }
529 } else {
530 barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
531 }
532
533 VkPipelineStageFlags sourceStage = 0;
534 VkPipelineStageFlags destinationStage = 0;
535
536 if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) {
537 barrier.srcAccessMask = 0;
538 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
539
540 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
541 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
542 } else if (
543 oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) {
544 barrier.srcAccessMask = 0;
545 barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
546
547 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
548 destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
549 } else if (
550 oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
551 newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) {
552 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
553 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
554
555 sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
556 destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
557 } else if (
558 oldLayout == VK_IMAGE_LAYOUT_UNDEFINED &&
559 newLayout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) {
560 barrier.srcAccessMask = 0;
561 barrier.dstAccessMask =
562 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
563
564 sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
565 destinationStage = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT;
566 } else {
567 throw std::invalid_argument("unsupported layout transition!");
568 }
569 vkCmdPipelineBarrier(
570 commandBuffer,
571 sourceStage,
572 destinationStage,
573 0,
574 0,
575 nullptr,
576 0,
577 nullptr,
578 1,
579 &barrier);
580
581 endSingleTimeCommands(commandBuffer);
582}
This file contains the Device class.
void transitionImageLayout(VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout, uint32_t mipLevels=1, uint32_t layerCount=1) const
Definition device.cpp:504
void endSingleTimeCommands(VkCommandBuffer commandBuffer) const
Definition device.cpp:432
void createCommandPool()
Definition device.cpp:171
SwapChainSupportDetails querySwapChainSupport(VkPhysicalDevice device) const
Definition device.cpp:334
void createInstance()
Definition device.cpp:55
bool checkValidationLayerSupport() const
Definition device.cpp:227
void createBuffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkBuffer &buffer, VkDeviceMemory &bufferMemory) const
Definition device.cpp:384
void setupDebugMessenger()
Definition device.cpp:217
void pickPhysicalDevice()
Definition device.cpp:98
bool checkDeviceExtensionSupport(VkPhysicalDevice device) const
Definition device.cpp:290
void createLogicalDevice()
Definition device.cpp:124
Device(Window &window)
Definition device.cpp:32
void createImageWithInfo(const VkImageCreateInfo &imageInfo, VkMemoryPropertyFlags properties, VkImage &image, VkDeviceMemory &imageMemory) const
Definition device.cpp:481
QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) const
Definition device.cpp:306
VkCommandBuffer beginSingleTimeCommands() const
Definition device.cpp:413
void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) const
Definition device.cpp:447
bool isDeviceSuitable(VkPhysicalDevice device) const
Definition device.cpp:187
uint32_t findMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties) const
Definition device.cpp:369
std::vector< const char * > getRequiredExtensions() const
Definition device.cpp:252
void copyBufferToImage(VkBuffer buffer, VkImage image, uint32_t width, uint32_t height, uint32_t layerCount) const
Definition device.cpp:460
void createSurface()
Definition Device.hpp:82
static void populateDebugMessengerCreateInfo(VkDebugUtilsMessengerCreateInfoEXT &createInfo)
Definition device.cpp:204
void hasGlfwRequiredInstanceExtensions() const
Definition device.cpp:267
VkFormat findSupportedFormat(const std::vector< VkFormat > &candidates, VkImageTiling tiling, VkFormatFeatureFlags features) const
Definition device.cpp:355
Class for window.
Definition Window.hpp:26
void DestroyDebugUtilsMessengerEXT(const VkInstance instance, const VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks *pAllocator)
Definition device.cpp:25
static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(const VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, const VkDebugUtilsMessageTypeFlagsEXT messageType, const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData, void *pUserData)
Definition device.cpp:8
VkResult CreateDebugUtilsMessengerEXT(const VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pDebugMessenger)
Definition device.cpp:16
bool isComplete() const
Definition Device.hpp:27
std::vector< VkPresentModeKHR > presentModes
Definition Device.hpp:19
VkSurfaceCapabilitiesKHR capabilities
Definition Device.hpp:17
std::vector< VkSurfaceFormatKHR > formats
Definition Device.hpp:18