# Session Log — 2026-07-06 ## Completed - **Build system**: Fixed Just 1.55.1 `[working-directory]` bug (literal paths required). Set up `just build` for 6 object files: volk.c, wapp.c, pr_rhi_vk.c, pr_rhi_vk_vma.cpp, vulkan_profiles.cpp, main.cpp. Linked with `-lSDL3 -lglm -ltinyobjloader -lktx -lslang -lvulkan`. - **RHI backend completeness**: Filled in all missing functions (profiles validation, swapchain/recreate, dynamic rendering, copy, queue submit, barriers, descriptor, pipeline, sync) — 68 functions total in single `pr_rhi_vk.c`. - **Bugfix — `prRhiPresentVk`**: Used `current_image_index` from acquire instead of hardcoded `0`. - **Bugfix — `extern "C"` linkage**: Added `extern "C"` guards in `pr_rhi.h` so C++ callers (main.cpp) can link C-compiled backend symbols. - **Bugfix — GPU name dangling pointers**: Added `device_name[256]`/`driver_info[256]` to `PrRhiPhysicalDevice` struct, populated during enumeration. Getters return pointers to these persistent buffers. - **Bugfix — `volkInitialize()`**: Added call at start of `prRhiCreateInstanceVk` — `vpGetInstanceProfileSupport` crashed because volk hadn't loaded the Vulkan loader. - **Bugfix — scratch arena OOM**: Changed initial 128KB → 64MB _and_ the line-320 reinit override 8MB → 64MB. Prevents OOM during mesh building. - **Bugfix — stale mesh array pointers**: Captured return values of `wpArrayAppendAlloc` in mesh-building loop — original code ignored the pointer, so `vertices`/`indices` pointed to stale initial array after regrowth. - **Bugfix — uninitialised Vulkan stack arrays**: Zero-initialised all 18 local Vulkan struct array declarations (`VkImageMemoryBarrier2[16]`, `VkBufferMemoryBarrier2[16]`, `VkRenderingAttachmentInfo[8]`, `VkBufferImageCopy[16]`, plus `VkDescriptorSetLayout[8]`, `VkPushConstantRange[8]`, `VkVertexInputBindingDescription[8]`, `VkVertexInputAttributeDescription[16]`, `VkDynamicState[2]`, `VkFormat[8]`, `VkPipelineColorBlendAttachmentState[8]`, `VkDescriptorSetLayoutBinding[16]`, `VkDescriptorBindingFlags[16]`, `VkDescriptorPoolSize[8]`, `VkDescriptorImageInfo[16]`, `VkDescriptorBufferInfo[16]`, `VkFence[16]` (×2), `VkCommandBuffer[16]` (×2), `VkDescriptorSet[16]`, `VkBuffer[16]`). Uninitialised `pNext`/`imageOffset` fields caused GPU-side device-lost crashes. - **Bugfix — `render_completed_semaphores` zero-length array**: `prRhiAcquireNextImage` returns swapchain image INDEX (0 on first call), not image count. Used as array capacity, this allocated 0 semaphores, causing out-of-bounds access in render loop → SIGSEGV. Fixed by reading `app.swapchain->image_count` instead. - **Demo renders**: `build/prism` now launches a window, loads `suzanne0.ktx` / `suzanne1.ktx`, renders textured Suzanne mesh with mouse orbit + keyboard mesh selection. ## Key Decisions - Just 1.55.1 bug: `[working-directory: '{{BUILDDIR}}']` causes "could not find the shell `sh`" — literal paths or no `[working-directory]` attribute required. - VMA implementation in separate `pr_rhi_vk_vma.cpp` (compiled as C++). - `PrRhiPhysicalDevice` stores `device_name[256]`/`driver_info[256]` to avoid dangling pointers. - All stack Vulkan struct arrays must be `= {0}` initialised — C backend does not zero auto vars, and uninitialised `pNext`/offset fields cause GPU driver crashes. ## Next Steps 1. Review code for structural/design quality issues the user already noticed. 2. Add `wpMemArenaAllocatorTempBegin`/`TempEnd` markers around scratch allocations. 3. Consider adding `prRhiGetSwapchainImageCount` accessor for encapsulation.