From e5eed5bdfa01cf549436c6001eaf334d266acc40 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Sat, 14 Sep 2024 22:38:51 -0700 Subject: fix lifetime problem --- src/vulkan_helper.cpp | 133 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 113 insertions(+), 20 deletions(-) (limited to 'src/vulkan_helper.cpp') diff --git a/src/vulkan_helper.cpp b/src/vulkan_helper.cpp index 339b9c0..69617c4 100644 --- a/src/vulkan_helper.cpp +++ b/src/vulkan_helper.cpp @@ -12,12 +12,33 @@ #include #ifdef USE_VULKAN_VALIDATION_LAYERS -static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report( + VkDebugReportFlagsEXT flags, + VkDebugReportObjectTypeEXT objectType, + uint64_t object, + size_t location, + int32_t messageCode, + const char* pLayerPrefix, + const char* pMessage, + 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); return VK_FALSE; } + +VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback( + VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, + VkDebugUtilsMessageTypeFlagsEXT messageType, + const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, + void* pUserData) +{ + (void) messageSeverity; + (void) messageType; + (void) pUserData; + std::cerr << "Validation layer: " << pCallbackData->pMessage << std::endl; + return VK_FALSE; +} #endif namespace iris { @@ -25,20 +46,24 @@ namespace iris { Device::Device(std::vector layers, std::vector instance_extensions) { VkApplicationInfo app_info = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pApplicationName = "IrisRenderer", + .pApplicationName = "Iris Renderer", .applicationVersion = VK_MAKE_VERSION(1, 0, 0), .pEngineName = "No Engine", .engineVersion = VK_MAKE_VERSION(1, 0, 0), .apiVersion = VK_API_VERSION_1_3, }; +#ifdef USE_VULKAN_VALIDATION_LAYERS + layers.push_back("VK_LAYER_KHRONOS_validation"); + instance_extensions.push_back("VK_EXT_debug_utils"); +#endif + // Create the Vulkan instance uint32_t enabled_layer_count = layers.size(); std::vector layers_cstr; for (const auto& layer : layers) { layers_cstr.push_back(layer.c_str()); } - uint32_t enabled_extension_count = instance_extensions.size(); std::vector instance_extensions_cstr; for (const auto& extension : instance_extensions) { @@ -59,16 +84,32 @@ Device::Device(std::vector layers, std::vector instanc &instance)); #ifdef USE_VULKAN_VALIDATION_LAYERS - layers.push_back("VK_LAYER_KHRONOS_validation"); - auto vkCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); + auto vkCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT) + vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT"); if (vkCreateDebugReportCallback) { VkDebugReportCallbackCreateInfoEXT debug_report_create_info = { .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT, - .flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, + .flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | + VK_DEBUG_REPORT_WARNING_BIT_EXT | + VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT, .pfnCallback = debug_report, }; CHECK_VULKAN(vkCreateDebugReportCallback(instance, &debug_report_create_info, nullptr, &debugReportCallback)); } + auto vkCreateDebugUtilsMessenger = (PFN_vkCreateDebugUtilsMessengerEXT) + vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); + if (vkCreateDebugUtilsMessenger) { + VkDebugUtilsMessengerCreateInfoEXT debug_utils_create_info = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT, + .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | + VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT, + .pfnUserCallback = debug_callback, + }; + CHECK_VULKAN(vkCreateDebugUtilsMessenger(instance, &debug_utils_create_info, nullptr, &debugUtilsMessenger)); + } #endif // Enumerate and select the physical device @@ -196,6 +237,7 @@ CommandBuffer::CommandBuffer(VkDevice device, { VkCommandPoolCreateInfo pool_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, .queueFamilyIndex = queue_family_index, // TODO: query capabilities to find a proper queue index }; CHECK_VULKAN(vkCreateCommandPool( @@ -225,7 +267,41 @@ CommandBuffer::CommandBuffer(VkDevice device, &fence)); } -CommandBuffer::~CommandBuffer() { +AsyncCommandBuffer::AsyncCommandBuffer(VkDevice device, + uint32_t queue_family_index, + VkQueue queue) + : device(device), queue(queue) +{ + VkCommandPoolCreateInfo pool_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = queue_family_index, // TODO: query capabilities to find a proper queue index + }; + CHECK_VULKAN(vkCreateCommandPool( + device, + &pool_info, + VK_NULL_HANDLE, + &this->pool)); + + VkCommandBufferAllocateInfo buffer_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .commandPool = this->pool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + CHECK_VULKAN(vkAllocateCommandBuffers( + device, + &buffer_info, + &buffer)); +} + +void AsyncCommandBuffer::destroy() { + vkFreeCommandBuffers(device, pool, 1, &buffer); + vkDestroyCommandPool(device, pool, VK_NULL_HANDLE); +} + + +void CommandBuffer::destroy() { vkDestroyFence(device, fence, VK_NULL_HANDLE); vkFreeCommandBuffers(device, pool, 1, &buffer); vkDestroyCommandPool(device, pool, VK_NULL_HANDLE); @@ -235,6 +311,10 @@ CommandBuffer Device::create_command_buffer() { return CommandBuffer(device, main_queue_family_index, graphics_queue); } +AsyncCommandBuffer Device::create_async_command_buffer() { + return AsyncCommandBuffer(device, main_queue_family_index, graphics_queue); +} + void CommandBuffer::begin(VkCommandBufferUsageFlags flags) { CHECK_VULKAN(vkResetFences(device, 1, &fence)); CHECK_VULKAN(vkResetCommandPool(device, pool, 0u)); @@ -284,8 +364,12 @@ void Buffer_t::unmap() { } } -Buffer_t::~Buffer_t() { - vmaDestroyBuffer(allocator, buffer, allocation); +void Buffer_t::release() { + if (buffer != VK_NULL_HANDLE) { + std::cerr << "Destroying buffer: 0x" << std::hex << (uint64_t)buffer << std::endl; + vmaDestroyBuffer(allocator, buffer, allocation); + buffer = VK_NULL_HANDLE; + } } Buffer_t Device::create_buffer_raw(VkDeviceSize size, @@ -319,9 +403,12 @@ Buffer Device::create_buffer(VkDeviceSize size, return std::make_shared(create_buffer_raw(size, usage, create_info)); } -Texture2D_t::~Texture2D_t() { - vmaDestroyImage(allocator, image, allocation); - // TODO: optionally destroy image view, if created +void Texture2D_t::release() { + if (image != VK_NULL_HANDLE) { + std::cerr << "Destroying image: 0x" << std::hex << (uint64_t)image << std::endl; + vmaDestroyImage(allocator, image, allocation); + image = VK_NULL_HANDLE; + } } Texture2D_t Device::create_texture_raw(VkExtent2D extent, @@ -353,6 +440,7 @@ Texture2D_t Device::create_texture_raw(VkExtent2D extent, &texture.image, &texture.allocation, VK_NULL_HANDLE)); + std::cerr << "Created image: 0x" << std::hex << (uint64_t)texture.image << std::endl; return texture; } @@ -361,7 +449,9 @@ Texture2D Device::create_texture(VkExtent2D extent, VkImageUsageFlags usage, VmaAllocationCreateInfo create_info) { - return std::make_shared(create_texture_raw(extent, format, usage, 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, @@ -393,7 +483,7 @@ Texture2D Device::create_texture_from_image(const char* filename, stbi_image_free(pixels); VkExtent2D extent = {static_cast(width), static_cast(height)}; - Texture2D_t texture = create_texture_raw(extent, format, usage, create_info); + Texture2D texture = create_texture(extent, format, usage, create_info); // Transit image layout for copying { @@ -403,15 +493,16 @@ 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 = 0, + .srcAccessMask = VK_ACCESS_NONE, .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = texture.image, + .image = texture->image, .subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .levelCount = 1, @@ -460,7 +551,7 @@ Texture2D Device::create_texture_from_image(const char* filename, vkCmdCopyBufferToImage( cmd_buf.buffer, staging_buf.buffer, - texture.image, + texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); @@ -490,7 +581,7 @@ Texture2D Device::create_texture_from_image(const char* filename, .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = texture.image, + .image = texture->image, .subresourceRange = { .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, .levelCount = 1, @@ -514,8 +605,10 @@ Texture2D Device::create_texture_from_image(const char* filename, CHECK_VULKAN(vkQueueSubmit(graphics_queue, 1, &submit_info, cmd_buf.fence)); CHECK_VULKAN(vkWaitForFences(cmd_buf.device, 1, &cmd_buf.fence, VK_TRUE, std::numeric_limits::max())); } - texture.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; - return std::make_shared(texture); + texture->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; + std::cerr << "Image layout transition done" << std::endl; + staging_buf.release(); + return texture; } } // namespace iris \ No newline at end of file -- cgit v1.2.3-70-g09d2