diff options
Diffstat (limited to 'main.c')
-rw-r--r-- | main.c | 72 |
1 files changed, 55 insertions, 17 deletions
@@ -38,7 +38,7 @@ static struct { static struct { size_t len; VkFramebuffer data[]; -} *swapchain_buffers; +} *framebuffers; struct code { size_t len; @@ -130,6 +130,16 @@ bool found_queue_indx(struct queue_indices inds) { return inds.found_queues == (GRAPHICS | PRESENT); } +void cleanup_swapchain() { + for (size_t i = 0; i < framebuffers->len; i++) { + vkDestroyFramebuffer(gpu, framebuffers->data[i], NULL); + } + for (size_t i = 0; i < swapchain_image_views->len; i++) { + vkDestroyImageView(gpu, swapchain_image_views->data[i], NULL); + } + vkDestroySwapchainKHR(gpu, swapchain, NULL); +} + void cleanup() { vkDeviceWaitIdle(gpu); for (size_t i = 0; i < MAX_FRAMES_INFLIGHT; i++) { @@ -137,17 +147,11 @@ void cleanup() { vkDestroySemaphore(gpu, render_finished[i], NULL); vkDestroyFence(gpu, in_flight_fence[i], NULL); } + cleanup_swapchain(); vkDestroyCommandPool(gpu, command_pool, NULL); - for (size_t i = 0; i < swapchain_buffers->len; i++) { - vkDestroyFramebuffer(gpu, swapchain_buffers->data[i], NULL); - } vkDestroyPipeline(gpu, graphics_pipeline, NULL); vkDestroyPipelineLayout(gpu, pipeline_layout, NULL); vkDestroyRenderPass(gpu, render_pass, NULL); - for (size_t i = 0; i < swapchain_image_views->len; i++) { - vkDestroyImageView(gpu, swapchain_image_views->data[i], NULL); - } - vkDestroySwapchainKHR(gpu, swapchain, NULL); vkDestroySurfaceKHR(instance, surface, NULL); vkDestroyDevice(gpu, NULL); vkDestroyInstance(instance, NULL); @@ -648,8 +652,8 @@ void create_render_pass() { } void create_framebuffers() { - swapchain_buffers = malloc(sizeof(*swapchain_buffers) + sizeof(*swapchain_buffers->data) * swapchain_image_views->len); - swapchain_buffers->len = swapchain_image_views->len; + framebuffers = malloc(sizeof(*framebuffers) + sizeof(*framebuffers->data) * swapchain_image_views->len); + framebuffers->len = swapchain_image_views->len; for (size_t i = 0; i < swapchain_image_views->len; i++) { VkImageView attachs[] = { @@ -666,7 +670,7 @@ void create_framebuffers() { .layers = 1 }; - VkResult res = vkCreateFramebuffer(gpu, &framebuffer_info, NULL, &swapchain_buffers->data[i]); + VkResult res = vkCreateFramebuffer(gpu, &framebuffer_info, NULL, &framebuffers->data[i]); if (res != VK_SUCCESS) { fputs("failed to create framebuffer", stderr); exit(-1); @@ -720,7 +724,7 @@ void record_command_buffer(VkCommandBuffer buffer, uint32_t image_index) { VkRenderPassBeginInfo render_pass_info = { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, .renderPass = render_pass, - .framebuffer = swapchain_buffers->data[image_index], + .framebuffer = framebuffers->data[image_index], .renderArea = { .extent = swapchain_extent, .offset = {0, 0} @@ -776,9 +780,27 @@ void create_sync_objects() { } } +void recreate_swapchain() { + int32_t width = 0, height = 0; + SDL_GetWindowSize(window, &width, &height); + while (width == 0 || height == 0) { + SDL_Event e; + SDL_PollEvent(&e); + SDL_GetWindowSize(window, &width, &height); + } + + vkDeviceWaitIdle(gpu); + + cleanup_swapchain(); + + create_swapchain(); + create_image_views(); + create_framebuffers(); +} + void init() { SDL_Init(SDL_INIT_VIDEO); - window = SDL_CreateWindow("vk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 800, SDL_WINDOW_VULKAN); + window = SDL_CreateWindow("vk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 800, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE); if (!window) { fputs("failed to create sdl window", stderr); exit(-1); @@ -818,10 +840,22 @@ void init() { void draw() { vkWaitForFences(gpu, 1, &in_flight_fence[current_frame], VK_TRUE, UINT64_MAX); - vkResetFences(gpu, 1, &in_flight_fence[current_frame]); uint32_t image_index; - vkAcquireNextImageKHR(gpu, swapchain, UINT64_MAX, image_avail[current_frame], VK_NULL_HANDLE, &image_index); + VkResult res = vkAcquireNextImageKHR(gpu, swapchain, UINT64_MAX, image_avail[current_frame], VK_NULL_HANDLE, &image_index); + switch (res) { + case VK_SUCCESS: + break; + case VK_ERROR_OUT_OF_DATE_KHR: + case VK_SUBOPTIMAL_KHR: + recreate_swapchain(); + return; + default: + fputs("failed to acquire swapchain images", stderr); + exit(-1); + } + + vkResetFences(gpu, 1, &in_flight_fence[current_frame]); vkResetCommandBuffer(command_buffers[current_frame], 0); record_command_buffer(command_buffers[current_frame], image_index); @@ -839,7 +873,7 @@ void draw() { .pCommandBuffers = &command_buffers[current_frame] }; - VkResult res = vkQueueSubmit(gfx_queue, 1, &submit_info, in_flight_fence[current_frame]); + res = vkQueueSubmit(gfx_queue, 1, &submit_info, in_flight_fence[current_frame]); if (res != VK_SUCCESS) { fputs("failed to submit draw command buffer", stderr); exit(-1); @@ -864,8 +898,12 @@ int main() { init(); SDL_Event e; - while (SDL_PollEvent(&e), e.type != SDL_QUIT) + while (SDL_PollEvent(&e), e.type != SDL_QUIT) { + if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_RESIZED) { + recreate_swapchain(); + } draw(); + } cleanup(); return 0; |