camera_cnn

Unnamed repository; edit this file 'description' to name the repository.
git clone anongit@rnpnr.xyz:camera_cnn.git
Log | Files | Refs | Feed | LICENSE

Commit: dda0049f9455f32e0b48d72c7bc9baa1e84918b3
Parent: 9011f7a3136ffa3d72c60471c500c459a7f2a65f
Author: Randy Palamar
Date:   Thu, 21 Aug 2025 19:49:36 -0600

core: support window resizing

Diffstat:
Mcommon.c | 59+++++++++++++++++++++++++++++++++++++++--------------------
Mutil.h | 1+
Mvulkan.h | 14+++++++++++++-
3 files changed, 53 insertions(+), 21 deletions(-)

diff --git a/common.c b/common.c @@ -55,6 +55,14 @@ key_callback(GLFWwindow *window, s32 key, s32 scancode, s32 action, s32 modifier ctx->should_exit = 1; } +function void +fb_callback(GLFWwindow *w, s32 width, s32 height) +{ + ViewerContext *v = glfwGetWindowUserPointer(w); + v->vulkan.swap_chain.framebuffer_resize = 1; + v->window_size = (sv2){{width, height}}; +} + function u32 vulkan_shader_kind_to_glslang_shader_kind(u32 kind) { @@ -511,6 +519,19 @@ find_best_graphics_device(VulkanContext *vctx, Arena arena) return result; } +function VkExtent2D +swap_chain_extent_for_window(GLFWwindow *w, VkSurfaceCapabilitiesKHR *si) +{ + VkExtent2D result = si->currentExtent; + if (result.width == U32_MAX) + glfwGetFramebufferSize(w, (s32 *)&result.width, (s32 *)&result.height); + + result.width = CLAMP(result.width, si->minImageExtent.width, si->maxImageExtent.width); + result.height = CLAMP(result.height, si->minImageExtent.height, si->maxImageExtent.height); + + return result; +} + function void swap_chain_from_existing(VulkanSwapChain *sc, VkDevice device, VkRenderPass render_pass, VkExtent2D extent, VkSurfaceTransformFlagBitsKHR transform, u32 requested_images, Arena *arena) @@ -545,7 +566,9 @@ swap_chain_from_existing(VulkanSwapChain *sc, VkDevice device, VkRenderPass rend VkSwapchainKHR swap_chain; /* TODO(rnp): custom allocator? */ vkCreateSwapchainKHR(device, &create_info, 0, &swap_chain); - /* TODO(rnp): does the old one have to be destroyed here? */ + + vkDeviceWaitIdle(device); + vkDestroySwapchainKHR(device, sc->swap_chain, 0); sc->swap_chain = swap_chain; u32 image_count; @@ -615,7 +638,6 @@ init_viewer(ViewerContext *ctx) if (!glfwInit()) os_fatal(str8("failed to start glfw\n")); glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); - glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE); ctx->window = glfwCreateWindow(ctx->window_size.w, ctx->window_size.h, "Camera CNN", 0, 0); if (!ctx->window) os_fatal(str8("failed to open window\n")); @@ -740,20 +762,7 @@ init_viewer(ViewerContext *ctx) vkCreateRenderPass(v->device, &render_pass_info, 0, &rp->render.render_pass); - VkExtent2D extent = surface_info.capabilities.currentExtent; - if (extent.width == U32_MAX) { - s32 width, height; - glfwGetFramebufferSize(ctx->window, &width, &height); - extent.width = (u32)width; - extent.height = (u32)height; - } - - extent.width = CLAMP(extent.width, - surface_info.capabilities.minImageExtent.width, - surface_info.capabilities.maxImageExtent.width); - extent.height = CLAMP(extent.height, - surface_info.capabilities.minImageExtent.height, - surface_info.capabilities.maxImageExtent.height); + VkExtent2D extent = swap_chain_extent_for_window(ctx->window, &surface_info.capabilities); sc->queue_index = 0; sc->exclusive_queue = 1; @@ -839,10 +848,10 @@ init_viewer(ViewerContext *ctx) glfwSetWindowUserPointer(ctx->window, ctx); glfwSetKeyCallback(ctx->window, key_callback); + glfwSetFramebufferSizeCallback(ctx->window, fb_callback); #if 0 glfwSetScrollCallback(ctx->window, scroll_callback); - glfwSetFramebufferSizeCallback(ctx->window, fb_callback); #endif } @@ -897,7 +906,7 @@ begin_frame(VulkanContext *v) } function void -end_frame(VulkanContext *v) +end_frame(VulkanContext *v, GLFWwindow *window, Arena arena) { VulkanSwapChain *sc = &v->swap_chain; VulkanPipeline *rp = &v->render_pipeline; @@ -927,7 +936,17 @@ end_frame(VulkanContext *v) vkCmdEndRenderPass(rp->render.command_buffers[index]); vkEndCommandBuffer(rp->render.command_buffers[index]); vkQueueSubmit(v->queue, 1, &submit_info, rp->render.command_buffer_fences[index]); - vkQueuePresentKHR(v->queue, &present_info); + VkResult pres = vkQueuePresentKHR(v->queue, &present_info); + if (pres == VK_ERROR_OUT_OF_DATE_KHR || pres == VK_SUBOPTIMAL_KHR || sc->framebuffer_resize) { + sc->framebuffer_resize = 0; + struct VulkanSurfaceInfo surface_info; + fill_vulkan_surface_info(v->physical_device, sc->surface, &surface_info, &arena); + /* TODO(rnp): handle surface format change */ + + VkExtent2D extent = swap_chain_extent_for_window(window, &surface_info.capabilities); + swap_chain_from_existing(&v->swap_chain, v->device, rp->render.render_pass, extent, + surface_info.capabilities.currentTransform, sc->image_count, &arena); + } sc->current_frame_index = (sc->current_frame_index + 1) % MAX_RENDER_FRAMES_IN_FLIGHT; } @@ -941,5 +960,5 @@ viewer_frame_step(ViewerContext *ctx, f32 dt) VulkanPipeline *rp = &ctx->vulkan.render_pipeline; begin_frame(&ctx->vulkan); vkCmdDraw(rp->render.command_buffers[ctx->vulkan.swap_chain.current_frame_index], 3, 1, 0, 0); - end_frame(&ctx->vulkan); + end_frame(&ctx->vulkan, ctx->window, ctx->arena); } diff --git a/util.h b/util.h @@ -254,6 +254,7 @@ typedef struct { u32 image_count; u32 framebuffer_index; u32 current_frame_index; + b32 framebuffer_resize; } VulkanSwapChain; typedef enum { diff --git a/vulkan.h b/vulkan.h @@ -18,7 +18,6 @@ typedef uint32_t VkBool32; typedef uint32_t VkFlags; -typedef uint32_t VkResult; typedef uint32_t VkSampleMask; typedef uint64_t VkDeviceSize; typedef void * VkCommandBuffer; @@ -42,6 +41,13 @@ typedef void * VkSurfaceKHR; typedef void * VkSwapchainKHR; typedef enum { + VK_SUCCESS = 0, + VK_SUBOPTIMAL_KHR = 1000001003, + VK_ERROR_OUT_OF_DATE_KHR = -1000001004, + VK_RESULT_MAX_ENUM = 0x7FFFFFFF +} VkResult; + +typedef enum { VK_STRUCTURE_TYPE_APPLICATION_INFO = 0, VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1, VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2, @@ -1969,11 +1975,17 @@ VkResult vkQueueSubmit(VkQueue queue, const VkSubmitInfo *pSubmits, VkFence fence); +VkResult vkDeviceWaitIdle(VkDevice device); + VkResult vkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkSwapchainKHR *pSwapchain); +void vkDestroySwapchainKHR(VkDevice device, + VkSwapchainKHR swapchain, + const VkAllocationCallbacks *pAllocator); + VkResult vkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint32_t *pSwapchainImageCount,