From 2ead02037dc89e987fbc0a021fe470e29d226cfd Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Sat, 7 Sep 2024 00:40:38 -0700 Subject: Add more encapsulation, use VMA for allocation --- src/vulkan_swapchain.cpp | 208 +++++++++++++++++++++++++---------------------- 1 file changed, 112 insertions(+), 96 deletions(-) (limited to 'src/vulkan_swapchain.cpp') diff --git a/src/vulkan_swapchain.cpp b/src/vulkan_swapchain.cpp index 651b558..fde4388 100644 --- a/src/vulkan_swapchain.cpp +++ b/src/vulkan_swapchain.cpp @@ -10,6 +10,7 @@ #include #include #include +#include std::vector get_glfw_instance_extensions() { uint32_t extension_count = 0; @@ -25,6 +26,116 @@ std::vector get_glfw_instance_extensions() { namespace iris { +void Swapchain::resize(uint32_t new_width, uint32_t new_height) { + width = new_width; + height = new_height; + + // wait for the device to finish + CHECK_VULKAN(vkDeviceWaitIdle(device.device)); + + // destroy old resources + if (swapchain != VK_NULL_HANDLE) { + for (uint32_t i = 0; i < SWAPCHAIN_IMAGE_COUNT; i++) { + vkDestroyFramebuffer(device.device, framebuffers[i], nullptr); + vkDestroyImageView(device.device, swapchain_image_views[i], nullptr); + } + vkDestroySwapchainKHR(device.device, swapchain, nullptr); + } + + VkSwapchainCreateInfoKHR swapchain_create_info = { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .surface = surface, + .minImageCount = SWAPCHAIN_IMAGE_COUNT, + .imageFormat = VK_FORMAT_B8G8R8A8_UNORM, + .imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + .imageExtent = {width, height}, + .imageArrayLayers = 1, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, + .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR, + .clipped = VK_TRUE, + .oldSwapchain = VK_NULL_HANDLE, + }; + CHECK_VULKAN(vkCreateSwapchainKHR( + device.device, + &swapchain_create_info, + nullptr, + &swapchain)); + + // images + uint32_t image_count = 0; + CHECK_VULKAN(vkGetSwapchainImagesKHR( + device.device, + swapchain, + &image_count, + nullptr)); + if (image_count > SWAPCHAIN_IMAGE_COUNT) { + // TODO throw an exception + std::cerr << "Swapchain image count is greater than expected" << std::endl; + abort(); + } + CHECK_VULKAN(vkGetSwapchainImagesKHR( + device.device, + swapchain, + &image_count, + swapchain_images)); + + // image views + for (uint32_t i = 0; i < image_count; i++) { + VkImageViewCreateInfo image_view_create_info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .image = swapchain_images[i], + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .format = VK_FORMAT_B8G8R8A8_UNORM, + .components = { + .r = VK_COMPONENT_SWIZZLE_IDENTITY, + .g = VK_COMPONENT_SWIZZLE_IDENTITY, + .b = VK_COMPONENT_SWIZZLE_IDENTITY, + .a = VK_COMPONENT_SWIZZLE_IDENTITY, + }, + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; + + CHECK_VULKAN(vkCreateImageView( + device.device, + &image_view_create_info, + nullptr, + &swapchain_image_views[i])); + } + + // framebuffers + for (uint32_t i = 0; i < image_count; i++) { + VkFramebufferCreateInfo frame_buffer_create_info = { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .renderPass = render_pass, + .attachmentCount = 1, + .pAttachments = &swapchain_image_views[i], + .width = width, + .height = height, + .layers = 1, + }; + CHECK_VULKAN(vkCreateFramebuffer( + device.device, + &frame_buffer_create_info, + nullptr, + &framebuffers[i])); + } + + upload_texture = device.create_texture( + {width, height}, + VK_FORMAT_B8G8R8A8_UNORM, + VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE); +} + Swapchain::Swapchain( GLFWwindow *window, iris::Device device) : device(device), window(window) @@ -129,102 +240,7 @@ Swapchain::Swapchain( &render_pass)); // Create swapchain and image/imageview/framebuffers - // TODO: move this into `resize` to support resizing - { - // swapchain - int i_width, i_height; - glfwGetFramebufferSize(window, &i_width, &i_height); - width = (uint32_t) i_width; - height = (uint32_t) i_height; - - VkSwapchainCreateInfoKHR swapchain_create_info = { - .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .surface = surface, - .minImageCount = SWAPCHAIN_IMAGE_COUNT, - .imageFormat = VK_FORMAT_B8G8R8A8_UNORM, - .imageColorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - .imageExtent = {width, height}, - .imageArrayLayers = 1, - .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, - .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, - .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, - .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - .presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR, - .clipped = VK_TRUE, - .oldSwapchain = VK_NULL_HANDLE, - }; - CHECK_VULKAN(vkCreateSwapchainKHR( - device.device, - &swapchain_create_info, - nullptr, - &swapchain)); - - // images - uint32_t image_count = 0; - CHECK_VULKAN(vkGetSwapchainImagesKHR( - device.device, - swapchain, - &image_count, - nullptr)); - if (image_count > SWAPCHAIN_IMAGE_COUNT) { - // TODO throw an exception - std::cerr << "Swapchain image count is greater than expected" << std::endl; - abort(); - } - CHECK_VULKAN(vkGetSwapchainImagesKHR( - device.device, - swapchain, - &image_count, - swapchain_images)); - - // image views - for (uint32_t i = 0; i < image_count; i++) { - VkImageViewCreateInfo image_view_create_info = { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = swapchain_images[i], - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .format = VK_FORMAT_B8G8R8A8_UNORM, - .components = { - .r = VK_COMPONENT_SWIZZLE_IDENTITY, - .g = VK_COMPONENT_SWIZZLE_IDENTITY, - .b = VK_COMPONENT_SWIZZLE_IDENTITY, - .a = VK_COMPONENT_SWIZZLE_IDENTITY, - }, - .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - }, - }; - - CHECK_VULKAN(vkCreateImageView( - device.device, - &image_view_create_info, - nullptr, - &swapchain_image_views[i])); - } - - // framebuffers - for (uint32_t i = 0; i < image_count; i++) { - VkFramebufferCreateInfo frame_buffer_create_info = { - .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .renderPass = render_pass, - .attachmentCount = 1, - .pAttachments = &swapchain_image_views[i], - .width = width, - .height = height, - .layers = 1, - }; - CHECK_VULKAN(vkCreateFramebuffer( - device.device, - &frame_buffer_create_info, - nullptr, - &framebuffers[i])); - } - } - + this->resize(width, height); // Create descriptor pool VkDescriptorPoolSize pool_size = { -- cgit v1.2.3-70-g09d2