# Plan: RHI Global Context ## Goal Replace per-call `WpAllocator *allocator` parameters with a global `PrRhiContext` managed by the RHI. The RHI owns the lifetime of all objects it creates. ## Changes ### 1. `src/prism/rhi/pr_rhi_types.h` — Add context struct Add after the existing typedefs: ```c typedef struct PrRhiContext { WpAllocator main; // objects returned to the user WpAllocator scratch; // internal temporaries within functions } PrRhiContext; ``` ### 2. `src/prism/rhi/pr_rhi.h` — Public API changes - Add `wp_extern PrRhiContext _G_RHI_CONTEXT;` declaration (near top, after includes) - Add `wp_extern b8 prRhiInit(void);` and `wp_extern void prRhiDestroy(void);` - Remove `WpAllocator *allocator` (and `const WpAllocator *allocator`) from **all** function signatures ### 3. `src/prism/rhi/pr_rhi.c` — New file (shared across backends) ```c #include "pr_rhi.h" PrRhiContext _G_RHI_CONTEXT; b8 prRhiInit(void) { _G_RHI_CONTEXT.main = wpMemArenaAllocatorInit(MiB(64)); _G_RHI_CONTEXT.scratch = wpMemArenaAllocatorInit(MiB(32)); return true; } void prRhiDestroy(void) { wpMemAllocatorFree(&_G_RHI_CONTEXT.scratch, ...); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, ...); } ``` ### 4. `src/prism/rhi/vulkan/pr_rhi_vk.h` — Remove allocator from Vk declarations Remove `WpAllocator *allocator` from all function declarations. ### 5. `src/prism/rhi/vulkan/pr_rhi_vk.c` — Implementation changes For every function that previously took `WpAllocator *allocator`: - Remove the parameter from the signature - Replace `allocator` with `_G_RHI_CONTEXT.main` for: - `wpMemAllocatorAlloc(allocator, sizeof(...))` for user-facing objects (returned to caller) - `wpArrayAllocCapacity(...)` for arrays that are stored in user-facing structs - Replace `allocator` with `_G_RHI_CONTEXT.scratch` for: - `wpArrayAllocCapacity(...)` for internal temporary arrays - `wpArrayDealloc(...)` for internal temporaries - Replace `wpMemAllocatorFree(allocator, ...)` with `wpMemAllocatorFree(&_G_RHI_CONTEXT.main, ...)` for destroy functions - Update internal calls (e.g. `prRhiCreateBufferVk` called from `prRhiCreateTextureFromKtxVk`) **Specific internal/helper changes:** - `_createSwapchainTexture` — remove `allocator` param, use `_G_RHI_CONTEXT.main` - `prRhiCreateTextureFromKtxVk` — staging buffer uses `_G_RHI_CONTEXT.main` (it's a user-facing object destroyed by the user) - `prRhiAllocateCommandBuffersVk` — VkCommandBuffer temp array uses scratch, PrRhiCommandBuffer array + structs use main - `prRhiCreatePipelineLayoutVk` — VkDescriptorSetLayout/VkPushConstantRange overflow arrays use scratch - `prRhiCreateDeviceVk` — VkQueueFamilyProperties2 array uses scratch ### 6. `src/prism/rhi/vulkan/pr_rhi_vk_aliases.h` — No changes needed Aliases only map function names, not parameters. ## Allocator usage per function | Function | Returned object | Allocator | |----------|----------------|-----------| | `prRhiCreateInstance` | PrRhiInstance | main | | `prRhiDestroyInstance` | — | free from main | | `prRhiGetPhysicalDevices` | PrRhiPhysicalDeviceArray + PrRhiPhysicalDevice structs | main | | `prRhiCreateSurfaceFromWindow` | PrRhiSurface | main | | `prRhiDestroySurface` | — | free from main | | `prRhiCreateDevice` | PrRhiDevice | main (internal VkQueueFamilyProperties2 array → scratch) | | `prRhiDestroyDevice` | — | free from main | | `prRhiCreateSwapchain` | PrRhiSwapchain + images + depth | main (internal VkImage array → scratch) | | `prRhiDestroySwapchain` | — | free from main | | `prRhiRecreateSwapchain` | updates existing struct | main for new images/depth, scratch for temp arrays | | `prRhiCreateBuffer` | PrRhiBuffer | main | | `prRhiDestroyBuffer` | — | free from main | | `prRhiCreateTexture` | PrRhiTexture | main | | `prRhiCreateTextureFromKtx` | PrRhiTexture (staging buffer too) | main | | `prRhiDestroyTexture` | — | free from main | | `prRhiCreateSampler` | PrRhiSampler | main | | `prRhiDestroySampler` | — | free from main | | `prRhiCreateShader` | PrRhiShader | main | | `prRhiDestroyShader` | — | free from main | | `prRhiCreatePipelineLayout` | PrRhiPipelineLayout | main (internal overflow arrays → scratch) | | `prRhiDestroyPipelineLayout` | — | free from main | | `prRhiCreateGraphicsPipeline` | PrRhiPipeline | main | | `prRhiCreateComputePipeline` | PrRhiPipeline | main | | `prRhiDestroyPipeline` | — | free from main | | `prRhiCreateDescriptorSetLayout` | PrRhiDescriptorSetLayout | main | | `prRhiDestroyDescriptorSetLayout` | — | free from main | | `prRhiCreateDescriptorPool` | PrRhiDescriptorPool | main | | `prRhiDestroyDescriptorPool` | — | free from main | | `prRhiAllocateDescriptorSet` | PrRhiDescriptorSet | main | | `prRhiFreeDescriptorSet` | — | free from main | | `prRhiCreateFence` | PrRhiFence | main | | `prRhiDestroyFence` | — | free from main | | `prRhiCreateSemaphore` | PrRhiSemaphore | main | | `prRhiDestroySemaphore` | — | free from main | | `prRhiCreateCommandPool` | PrRhiCommandPool | main | | `prRhiDestroyCommandPool` | — | free from main | | `prRhiAllocateCommandBuffers` | PrRhiCommandBufferArray + structs | main (internal VkCommandBuffer array → scratch) |