diff --git a/main.cpp b/main.cpp index dfdcc9b..6e3651e 100644 --- a/main.cpp +++ b/main.cpp @@ -170,8 +170,8 @@ int main() { check(volkInitialize()); display_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay()); - window = SDL_CreateWindow("How To Vulkan", (i32)(display_scale * 1920), - (i32)(display_scale * 1080), SDL_WINDOW_VULKAN); + window = SDL_CreateWindow("How To Vulkan", (i32)(display_scale * 1920), (i32)(display_scale * 1080), + SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE); check(window != nullptr, EXIT_CODE_WINDOW_CREATION_FAILED); // }}} @@ -1373,11 +1373,91 @@ int main() { } } // }}} + + // {{{ Recreate Swapchain If Needed + if (update_swapchain) { + // TODO (Abdelrahman): This doesn't work well. Debug it. + update_swapchain = false; + check(vkDeviceWaitIdle(device)); + + check(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device, surface, &surface_caps)); + + // Create new swapchain + swapchain_create_info.oldSwapchain = swapchain; + swapchain_create_info.imageExtent = { (u32)window_size.x, (u32)window_size.y }; + check(vkCreateSwapchainKHR(device, &swapchain_create_info, NULL, &swapchain)); + + // Clean old image views + for (u32 i = 0; i < swapchain_image_count; ++i) { + vkDestroyImageView(device, swapchain_views[i], NULL); + } + + // Clean old render_completed semaphores + for (u32 i = 0; i < swapchain_image_count; ++i) { + vkDestroySemaphore(device, render_completed_semaphores[i], NULL); + } + + // Get new swapchain images + check(vkGetSwapchainImagesKHR(device, swapchain, &swapchain_image_count, nullptr)); + if (swapchain_image_count != wapp_array_count(swapchain_images)) { + swapchain_images = wapp_array_alloc_capacity(VkImage, &arena, swapchain_image_count, ARRAY_INIT_FILLED); + swapchain_views = wapp_array_alloc_capacity(VkImageView, &arena, swapchain_image_count, ARRAY_INIT_FILLED); + render_completed_semaphores = wapp_array_alloc_capacity(VkSemaphore, &arena, swapchain_image_count, ARRAY_INIT_FILLED); + } + check(swapchain_images != nullptr, EXIT_CODE_ALLOCATION_FAILURE); + check(vkGetSwapchainImagesKHR(device, swapchain, &swapchain_image_count, swapchain_images)); + + check(swapchain_views != nullptr, EXIT_CODE_ALLOCATION_FAILURE); + + for (u32 i = 0; i < swapchain_image_count; ++i) { + VkImageViewCreateInfo view_create_info = {}; + view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_create_info.image = swapchain_images[i]; + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_create_info.format = image_format; + view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + view_create_info.subresourceRange.levelCount = 1; + view_create_info.subresourceRange.layerCount = 1; + + check(vkCreateImageView(device, &view_create_info, nullptr, &swapchain_views[i])); + } + + check(render_completed_semaphores != nullptr, EXIT_CODE_SYNC_OBJ_CREATE_FAILED); + + for (u32 i = 0; i < swapchain_image_count; ++i) { + check(vkCreateSemaphore(device, &semaphore_create_info, NULL, &render_completed_semaphores[i])); + } + + vkDestroySwapchainKHR(device, swapchain_create_info.oldSwapchain, NULL); + vmaDestroyImage(allocator, depth_image, depth_allocation); + vkDestroyImageView(device, depth_view, NULL); + + depth_image_create_info.extent = { (u32)window_size.x, (u32)window_size.y, 1 }; + + VmaAllocationCreateInfo alloc_create_info = {}; + alloc_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; + alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO; + + check(vmaCreateImage(allocator, &depth_image_create_info, &alloc_create_info, &depth_image, + &depth_allocation, nullptr)); + + VkImageViewCreateInfo view_create_info = {}; + view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + view_create_info.image = depth_image; + view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; + view_create_info.format = depth_format; + view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + view_create_info.subresourceRange.levelCount = 1; + view_create_info.subresourceRange.layerCount = 1; + + check(vkCreateImageView(device, &view_create_info, NULL, &depth_view)); + } + // }}} } // }}} // {{{ Cleanup - check(vkQueueWaitIdle(queue)); + check(vkDeviceWaitIdle(device)); vkDestroyPipeline(device, graphics_pipeline, NULL); vkDestroyPipelineLayout(device, graphics_pipeline_layout, NULL);