From 3c72c9b387aa81337c78f36b692705a02c4d5fcf Mon Sep 17 00:00:00 2001 From: Piotr Krygier Date: Thu, 8 Feb 2024 10:04:20 +0100 Subject: [PATCH] Fixed window resizing --- graphics/src/rse_vulkan_image.c | 18 +++++++++--------- graphics/src/rse_vulkan_image.h | 3 +++ graphics/src/vulkan_base.c | 17 +++++++++++++---- graphics/src/vulkan_pipeline.c | 11 +++++++---- graphics/src/window.c | 25 +++++++++++++++++++++++++ graphics/src/window.h | 4 ++++ 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/graphics/src/rse_vulkan_image.c b/graphics/src/rse_vulkan_image.c index e4b2f1ed..39c14215 100644 --- a/graphics/src/rse_vulkan_image.c +++ b/graphics/src/rse_vulkan_image.c @@ -191,7 +191,7 @@ static rse_err_t create_image_view(struct rse_vulkan_image_t* image, VkFormat fo return RSE_ERROR_NO_ERROR; } -static rse_err_t create_color_resource() +rse_err_t rse_create_color_resource() { rse_err_t status = RSE_ERROR_NO_ERROR; VkFormat color_format = IMAGE_FORMAT; @@ -262,7 +262,7 @@ static rse_err_t format_to_pixel_size(VkFormat format, return RSE_ERROR_NO_ERROR; } -static rse_err_t transition_image_layout(struct rse_vulkan_image_t* image, VkImageLayout old_layout, VkImageLayout new_layout) +static rse_err_t transition_image_layout(struct rse_vulkan_image_t* image, VkImageLayout old_layout, VkImageLayout new_layout) { VkImageSubresourceRange range = {0}; VkImageMemoryBarrier image_barrier = {0}; @@ -464,7 +464,7 @@ rse_err_t init_vulkan_images() STATUS_CHECK(create_sampler()); STATUS_CHECK(rse_create_depth_resources()); - // STATUS_CHECK(create_color_resource()); + STATUS_CHECK(rse_create_color_resource()); return status; } @@ -516,20 +516,20 @@ void rse_destroy_textures() vmaDestroyImage(g_vulkan_state.allocator, g_texture_images[i].image, g_texture_images[i].allocation); } } - - vkDestroyImageView(g_vulkan_state.device, g_depth_image.image_view, NULL); - vkDestroyImageView(g_vulkan_state.device, g_color_image.image_view, NULL); - vmaDestroyImage(g_vulkan_state.allocator, g_depth_image.image, g_depth_image.allocation); - vmaDestroyImage(g_vulkan_state.allocator, g_color_image.image, g_color_image.allocation); } void rse_destroy_depth_resource() { - vkDestroyImageView(g_vulkan_state.device, g_depth_image.image_view, NULL); vmaDestroyImage(g_vulkan_state.allocator, g_depth_image.image, g_depth_image.allocation); } +void rse_destroy_color_resource() +{ + vkDestroyImageView(g_vulkan_state.device, g_color_image.image_view, NULL); + vmaDestroyImage(g_vulkan_state.allocator, g_color_image.image, g_color_image.allocation); +} + uint8_t image_exists(uint8_t image_id) { return g_texture_images[image_id].id_taken == IMAGE_TAKEN; } diff --git a/graphics/src/rse_vulkan_image.h b/graphics/src/rse_vulkan_image.h index 2fdac902..0b3f4649 100644 --- a/graphics/src/rse_vulkan_image.h +++ b/graphics/src/rse_vulkan_image.h @@ -93,6 +93,9 @@ VkImageView rse_get_depth_image_view(void); VkImageView rse_get_color_image_view(void); +rse_err_t rse_create_color_resource(void); +void rse_destroy_color_resource(void); + rse_err_t rse_create_depth_resources(void); void rse_destroy_depth_resource(void); diff --git a/graphics/src/vulkan_base.c b/graphics/src/vulkan_base.c index bc49df1f..dc7872ea 100644 --- a/graphics/src/vulkan_base.c +++ b/graphics/src/vulkan_base.c @@ -29,6 +29,7 @@ #include "locale_vulkan.h" #include "utilities/rse_errors_common.h" #include "utilities/logger.h" +#include "vulkan/vulkan_core.h" #include "vulkan_errors.h" #include "window.h" @@ -553,8 +554,8 @@ static rse_err_t create_sync_objects() if (VK_SUCCESS != vkCreateSemaphore(g_vulkan_state.device, &semaphore_info, NULL, &g_image_available_semaphores[i]) || VK_SUCCESS != vkCreateSemaphore(g_vulkan_state.device, &semaphore_info, NULL, &g_render_finished_semaphores[i]) || VK_SUCCESS != vkCreateFence(g_vulkan_state.device, &fenceInfo, NULL, &g_in_flight_fences[i])) { - LOGF(vulkan_messages[VULKAN_SYNCOBJCTS_CREATION_FAILED]); - return VULKAN_ERROR_SYNCOBJCTS_CREATION_FAILED; + LOGF(vulkan_messages[VULKAN_SYNCOBJCTS_CREATION_FAILED]); + return VULKAN_ERROR_SYNCOBJCTS_CREATION_FAILED; } } @@ -613,7 +614,7 @@ rse_err_t draw_frame() result = vkAcquireNextImageKHR(g_vulkan_state.device, g_vulkan_state.swapchain, UINT64_MAX, g_image_available_semaphores[g_vulkan_state.current_frame], VK_NULL_HANDLE, &image_index); - if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { + if (result == VK_ERROR_OUT_OF_DATE_KHR) { recreate_swapchain(); return RSE_ERROR_NO_ERROR; } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { @@ -660,7 +661,15 @@ rse_err_t draw_frame() present_info.pImageIndices = &image_index; - vkQueuePresentKHR(g_present_queue, &present_info); + result = vkQueuePresentKHR(g_present_queue, &present_info); + + if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || is_framebuffer_resized()) { + reset_framebuffer_resized(); + recreate_swapchain(); + } else if (result != VK_SUCCESS) { + LOGF(vulkan_messages[VULAKN_DRAW_FAILED]); + return VULKAN_ERROR_DRAW_FAILED; + } g_vulkan_state.current_frame = (g_vulkan_state.current_frame + 1) % SWAP_BUFFER_COUNT; diff --git a/graphics/src/vulkan_pipeline.c b/graphics/src/vulkan_pipeline.c index c2650c8f..18ccd665 100644 --- a/graphics/src/vulkan_pipeline.c +++ b/graphics/src/vulkan_pipeline.c @@ -780,16 +780,20 @@ void recreate_swapchain() { int width = 0; int height = 0; - + + glfwGetFramebufferSize(get_window_handle(), &width, &height); while (width == 0 || height == 0) { glfwGetFramebufferSize(get_window_handle(), &width, &height); glfwWaitEvents(); } + vkDeviceWaitIdle(g_vulkan_state.device); + cleanup_swapchain(); - + create_swapchain(); create_swapchain_image_views(); + rse_create_color_resource(); rse_create_depth_resources(); create_framebuffers(); } @@ -802,8 +806,7 @@ void cleanup_swapchain() { size_t i; - vkDeviceWaitIdle(g_vulkan_state.device); - + rse_destroy_color_resource(); rse_destroy_depth_resource(); for (i = 0; i < g_swapchain_images_count; i++) { vkDestroyFramebuffer(g_vulkan_state.device, g_vulkan_state.swapchain_framebuffers[i], NULL); diff --git a/graphics/src/window.c b/graphics/src/window.c index d819c3f6..df485aec 100644 --- a/graphics/src/window.c +++ b/graphics/src/window.c @@ -10,14 +10,19 @@ */ #include "window.h" +#include +#include "GLFW/glfw3.h" #include "locale_window.h" #include "rse_window_errors.h" +#include "src/vulkan_commons.h" #include "utilities/logger.h" #include "utilities/rse_errors_common.h" +#include "vulkan/vulkan_core.h" #include "vulkan_base.h" GLFWwindow *g_window_handle = NULL; +uint8_t g_is_frambuffer_resized = 0U; /** * @brief GLFW error callback @@ -51,6 +56,14 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, } } +static void framebuffer_resized_callback(GLFWwindow* window, int width, int height) +{ + (void)window; + (void)width; + (void)height; + g_is_frambuffer_resized = 1; +} + rse_err_t window_init() { @@ -82,6 +95,7 @@ rse_err_t window_init() } glfwSetKeyCallback(g_window_handle, key_callback); + glfwSetFramebufferSizeCallback(g_window_handle, framebuffer_resized_callback); return RSE_ERROR_NO_ERROR; } @@ -93,6 +107,7 @@ rse_err_t window_loop() draw_frame(); } + vkDeviceWaitIdle(g_vulkan_state.device); return RSE_ERROR_NO_ERROR; } @@ -107,3 +122,13 @@ GLFWwindow* get_window_handle() { return g_window_handle; } + +uint8_t is_framebuffer_resized() +{ + return g_is_frambuffer_resized; +} + +void reset_framebuffer_resized() +{ + g_is_frambuffer_resized = 0U; +} diff --git a/graphics/src/window.h b/graphics/src/window.h index 520809a5..288c7afe 100644 --- a/graphics/src/window.h +++ b/graphics/src/window.h @@ -12,6 +12,7 @@ #ifndef RSE_WINDOW_H #define RSE_WINDOW_H +#include #include /* Vulkan header MUST be included before glfw */ @@ -45,4 +46,7 @@ void window_terminate(); GLFWwindow* get_window_handle(); +uint8_t is_framebuffer_resized(void); +void reset_framebuffer_resized(void); + #endif /* RSE_WINDOW_H */