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: 9011f7a3136ffa3d72c60471c500c459a7f2a65f
Parent: 7455a1e17c31ec3561c15ec2a86f8c861d0bd84b
Author: Randy Palamar
Date:   Thu, 21 Aug 2025 15:49:53 -0600

core: don't crash on invalid shader reload

unfortunately vulkan doesn't have a 0 pipeline so some other way
of indicating that a shader is broken is needed

Diffstat:
Mcommon.c | 84++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 49 insertions(+), 35 deletions(-)

diff --git a/common.c b/common.c @@ -262,16 +262,30 @@ vulkan_pipeline_from_shader_text(VulkanPipeline *vp, VkDevice device, OS *os, Ar .subpass = 0, }; - vkDestroyPipeline(device, vp->pipeline, 0); - if (valid) { - vkCreateGraphicsPipelines(device, 0, 1, &pipeline_info, 0, &vp->pipeline); + /* TODO(rnp): have a set of default shaders for when compilation fails. + * Vulkan has no concept of a 0 shader which does nothing. Visual indication + * of brokeness is desirable for debugging */ + + /* NOTE(rnp): this could be fancier to avoid it but for now we are okay + * with a stall when shaders are reloading */ + switch (vp->kind) { + case VulkanPipelineKind_Render:{ + vkWaitForFences(device, countof(vp->render.command_buffer_fences), + vp->render.command_buffer_fences, 1, U64_MAX); + }break; + case VulkanPipelineKind_Compute:{ + vkWaitForFences(device, countof(vp->compute.command_buffer_fences), + vp->compute.command_buffer_fences, 1, U64_MAX); + }break; + InvalidDefaultCase; + } + vkDestroyPipeline(device, vp->pipeline, 0); + vkCreateGraphicsPipelines(device, 0, 1, &pipeline_info, 0, &vp->pipeline); Stream sb = arena_stream(arena); stream_append_str8s(&sb, str8("loaded: "), name, str8("\n")); os_write_file(os->error_handle, stream_to_str8(&sb)); - } else { - vp->pipeline = 0; } for (s32 i = 0; i < count; i++) @@ -756,6 +770,36 @@ init_viewer(ViewerContext *ctx) surface_info.capabilities.currentTransform, image_count, &ctx->arena); } + VkCommandPoolCreateInfo command_pool_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, + .queueFamilyIndex = queue_family_index, + }; + + vkCreateCommandPool(v->device, &command_pool_info, 0, &v->command_pool); + + VkCommandBufferAllocateInfo command_buffer_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .commandPool = v->command_pool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = countof(rp->render.command_buffers), + }; + vkAllocateCommandBuffers(v->device, &command_buffer_info, rp->render.command_buffers); + + VkSemaphoreCreateInfo semaphore_info = {.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO}; + VkFenceCreateInfo fence_info = { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .flags = VK_FENCE_CREATE_SIGNALED_BIT, + }; + + for (u32 i = 0; i < sc->image_count; i++) + vkCreateSemaphore(v->device, &semaphore_info, 0, sc->render_complete_semaphores + i); + + for EachElement(rp->render.command_buffer_fences, it) { + vkCreateSemaphore(v->device, &semaphore_info, 0, sc->image_available_semaphores + it); + vkCreateFence(v->device, &fence_info, 0, rp->render.command_buffer_fences + it); + } + ShaderReloadContext *render = push_struct(&ctx->arena, typeof(*render)); render->pipeline = rp; render->device = v->device; @@ -793,36 +837,6 @@ init_viewer(ViewerContext *ctx) reload_shader(&ctx->os, render->path, (sptr)render, ctx->arena); os_add_file_watch(&ctx->os, &ctx->arena, render->path, reload_shader, (sptr)render); - VkCommandPoolCreateInfo command_pool_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, - .queueFamilyIndex = queue_family_index, - }; - - vkCreateCommandPool(v->device, &command_pool_info, 0, &v->command_pool); - - VkCommandBufferAllocateInfo command_buffer_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .commandPool = v->command_pool, - .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - .commandBufferCount = countof(rp->render.command_buffers), - }; - vkAllocateCommandBuffers(v->device, &command_buffer_info, rp->render.command_buffers); - - VkSemaphoreCreateInfo semaphore_info = {.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO}; - VkFenceCreateInfo fence_info = { - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .flags = VK_FENCE_CREATE_SIGNALED_BIT, - }; - - for (u32 i = 0; i < sc->image_count; i++) - vkCreateSemaphore(v->device, &semaphore_info, 0, sc->render_complete_semaphores + i); - - for EachElement(rp->render.command_buffer_fences, it) { - vkCreateSemaphore(v->device, &semaphore_info, 0, sc->image_available_semaphores + it); - vkCreateFence(v->device, &fence_info, 0, rp->render.command_buffer_fences + it); - } - glfwSetWindowUserPointer(ctx->window, ctx); glfwSetKeyCallback(ctx->window, key_callback);