From 6185c081c1a6ec13b54eab6a12ff72814cf3addb Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Tue, 1 Oct 2024 17:08:41 -0700 Subject: Fix vulkan validation error --- src/vulkan_helper.cpp | 122 +++++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 56 deletions(-) (limited to 'src/vulkan_helper.cpp') diff --git a/src/vulkan_helper.cpp b/src/vulkan_helper.cpp index 69617c4..f39d867 100644 --- a/src/vulkan_helper.cpp +++ b/src/vulkan_helper.cpp @@ -1,12 +1,12 @@ #include "vulkan_helper.h" #include "vulkan/vulkan_core.h" #include +#include #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #include #include #include -#include #include #define VMA_IMPLEMENTATION #include @@ -23,7 +23,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report( void* pUserData) { (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments - fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); + spdlog::debug("[vulkan] Debug report from ObjectType: {}\nMessage: {}\n\n", (uint32_t)objectType, pMessage); return VK_FALSE; } @@ -36,7 +36,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback( (void) messageSeverity; (void) messageType; (void) pUserData; - std::cerr << "Validation layer: " << pCallbackData->pMessage << std::endl; + spdlog::error("{}", pCallbackData->pMessage); return VK_FALSE; } #endif @@ -151,8 +151,7 @@ Device::Device(std::vector layers, std::vector instanc } if (!has_raytracing || !has_acceleration_structure) { - // TODO throw an exception - std::cerr << "Physical device does not support ray tracing extensions" << std::endl; + spdlog::critical("Physical device does not support ray tracing extensions"); abort(); } } @@ -225,6 +224,19 @@ Device::Device(std::vector layers, std::vector instanc // not handled by RAII, manually call at the end. void Device::destroy() { +#ifdef USE_VULKAN_VALIDATION_LAYERS + auto vkDestroyDebugReportCallback = (PFN_vkDestroyDebugReportCallbackEXT) + vkGetInstanceProcAddr(instance, "vkDestroyDebugReportCallbackEXT"); + if (vkDestroyDebugReportCallback) { + vkDestroyDebugReportCallback(instance, debugReportCallback, nullptr); + } + auto vkDestroyDebugUtilsMessenger = (PFN_vkDestroyDebugUtilsMessengerEXT) + vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); + if (vkDestroyDebugUtilsMessenger) { + vkDestroyDebugUtilsMessenger(instance, debugUtilsMessenger, nullptr); + } +#endif + vmaDestroyAllocator(allocator); vkDestroyDevice(device, VK_NULL_HANDLE); vkDestroyInstance(instance, VK_NULL_HANDLE); @@ -265,6 +277,7 @@ CommandBuffer::CommandBuffer(VkDevice device, &fence_info, VK_NULL_HANDLE, &fence)); + spdlog::debug("Created command buffer: 0x{:x}", (uint64_t)buffer); } AsyncCommandBuffer::AsyncCommandBuffer(VkDevice device, @@ -293,11 +306,23 @@ AsyncCommandBuffer::AsyncCommandBuffer(VkDevice device, device, &buffer_info, &buffer)); + + VkFenceCreateInfo fence_info = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + }; + CHECK_VULKAN(vkCreateFence( + device, + &fence_info, + VK_NULL_HANDLE, + &fence)); + spdlog::debug("Created async command buffer: 0x{:x}", (uint64_t)buffer); } void AsyncCommandBuffer::destroy() { + vkDestroyFence(device, fence, VK_NULL_HANDLE); vkFreeCommandBuffers(device, pool, 1, &buffer); vkDestroyCommandPool(device, pool, VK_NULL_HANDLE); + spdlog::debug("Destroyed async command buffer: 0x{:x}", (uint64_t)buffer); } @@ -305,6 +330,7 @@ void CommandBuffer::destroy() { vkDestroyFence(device, fence, VK_NULL_HANDLE); vkFreeCommandBuffers(device, pool, 1, &buffer); vkDestroyCommandPool(device, pool, VK_NULL_HANDLE); + spdlog::debug("Destroyed command buffer: 0x{:x}", (uint64_t)buffer); } CommandBuffer Device::create_command_buffer() { @@ -366,55 +392,51 @@ void Buffer_t::unmap() { void Buffer_t::release() { if (buffer != VK_NULL_HANDLE) { - std::cerr << "Destroying buffer: 0x" << std::hex << (uint64_t)buffer << std::endl; + spdlog::debug("Destroying buffer: 0x{:x}", (uint64_t)buffer); + vkDeviceWaitIdle(device); vmaDestroyBuffer(allocator, buffer, allocation); buffer = VK_NULL_HANDLE; } } -Buffer_t Device::create_buffer_raw(VkDeviceSize size, - VkBufferUsageFlags usage, - VmaAllocationCreateInfo create_info) +Buffer Device::create_buffer(VkDeviceSize size, + VkBufferUsageFlags usage, + VmaAllocationCreateInfo create_info) { VkBufferCreateInfo buffer_info = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .size = size, .usage = usage, }; - Buffer_t buffer = { - .allocator = this->allocator, - .flags = usage, - .size = size, - }; + Buffer buffer = std::make_shared(); + buffer->device = this->device; + buffer->allocator = this->allocator; + buffer->flags = usage; + buffer->size = size; CHECK_VULKAN(vmaCreateBuffer( allocator, &buffer_info, &create_info, - &buffer.buffer, - &buffer.allocation, + &buffer->buffer, + &buffer->allocation, VK_NULL_HANDLE)); + spdlog::debug("Created buffer: 0x{:x}", (uint64_t)buffer->buffer); return buffer; } -Buffer Device::create_buffer(VkDeviceSize size, - VkBufferUsageFlags usage, - VmaAllocationCreateInfo create_info) -{ - return std::make_shared(create_buffer_raw(size, usage, create_info)); -} - void Texture2D_t::release() { if (image != VK_NULL_HANDLE) { - std::cerr << "Destroying image: 0x" << std::hex << (uint64_t)image << std::endl; + spdlog::debug("Destroying image: 0x{:x}", (uint64_t)image); + vkDeviceWaitIdle(device); vmaDestroyImage(allocator, image, allocation); image = VK_NULL_HANDLE; } } -Texture2D_t Device::create_texture_raw(VkExtent2D extent, - VkFormat format, - VkImageUsageFlags usage, - VmaAllocationCreateInfo create_info) +Texture2D Device::create_texture(VkExtent2D extent, + VkFormat format, + VkImageUsageFlags usage, + VmaAllocationCreateInfo create_info) { VkImageCreateInfo image_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, @@ -427,33 +449,25 @@ Texture2D_t Device::create_texture_raw(VkExtent2D extent, .tiling = VK_IMAGE_TILING_OPTIMAL, .usage = usage, }; - Texture2D_t texture = { - .allocator = this->allocator, - .layout = VK_IMAGE_LAYOUT_UNDEFINED, - .flags = usage, - .extent = extent, - }; + + Texture2D texture = std::make_shared(); + texture->device = this->device; + texture->allocator = this->allocator; + texture->layout = VK_IMAGE_LAYOUT_UNDEFINED; + texture->flags = usage; + texture->extent = extent; + CHECK_VULKAN(vmaCreateImage( allocator, &image_info, &create_info, - &texture.image, - &texture.allocation, + &texture->image, + &texture->allocation, VK_NULL_HANDLE)); - std::cerr << "Created image: 0x" << std::hex << (uint64_t)texture.image << std::endl; + spdlog::debug("Created image: 0x{:x}", (uint64_t)texture->image); return texture; } -Texture2D Device::create_texture(VkExtent2D extent, - VkFormat format, - VkImageUsageFlags usage, - VmaAllocationCreateInfo create_info) -{ - auto t = std::make_shared(create_texture_raw(extent, format, usage, create_info)); - std::cerr << "Before create texture terminates" << std::endl; - return t; -} - Texture2D Device::create_texture_from_image(const char* filename, VkFormat format, VkImageUsageFlags usage, @@ -461,13 +475,12 @@ Texture2D Device::create_texture_from_image(const char* filename, int width, height, channels; stbi_uc* pixels = stbi_load(filename, &width, &height, &channels, STBI_rgb_alpha); if (pixels == nullptr) { - // TODO throw an exception - std::cerr << "Failed to load image: " << filename << std::endl; + spdlog::critical("Failed to load image: {}", filename); abort(); } // destroy after use, don't need to wrap with shared_ptr - auto staging_buf = create_buffer_raw( + auto staging_buf = create_buffer( width * height * 4, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VmaAllocationCreateInfo { @@ -476,10 +489,10 @@ Texture2D Device::create_texture_from_image(const char* filename, .usage = VMA_MEMORY_USAGE_AUTO, }); std::memcpy( - staging_buf.map(), + staging_buf->map(), pixels, width * height * 4); - staging_buf.unmap(); + staging_buf->unmap(); stbi_image_free(pixels); VkExtent2D extent = {static_cast(width), static_cast(height)}; @@ -493,7 +506,6 @@ Texture2D Device::create_texture_from_image(const char* filename, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, }; CHECK_VULKAN(vkBeginCommandBuffer(cmd_buf.buffer, &begin_info)); - std::cerr << "Image layout transition for 0x" << std::hex << (uint64_t)texture->image << std::endl; VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .srcAccessMask = VK_ACCESS_NONE, @@ -550,7 +562,7 @@ Texture2D Device::create_texture_from_image(const char* filename, }; vkCmdCopyBufferToImage( cmd_buf.buffer, - staging_buf.buffer, + staging_buf->buffer, texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, @@ -606,8 +618,6 @@ Texture2D Device::create_texture_from_image(const char* filename, CHECK_VULKAN(vkWaitForFences(cmd_buf.device, 1, &cmd_buf.fence, VK_TRUE, std::numeric_limits::max())); } texture->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - std::cerr << "Image layout transition done" << std::endl; - staging_buf.release(); return texture; } -- cgit v1.2.3-70-g09d2