summaryrefslogtreecommitdiffstats
path: root/src/renderer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer.c')
-rw-r--r--src/renderer.c104
1 files changed, 73 insertions, 31 deletions
diff --git a/src/renderer.c b/src/renderer.c
index d95cf99..7022af6 100644
--- a/src/renderer.c
+++ b/src/renderer.c
@@ -734,9 +734,7 @@ choose_swapchain_extent(const VkSurfaceCapabilitiesKHR *capabilities, int width,
}
}
-static bool vgltf_renderer_create_swapchain(struct vgltf_renderer *renderer,
- int window_width_px,
- int window_height_px) {
+static bool vgltf_renderer_create_swapchain(struct vgltf_renderer *renderer) {
struct swapchain_support_details swapchain_support_details = {};
swapchain_support_details_query_from_device(
&swapchain_support_details, renderer->physical_device, renderer->surface);
@@ -748,9 +746,9 @@ static bool vgltf_renderer_create_swapchain(struct vgltf_renderer *renderer,
swapchain_support_details.present_modes,
swapchain_support_details.present_mode_count);
- VkExtent2D extent =
- choose_swapchain_extent(&swapchain_support_details.capabilities,
- window_width_px, window_height_px);
+ VkExtent2D extent = choose_swapchain_extent(
+ &swapchain_support_details.capabilities, renderer->window_size.width,
+ renderer->window_size.height);
uint32_t image_count =
swapchain_support_details.capabilities.minImageCount + 1;
if (swapchain_support_details.capabilities.maxImageCount > 0 &&
@@ -1181,18 +1179,59 @@ err:
return false;
}
+static void vgltf_renderer_cleanup_swapchain(struct vgltf_renderer *renderer) {
+ for (uint32_t framebuffer_index = 0;
+ framebuffer_index < renderer->swapchain_image_count;
+ framebuffer_index++) {
+ vkDestroyFramebuffer(renderer->device,
+ renderer->swapchain_framebuffers[framebuffer_index],
+ nullptr);
+ }
+
+ for (uint32_t image_view_index = 0;
+ image_view_index < renderer->swapchain_image_count; image_view_index++) {
+ vkDestroyImageView(renderer->device,
+ renderer->swapchain_image_views[image_view_index],
+ nullptr);
+ }
+
+ vkDestroySwapchainKHR(renderer->device, renderer->swapchain, nullptr);
+}
+
+static bool vgltf_renderer_recreate_swapchain(struct vgltf_renderer *renderer) {
+ vkDeviceWaitIdle(renderer->device);
+ vgltf_renderer_cleanup_swapchain(renderer);
+
+ // TODO add error handling
+ vgltf_renderer_create_swapchain(renderer);
+ vgltf_renderer_create_image_views(renderer);
+ vgltf_renderer_create_framebuffers(renderer);
+ return true;
+}
+
bool vgltf_renderer_triangle_pass(struct vgltf_renderer *renderer) {
vkWaitForFences(renderer->device, 1,
&renderer->in_flight_fences[renderer->current_frame], VK_TRUE,
UINT64_MAX);
- vkResetFences(renderer->device, 1,
- &renderer->in_flight_fences[renderer->current_frame]);
uint32_t image_index;
- vkAcquireNextImageKHR(
+ VkResult acquire_swapchain_image_result = vkAcquireNextImageKHR(
renderer->device, renderer->swapchain, UINT64_MAX,
renderer->image_available_semaphores[renderer->current_frame],
VK_NULL_HANDLE, &image_index);
+ if (acquire_swapchain_image_result == VK_ERROR_OUT_OF_DATE_KHR ||
+ acquire_swapchain_image_result == VK_SUBOPTIMAL_KHR ||
+ renderer->framebuffer_resized) {
+ renderer->framebuffer_resized = false;
+ vgltf_renderer_recreate_swapchain(renderer);
+ return true;
+ } else if (acquire_swapchain_image_result != VK_SUCCESS) {
+ VGLTF_LOG_ERR("Failed to acquire a swapchain image");
+ goto err;
+ }
+
+ vkResetFences(renderer->device, 1,
+ &renderer->in_flight_fences[renderer->current_frame]);
vkResetCommandBuffer(renderer->command_buffer[renderer->current_frame], 0);
VkCommandBufferBeginInfo begin_info = {
@@ -1277,7 +1316,15 @@ bool vgltf_renderer_triangle_pass(struct vgltf_renderer *renderer) {
present_info.swapchainCount = 1;
present_info.pSwapchains = swapchains;
present_info.pImageIndices = &image_index;
- vkQueuePresentKHR(renderer->present_queue, &present_info);
+ VkResult result = vkQueuePresentKHR(renderer->present_queue, &present_info);
+ if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
+ vgltf_renderer_recreate_swapchain(renderer);
+ } else if (acquire_swapchain_image_result != VK_SUCCESS) {
+ VGLTF_LOG_ERR("Failed to acquire a swapchain image");
+ goto err;
+ }
+ renderer->current_frame =
+ (renderer->current_frame + 1) % VGLTF_RENDERER_MAX_FRAME_IN_FLIGHT_COUNT;
return true;
err:
return false;
@@ -1308,9 +1355,9 @@ bool vgltf_renderer_init(struct vgltf_renderer *renderer,
VGLTF_LOG_ERR("Couldn't get window size");
goto destroy_device;
}
+ renderer->window_size = window_size;
- if (!vgltf_renderer_create_swapchain(renderer, window_size.width,
- window_size.height)) {
+ if (!vgltf_renderer_create_swapchain(renderer)) {
VGLTF_LOG_ERR("Couldn't create swapchain");
goto destroy_device;
}
@@ -1392,6 +1439,10 @@ err:
}
void vgltf_renderer_deinit(struct vgltf_renderer *renderer) {
vkDeviceWaitIdle(renderer->device);
+ vgltf_renderer_cleanup_swapchain(renderer);
+ vkDestroyPipeline(renderer->device, renderer->graphics_pipeline, nullptr);
+ vkDestroyPipelineLayout(renderer->device, renderer->pipeline_layout, nullptr);
+ vkDestroyRenderPass(renderer->device, renderer->render_pass, nullptr);
for (int i = 0; i < VGLTF_RENDERER_MAX_FRAME_IN_FLIGHT_COUNT; i++) {
vkDestroySemaphore(renderer->device,
renderer->image_available_semaphores[i], nullptr);
@@ -1400,29 +1451,20 @@ void vgltf_renderer_deinit(struct vgltf_renderer *renderer) {
vkDestroyFence(renderer->device, renderer->in_flight_fences[i], nullptr);
}
vkDestroyCommandPool(renderer->device, renderer->command_pool, nullptr);
- for (uint32_t swapchain_framebuffer_index = 0;
- swapchain_framebuffer_index < renderer->swapchain_image_count;
- swapchain_framebuffer_index++) {
- vkDestroyFramebuffer(
- renderer->device,
- renderer->swapchain_framebuffers[swapchain_framebuffer_index], nullptr);
- }
- vkDestroyPipeline(renderer->device, renderer->graphics_pipeline, nullptr);
- vkDestroyPipelineLayout(renderer->device, renderer->pipeline_layout, nullptr);
- vkDestroyRenderPass(renderer->device, renderer->render_pass, nullptr);
- for (uint32_t swapchain_image_view_index = 0;
- swapchain_image_view_index < renderer->swapchain_image_count;
- swapchain_image_view_index++) {
- vkDestroyImageView(
- renderer->device,
- renderer->swapchain_image_views[swapchain_image_view_index], nullptr);
- }
- vkDestroySwapchainKHR(renderer->device, renderer->swapchain, nullptr);
vkDestroyDevice(renderer->device, nullptr);
- vkDestroySurfaceKHR(renderer->instance, renderer->surface, nullptr);
if (enable_validation_layers) {
destroy_debug_utils_messenger_ext(renderer->instance,
renderer->debug_messenger, nullptr);
}
+ vkDestroySurfaceKHR(renderer->instance, renderer->surface, nullptr);
vkDestroyInstance(renderer->instance, nullptr);
}
+void vgltf_renderer_on_window_resized(struct vgltf_renderer *renderer,
+ struct vgltf_window_size size) {
+ if (size.width > 0 && size.height > 0 &&
+ size.width != renderer->window_size.width &&
+ size.height != renderer->window_size.height) {
+ renderer->window_size = size;
+ renderer->framebuffer_resized = true;
+ }
+}
Go back to lisible.xyz