Add RHI global context allocator

This commit is contained in:
2026-07-11 11:34:30 +01:00
parent 943f00345c
commit bffe9b8174
8 changed files with 376 additions and 295 deletions
+115
View File
@@ -0,0 +1,115 @@
# 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) |
+3 -2
View File
@@ -12,7 +12,7 @@ VK_SDK := `echo $VULKAN_SDK`
VENDOR_INC := "vendor/include" VENDOR_INC := "vendor/include"
VENDOR_LIB := "vendor/lib" VENDOR_LIB := "vendor/lib"
VK_FLAGS := "-DVK_NO_PROTOTYPES -I" + VK_SDK + "/include -I" + VK_SDK + "/include/vma -I" + VENDOR_INC VK_FLAGS := "-DPR_RHI_VULKAN -DVK_NO_PROTOTYPES -I" + VK_SDK + "/include -I" + VK_SDK + "/include/vma -I" + VENDOR_INC
APP_INC := "-I" + VK_SDK + "/include -I" + VK_SDK + "/include/vma -I" + VK_SDK + "/include/slang -I" + VENDOR_INC + " -Isrc" APP_INC := "-I" + VK_SDK + "/include -I" + VK_SDK + "/include/vma -I" + VK_SDK + "/include/slang -I" + VENDOR_INC + " -Isrc"
# Build KTX from source # Build KTX from source
@@ -40,13 +40,14 @@ build: vendor
src/prism/rhi/vulkan/pr_rhi_vk_vma.cpp \ src/prism/rhi/vulkan/pr_rhi_vk_vma.cpp \
-o {{BUILDDIR}}/pr_rhi_vk_vma.o -o {{BUILDDIR}}/pr_rhi_vk_vma.o
bear -a -- {{CC}} -g -c {{VK_FLAGS}} {{VK_SDK}}/include/volk/volk.c -o {{BUILDDIR}}/volk.o bear -a -- {{CC}} -g -c {{VK_FLAGS}} {{VK_SDK}}/include/volk/volk.c -o {{BUILDDIR}}/volk.o
bear -a -- {{CC}} -g -c {{VK_FLAGS}} src/prism/rhi/pr_rhi.c -o {{BUILDDIR}}/pr_rhi.o
bear -a -- {{CC}} -g -c {{VK_FLAGS}} src/prism/rhi/vulkan/pr_rhi_vk.c -o {{BUILDDIR}}/pr_rhi_vk.o bear -a -- {{CC}} -g -c {{VK_FLAGS}} src/prism/rhi/vulkan/pr_rhi_vk.c -o {{BUILDDIR}}/pr_rhi_vk.o
bear -a -- {{CC}} -g -c src/wapp/wapp.c -o {{BUILDDIR}}/wapp.o bear -a -- {{CC}} -g -c src/wapp/wapp.c -o {{BUILDDIR}}/wapp.o
bear -a -- {{CXX}} -g -c -Wno-nullability-completeness -DVK_NO_PROTOTYPES \ bear -a -- {{CXX}} -g -c -Wno-nullability-completeness -DVK_NO_PROTOTYPES \
{{APP_INC}} \ {{APP_INC}} \
src/main.cpp \ src/main.cpp \
-o {{BUILDDIR}}/main.o -o {{BUILDDIR}}/main.o
bear -a -- {{CXX}} -g -DVK_NO_PROTOTYPES \ bear -a -- {{CXX}} -g {{VK_FLAGS}} \
-L{{VK_SDK}}/lib -L{{VENDOR_LIB}} \ -L{{VK_SDK}}/lib -L{{VENDOR_LIB}} \
build/*.o \ build/*.o \
-lSDL3 -lglm -ltinyobjloader -lktx -lslang -lvulkan \ -lSDL3 -lglm -ltinyobjloader -lktx -lslang -lvulkan \
+42 -40
View File
@@ -136,6 +136,7 @@ struct AppState {
int main() { int main() {
AppState app = {}; AppState app = {};
WpAllocator arena = wpMemArenaAllocatorInitZero(MiB(128)); WpAllocator arena = wpMemArenaAllocatorInitZero(MiB(128));
prRhiInit();
// {{{ Initialisation // {{{ Initialisation
check(SDL_Init(SDL_INIT_VIDEO), EXIT_CODE_SDL_INIT_FAILED); check(SDL_Init(SDL_INIT_VIDEO), EXIT_CODE_SDL_INIT_FAILED);
@@ -149,11 +150,11 @@ int main() {
// {{{ Instance creation // {{{ Instance creation
PrRhiInstanceDesc inst_desc = {}; PrRhiInstanceDesc inst_desc = {};
app.inst = prRhiCreateInstance(inst_desc, &arena); app.inst = prRhiCreateInstance(inst_desc);
// }}} // }}}
// {{{ Physical device selection // {{{ Physical device selection
PrRhiPhysicalDeviceArray pdevs = prRhiGetPhysicalDevices(app.inst, &arena); PrRhiPhysicalDeviceArray pdevs = prRhiGetPhysicalDevices(app.inst);
check(wpArrayCount(pdevs) > 0, EXIT_CODE_NO_PHYSICAL_DEVICES); check(wpArrayCount(pdevs) > 0, EXIT_CODE_NO_PHYSICAL_DEVICES);
i32 selected = -1; i32 selected = -1;
@@ -185,13 +186,13 @@ int main() {
// {{{ Surface creation // {{{ Surface creation
check(SDL_GetWindowSize(app.window, &app.window_size.x, &app.window_size.y), check(SDL_GetWindowSize(app.window, &app.window_size.x, &app.window_size.y),
EXIT_CODE_GET_WINDOW_SIZE_FAILED); EXIT_CODE_GET_WINDOW_SIZE_FAILED);
app.surface = prRhiCreateSurfaceFromWindow(app.inst, (void *)app.window, &arena); app.surface = prRhiCreateSurfaceFromWindow(app.inst, (void *)app.window);
// }}} // }}}
// {{{ Device creation // {{{ Device creation
PrRhiDeviceDesc dev_desc = {}; PrRhiDeviceDesc dev_desc = {};
dev_desc.present_mode = PR_RHI_PRESENT_MODE_FIFO; dev_desc.present_mode = PR_RHI_PRESENT_MODE_FIFO;
app.device = prRhiCreateDevice(app.pdev, app.surface, dev_desc, &arena); app.device = prRhiCreateDevice(app.pdev, app.surface, dev_desc);
u32 qfi = prRhiGetQueueFamilyIndex(app.device); u32 qfi = prRhiGetQueueFamilyIndex(app.device);
// }}} // }}}
@@ -202,7 +203,7 @@ int main() {
swap_desc.height = (u32)app.window_size.y; swap_desc.height = (u32)app.window_size.y;
swap_desc.has_depth = true; swap_desc.has_depth = true;
swap_desc.depth_format = PR_RHI_FORMAT_D24_UNORM_S8_UINT; swap_desc.depth_format = PR_RHI_FORMAT_D24_UNORM_S8_UINT;
app.swapchain = prRhiCreateSwapchain(app.device, swap_desc, &arena); app.swapchain = prRhiCreateSwapchain(app.device, swap_desc);
PrRhiFormat swapchain_format = prRhiGetSwapchainFormat(app.swapchain); PrRhiFormat swapchain_format = prRhiGetSwapchainFormat(app.swapchain);
// }}} // }}}
@@ -251,7 +252,7 @@ int main() {
vert_desc.size = app.vertex_buf_size + index_buf_size; vert_desc.size = app.vertex_buf_size + index_buf_size;
vert_desc.usage = (PrRhiBufferUsage)(PR_RHI_BUFFER_USAGE_VERTEX | PR_RHI_BUFFER_USAGE_INDEX); vert_desc.usage = (PrRhiBufferUsage)(PR_RHI_BUFFER_USAGE_VERTEX | PR_RHI_BUFFER_USAGE_INDEX);
vert_desc.memory = PR_RHI_MEMORY_CPU_TO_GPU; vert_desc.memory = PR_RHI_MEMORY_CPU_TO_GPU;
app.vert_index_buf = prRhiCreateBuffer(app.device, vert_desc, &arena); app.vert_index_buf = prRhiCreateBuffer(app.device, vert_desc);
void *mapped = prRhiBufferMap(app.device, app.vert_index_buf); void *mapped = prRhiBufferMap(app.device, app.vert_index_buf);
memcpy(mapped, vertices, app.vertex_buf_size); memcpy(mapped, vertices, app.vertex_buf_size);
@@ -270,7 +271,7 @@ int main() {
buf_desc.usage = (PrRhiBufferUsage)(PR_RHI_BUFFER_USAGE_STORAGE | buf_desc.usage = (PrRhiBufferUsage)(PR_RHI_BUFFER_USAGE_STORAGE |
PR_RHI_BUFFER_USAGE_SHADER_DEVICE_ADDRESS); PR_RHI_BUFFER_USAGE_SHADER_DEVICE_ADDRESS);
buf_desc.memory = PR_RHI_MEMORY_CPU_TO_GPU; buf_desc.memory = PR_RHI_MEMORY_CPU_TO_GPU;
app.shader_data_bufs[i] = prRhiCreateBuffer(app.device, buf_desc, &arena); app.shader_data_bufs[i] = prRhiCreateBuffer(app.device, buf_desc);
} }
// }}} // }}}
@@ -281,7 +282,7 @@ int main() {
for (u32 i = 0; i < AppState::max_frames_in_flight; ++i) { for (u32 i = 0; i < AppState::max_frames_in_flight; ++i) {
PrRhiFenceDesc fd = {}; PrRhiFenceDesc fd = {};
fd.signaled = true; fd.signaled = true;
app.fences[i] = prRhiCreateFence(app.device, fd, &arena); app.fences[i] = prRhiCreateFence(app.device, fd);
} }
// Image acquired semaphores (per frame) // Image acquired semaphores (per frame)
@@ -289,7 +290,7 @@ int main() {
AppState::max_frames_in_flight, AppState::max_frames_in_flight,
WP_ARRAY_INIT_FILLED); WP_ARRAY_INIT_FILLED);
for (u32 i = 0; i < AppState::max_frames_in_flight; ++i) { for (u32 i = 0; i < AppState::max_frames_in_flight; ++i) {
app.image_acquired_semaphores[i] = prRhiCreateSemaphore(app.device, &arena); app.image_acquired_semaphores[i] = prRhiCreateSemaphore(app.device);
} }
// Render completed semaphores (per swapchain image) // Render completed semaphores (per swapchain image)
@@ -298,30 +299,30 @@ int main() {
swapchain_image_count, swapchain_image_count,
WP_ARRAY_INIT_FILLED); WP_ARRAY_INIT_FILLED);
for (u32 i = 0; i < swapchain_image_count; ++i) { for (u32 i = 0; i < swapchain_image_count; ++i) {
app.render_completed_semaphores[i] = prRhiCreateSemaphore(app.device, &arena); app.render_completed_semaphores[i] = prRhiCreateSemaphore(app.device);
} }
// }}} // }}}
// {{{ Command pool and buffers // {{{ Command pool and buffers
PrRhiCommandPoolDesc pool_desc = {}; PrRhiCommandPoolDesc pool_desc = {};
pool_desc.queue_family_index = qfi; pool_desc.queue_family_index = qfi;
app.cmd_pool = prRhiCreateCommandPool(app.device, pool_desc, &arena); app.cmd_pool = prRhiCreateCommandPool(app.device, pool_desc);
app.cmd_buffers = prRhiAllocateCommandBuffers(app.device, app.cmd_pool, app.cmd_buffers = prRhiAllocateCommandBuffers(app.device, app.cmd_pool,
AppState::max_frames_in_flight, &arena); AppState::max_frames_in_flight);
// }}} // }}}
// {{{ Texture loading // {{{ Texture loading
app.textures = wpArrayAllocCapacity(TextureResources, &arena, AppState::texture_count, app.textures = wpArrayAllocCapacity(TextureResources, &arena, AppState::texture_count,
WP_ARRAY_INIT_FILLED); WP_ARRAY_INIT_FILLED);
PrRhiCommandBufferArray upload_cbs = prRhiAllocateCommandBuffers(app.device, app.cmd_pool, 1, &arena); PrRhiCommandBufferArray upload_cbs = prRhiAllocateCommandBuffers(app.device, app.cmd_pool, 1);
PrRhiCommandBuffer *upload_cb = upload_cbs[0]; PrRhiCommandBuffer *upload_cb = upload_cbs[0];
for (u32 i = 0; i < AppState::texture_count; ++i) { for (u32 i = 0; i < AppState::texture_count; ++i) {
char buf[2048] = {}; char buf[2048] = {};
snprintf(buf, sizeof(buf), "assets/suzanne%u.ktx", i); snprintf(buf, sizeof(buf), "assets/suzanne%u.ktx", i);
PrRhiTexture *tex = prRhiCreateTextureFromKtx(app.device, buf, app.cmd_pool, upload_cb, &arena); PrRhiTexture *tex = prRhiCreateTextureFromKtx(app.device, buf, app.cmd_pool, upload_cb);
// Create sampler // Create sampler
PrRhiSamplerDesc samp_desc = {}; PrRhiSamplerDesc samp_desc = {};
@@ -330,7 +331,7 @@ int main() {
samp_desc.mipmap_mode = PR_RHI_MIPMAP_MODE_LINEAR; samp_desc.mipmap_mode = PR_RHI_MIPMAP_MODE_LINEAR;
samp_desc.max_anisotropy = 8.0f; samp_desc.max_anisotropy = 8.0f;
samp_desc.max_lod = PR_RHI_LOD_CLAMP_NONE; samp_desc.max_lod = PR_RHI_LOD_CLAMP_NONE;
PrRhiSampler *sampler = prRhiCreateSampler(app.device, samp_desc, &arena); PrRhiSampler *sampler = prRhiCreateSampler(app.device, samp_desc);
app.textures[i].texture = tex; app.textures[i].texture = tex;
app.textures[i].sampler = sampler; app.textures[i].sampler = sampler;
@@ -351,7 +352,7 @@ int main() {
PrRhiDescriptorSetLayoutDesc layout_desc = {}; PrRhiDescriptorSetLayoutDesc layout_desc = {};
layout_desc.bindings = ds_layouts; layout_desc.bindings = ds_layouts;
app.desc_set_layout = prRhiCreateDescriptorSetLayout(app.device, layout_desc, &arena); app.desc_set_layout = prRhiCreateDescriptorSetLayout(app.device, layout_desc);
// Pool // Pool
PrRhiDescriptorPoolSize pool_size = {}; PrRhiDescriptorPoolSize pool_size = {};
@@ -361,12 +362,12 @@ int main() {
PrRhiDescriptorPoolDesc pool_desc2 = {}; PrRhiDescriptorPoolDesc pool_desc2 = {};
pool_desc2.max_sets = 1; pool_desc2.max_sets = 1;
pool_desc2.pool_sizes = wpArray(PrRhiDescriptorPoolSize, pool_size); pool_desc2.pool_sizes = wpArray(PrRhiDescriptorPoolSize, pool_size);
app.desc_pool = prRhiCreateDescriptorPool(app.device, pool_desc2, &arena); app.desc_pool = prRhiCreateDescriptorPool(app.device, pool_desc2);
// Allocate descriptor set (variable count) // Allocate descriptor set (variable count)
app.desc_set = prRhiAllocateDescriptorSet(app.device, app.desc_pool, app.desc_set = prRhiAllocateDescriptorSet(app.device, app.desc_pool,
app.desc_set_layout, app.desc_set_layout,
AppState::texture_count, &arena); AppState::texture_count);
// Write descriptor set // Write descriptor set
PrRhiDescriptorImageInfoArray img_infos = wpArrayAllocCapacity(PrRhiDescriptorImageInfo, PrRhiDescriptorImageInfoArray img_infos = wpArrayAllocCapacity(PrRhiDescriptorImageInfo,
@@ -416,7 +417,7 @@ int main() {
PrRhiShaderDesc shader_desc = {}; PrRhiShaderDesc shader_desc = {};
shader_desc.spirv_code = spirv->getBufferPointer(); shader_desc.spirv_code = spirv->getBufferPointer();
shader_desc.spirv_size = spirv->getBufferSize(); shader_desc.spirv_size = spirv->getBufferSize();
app.shader = prRhiCreateShader(app.device, shader_desc, &arena); app.shader = prRhiCreateShader(app.device, shader_desc);
// }}} // }}}
// {{{ Pipeline layout // {{{ Pipeline layout
@@ -430,7 +431,7 @@ int main() {
PrRhiPipelineLayoutDesc pl_desc = {}; PrRhiPipelineLayoutDesc pl_desc = {};
pl_desc.set_layouts = pl_layouts; pl_desc.set_layouts = pl_layouts;
pl_desc.push_constant_ranges = wpArray(PrRhiPushConstantRange, pc_range); pl_desc.push_constant_ranges = wpArray(PrRhiPushConstantRange, pc_range);
app.pipeline_layout = prRhiCreatePipelineLayout(app.device, pl_desc, &arena); app.pipeline_layout = prRhiCreatePipelineLayout(app.device, pl_desc);
// }}} // }}}
// {{{ Graphics pipeline // {{{ Graphics pipeline
@@ -474,7 +475,7 @@ int main() {
pipe_desc.dynamic_viewport = true; pipe_desc.dynamic_viewport = true;
pipe_desc.dynamic_scissor = true; pipe_desc.dynamic_scissor = true;
pipe_desc.layout = app.pipeline_layout; pipe_desc.layout = app.pipeline_layout;
app.pipeline = prRhiCreateGraphicsPipeline(app.device, pipe_desc, &arena); app.pipeline = prRhiCreateGraphicsPipeline(app.device, pipe_desc);
// }}} // }}}
// {{{ Render loop // {{{ Render loop
@@ -673,7 +674,7 @@ int main() {
if (app.update_swapchain) { if (app.update_swapchain) {
prRhiDeviceWaitIdle(app.device); prRhiDeviceWaitIdle(app.device);
prRhiRecreateSwapchain(app.device, &app.swapchain, prRhiRecreateSwapchain(app.device, &app.swapchain,
(u32)app.window_size.x, (u32)app.window_size.y, &arena); (u32)app.window_size.x, (u32)app.window_size.y);
// Re-create render completed semaphores for new image count // Re-create render completed semaphores for new image count
// TODO: proper cleanup — for now, just leak old ones // TODO: proper cleanup — for now, just leak old ones
@@ -682,7 +683,7 @@ int main() {
app.render_completed_semaphores = wpArrayAllocCapacity(PrRhiSemaphore *, &arena, app.render_completed_semaphores = wpArrayAllocCapacity(PrRhiSemaphore *, &arena,
new_count, WP_ARRAY_INIT_FILLED); new_count, WP_ARRAY_INIT_FILLED);
for (u32 i = 0; i < new_count; ++i) { for (u32 i = 0; i < new_count; ++i) {
app.render_completed_semaphores[i] = prRhiCreateSemaphore(app.device, &arena); app.render_completed_semaphores[i] = prRhiCreateSemaphore(app.device);
} }
app.update_swapchain = false; app.update_swapchain = false;
@@ -697,39 +698,40 @@ int main() {
// {{{ Cleanup // {{{ Cleanup
prRhiDeviceWaitIdle(app.device); prRhiDeviceWaitIdle(app.device);
prRhiDestroyPipeline(app.device, app.pipeline, &arena); prRhiDestroyPipeline(app.device, app.pipeline);
prRhiDestroyPipelineLayout(app.device, app.pipeline_layout, &arena); prRhiDestroyPipelineLayout(app.device, app.pipeline_layout);
prRhiDestroyShader(app.device, app.shader, &arena); prRhiDestroyShader(app.device, app.shader);
prRhiDestroyDescriptorPool(app.device, app.desc_pool, &arena); prRhiDestroyDescriptorPool(app.device, app.desc_pool);
prRhiDestroyDescriptorSetLayout(app.device, app.desc_set_layout, &arena); prRhiDestroyDescriptorSetLayout(app.device, app.desc_set_layout);
for (u32 i = 0; i < AppState::texture_count; ++i) { for (u32 i = 0; i < AppState::texture_count; ++i) {
prRhiDestroySampler(app.device, app.textures[i].sampler, &arena); prRhiDestroySampler(app.device, app.textures[i].sampler);
prRhiDestroyTexture(app.device, app.textures[i].texture, &arena); prRhiDestroyTexture(app.device, app.textures[i].texture);
} }
prRhiFreeCommandBuffers(app.device, app.cmd_pool, AppState::max_frames_in_flight, prRhiFreeCommandBuffers(app.device, app.cmd_pool, AppState::max_frames_in_flight,
app.cmd_buffers); app.cmd_buffers);
prRhiDestroyCommandPool(app.device, app.cmd_pool, &arena); prRhiDestroyCommandPool(app.device, app.cmd_pool);
for (u32 i = 0; i < swapchain_image_count; ++i) { for (u32 i = 0; i < swapchain_image_count; ++i) {
prRhiDestroySemaphore(app.device, app.render_completed_semaphores[i], &arena); prRhiDestroySemaphore(app.device, app.render_completed_semaphores[i]);
} }
for (u32 i = 0; i < AppState::max_frames_in_flight; ++i) { for (u32 i = 0; i < AppState::max_frames_in_flight; ++i) {
prRhiDestroySemaphore(app.device, app.image_acquired_semaphores[i], &arena); prRhiDestroySemaphore(app.device, app.image_acquired_semaphores[i]);
prRhiDestroyFence(app.device, app.fences[i], &arena); prRhiDestroyFence(app.device, app.fences[i]);
prRhiDestroyBuffer(app.device, app.shader_data_bufs[i], &arena); prRhiDestroyBuffer(app.device, app.shader_data_bufs[i]);
} }
prRhiDestroyBuffer(app.device, app.vert_index_buf, &arena); prRhiDestroyBuffer(app.device, app.vert_index_buf);
prRhiDestroySwapchain(app.device, app.swapchain, &arena); prRhiDestroySwapchain(app.device, app.swapchain);
prRhiDestroyDevice(app.device, &arena); prRhiDestroyDevice(app.device);
prRhiDestroySurface(app.inst, app.surface, &arena); prRhiDestroySurface(app.inst, app.surface);
prRhiDestroyInstance(app.inst, &arena); prRhiDestroyInstance(app.inst);
SDL_DestroyWindow(app.window); SDL_DestroyWindow(app.window);
SDL_Quit(); SDL_Quit();
prRhiDestroy();
wpMemArenaAllocatorDestroy(&arena); wpMemArenaAllocatorDestroy(&arena);
// }}} // }}}
+17
View File
@@ -0,0 +1,17 @@
// vim:fileencoding=utf-8:foldmethod=marker
//
// RHI context — shared initialisation and global state.
#include "pr_rhi.h"
PrRhiContext _G_RHI_CONTEXT;
void prRhiInit(void) {
_G_RHI_CONTEXT.main = wpMemArenaAllocatorInit(MiB(64));
_G_RHI_CONTEXT.scratch = wpMemArenaAllocatorInit(MiB(32));
}
void prRhiDestroy(void) {
wpMemArenaAllocatorDestroy(&_G_RHI_CONTEXT.scratch);
wpMemArenaAllocatorDestroy(&_G_RHI_CONTEXT.main);
}
+43 -61
View File
@@ -29,18 +29,23 @@
extern "C" { extern "C" {
#endif #endif
wp_extern PrRhiContext _G_RHI_CONTEXT;
wp_extern void prRhiInit(void);
wp_extern void prRhiDestroy(void);
// ====================================================================== // ======================================================================
// Instance // Instance
// ====================================================================== // ======================================================================
PrRhiInstance *prRhiCreateInstance(PrRhiInstanceDesc desc, WpAllocator *allocator); PrRhiInstance *prRhiCreateInstance(PrRhiInstanceDesc desc);
void prRhiDestroyInstance(PrRhiInstance *inst, WpAllocator *allocator); void prRhiDestroyInstance(PrRhiInstance *inst);
// ====================================================================== // ======================================================================
// Physical device enumeration // Physical device enumeration
// ====================================================================== // ======================================================================
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevices(PrRhiInstance *inst, const WpAllocator *allocator); PrRhiPhysicalDeviceArray prRhiGetPhysicalDevices(PrRhiInstance *inst);
void prRhiGetPhysicalDeviceName(PrRhiPhysicalDevice *pdev, WpStr8 *out); void prRhiGetPhysicalDeviceName(PrRhiPhysicalDevice *pdev, WpStr8 *out);
void prRhiGetPhysicalDeviceDriverInfo(PrRhiPhysicalDevice *pdev, WpStr8 *out); void prRhiGetPhysicalDeviceDriverInfo(PrRhiPhysicalDevice *pdev, WpStr8 *out);
void prRhiGetPhysicalDeviceProperties(PrRhiPhysicalDevice *pdev, void prRhiGetPhysicalDeviceProperties(PrRhiPhysicalDevice *pdev,
@@ -50,9 +55,8 @@ void prRhiGetPhysicalDeviceProperties(PrRhiPhysicalDevice *p
// Surface (platform-specific) // Surface (platform-specific)
// ====================================================================== // ======================================================================
PrRhiSurface *prRhiCreateSurfaceFromWindow(PrRhiInstance *inst, void *window_handle, PrRhiSurface *prRhiCreateSurfaceFromWindow(PrRhiInstance *inst, void *window_handle);
WpAllocator *allocator); void prRhiDestroySurface(PrRhiInstance *inst, PrRhiSurface *surface);
void prRhiDestroySurface(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *allocator);
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev, PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev,
PrRhiSurface *surface); PrRhiSurface *surface);
@@ -61,8 +65,8 @@ PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev,
// ====================================================================== // ======================================================================
PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface, PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
PrRhiDeviceDesc desc, WpAllocator *allocator); PrRhiDeviceDesc desc);
void prRhiDestroyDevice(PrRhiDevice *device, WpAllocator *allocator); void prRhiDestroyDevice(PrRhiDevice *device);
void prRhiDeviceWaitIdle(PrRhiDevice *device); void prRhiDeviceWaitIdle(PrRhiDevice *device);
u32 prRhiGetQueueFamilyIndex(PrRhiDevice *device); u32 prRhiGetQueueFamilyIndex(PrRhiDevice *device);
@@ -70,10 +74,8 @@ u32 prRhiGetQueueFamilyIndex(PrRhiDevice *device);
// Swapchain // Swapchain
// ====================================================================== // ======================================================================
PrRhiSwapchain *prRhiCreateSwapchain(PrRhiDevice *device, PrRhiSwapchainDesc desc, PrRhiSwapchain *prRhiCreateSwapchain(PrRhiDevice *device, PrRhiSwapchainDesc desc);
WpAllocator *allocator); void prRhiDestroySwapchain(PrRhiDevice *device, PrRhiSwapchain *swapchain);
void prRhiDestroySwapchain(PrRhiDevice *device, PrRhiSwapchain *swapchain,
WpAllocator *allocator);
PrRhiSwapchainResult prRhiAcquireNextImage(PrRhiDevice *device, PrRhiSwapchain *swapchain, PrRhiSwapchainResult prRhiAcquireNextImage(PrRhiDevice *device, PrRhiSwapchain *swapchain,
PrRhiSemaphore *signal_semaphore, u32 *out_image_index); PrRhiSemaphore *signal_semaphore, u32 *out_image_index);
@@ -82,7 +84,7 @@ PrRhiSwapchainResult prRhiPresent(PrRhiDevice *device, PrRhiSwapchain *swapchain
PrRhiSemaphore *wait_semaphore); PrRhiSemaphore *wait_semaphore);
void prRhiRecreateSwapchain(PrRhiDevice *device, PrRhiSwapchain **swapchain, void prRhiRecreateSwapchain(PrRhiDevice *device, PrRhiSwapchain **swapchain,
u32 width, u32 height, WpAllocator *allocator); u32 width, u32 height);
PrRhiTexture *prRhiGetSwapchainTexture(PrRhiSwapchain *swapchain, u32 image_index); PrRhiTexture *prRhiGetSwapchainTexture(PrRhiSwapchain *swapchain, u32 image_index);
PrRhiTexture *prRhiGetSwapchainDepthTexture(PrRhiSwapchain *swapchain); PrRhiTexture *prRhiGetSwapchainDepthTexture(PrRhiSwapchain *swapchain);
@@ -92,9 +94,8 @@ PrRhiFormat prRhiGetSwapchainFormat(PrRhiSwapchain *swapchain);
// Buffers // Buffers
// ====================================================================== // ======================================================================
PrRhiBuffer *prRhiCreateBuffer(PrRhiDevice *device, PrRhiBufferDesc desc, PrRhiBuffer *prRhiCreateBuffer(PrRhiDevice *device, PrRhiBufferDesc desc);
WpAllocator *allocator); void prRhiDestroyBuffer(PrRhiDevice *device, PrRhiBuffer *buffer);
void prRhiDestroyBuffer(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *allocator);
void *prRhiBufferMap(PrRhiDevice *device, PrRhiBuffer *buffer); void *prRhiBufferMap(PrRhiDevice *device, PrRhiBuffer *buffer);
void prRhiBufferUnmap(PrRhiDevice *device, PrRhiBuffer *buffer); void prRhiBufferUnmap(PrRhiDevice *device, PrRhiBuffer *buffer);
@@ -105,115 +106,96 @@ PrRhiDeviceAddress prRhiGetBufferDeviceAddress(PrRhiDevice *device, PrRhiBuffer
// Textures // Textures
// ====================================================================== // ======================================================================
PrRhiTexture *prRhiCreateTexture(PrRhiDevice *device, PrRhiTextureDesc desc, PrRhiTexture *prRhiCreateTexture(PrRhiDevice *device, PrRhiTextureDesc desc);
WpAllocator *allocator);
PrRhiTexture *prRhiCreateTextureFromKtx(PrRhiDevice *device, const char *path, PrRhiTexture *prRhiCreateTextureFromKtx(PrRhiDevice *device, const char *path,
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb, PrRhiCommandPool *pool, PrRhiCommandBuffer *cb);
WpAllocator *allocator); void prRhiDestroyTexture(PrRhiDevice *device, PrRhiTexture *texture);
void prRhiDestroyTexture(PrRhiDevice *device, PrRhiTexture *texture,
WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Samplers // Samplers
// ====================================================================== // ======================================================================
PrRhiSampler *prRhiCreateSampler(PrRhiDevice *device, PrRhiSamplerDesc desc, PrRhiSampler *prRhiCreateSampler(PrRhiDevice *device, PrRhiSamplerDesc desc);
WpAllocator *allocator); void prRhiDestroySampler(PrRhiDevice *device, PrRhiSampler *sampler);
void prRhiDestroySampler(PrRhiDevice *device, PrRhiSampler *sampler,
WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Shaders (from SPIR-V) // Shaders (from SPIR-V)
// ====================================================================== // ======================================================================
PrRhiShader *prRhiCreateShader(PrRhiDevice *device, PrRhiShaderDesc desc, PrRhiShader *prRhiCreateShader(PrRhiDevice *device, PrRhiShaderDesc desc);
WpAllocator *allocator); void prRhiDestroyShader(PrRhiDevice *device, PrRhiShader *shader);
void prRhiDestroyShader(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Pipeline layouts // Pipeline layouts
// ====================================================================== // ======================================================================
PrRhiPipelineLayout *prRhiCreatePipelineLayout(PrRhiDevice *device, PrRhiPipelineLayout *prRhiCreatePipelineLayout(PrRhiDevice *device,
PrRhiPipelineLayoutDesc desc, PrRhiPipelineLayoutDesc desc);
WpAllocator *allocator);
void prRhiDestroyPipelineLayout(PrRhiDevice *device, void prRhiDestroyPipelineLayout(PrRhiDevice *device,
PrRhiPipelineLayout *layout, PrRhiPipelineLayout *layout);
WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Pipelines // Pipelines
// ====================================================================== // ======================================================================
PrRhiPipeline *prRhiCreateGraphicsPipeline(PrRhiDevice *device, PrRhiPipeline *prRhiCreateGraphicsPipeline(PrRhiDevice *device,
PrRhiGraphicsPipelineDesc desc, PrRhiGraphicsPipelineDesc desc);
WpAllocator *allocator);
PrRhiPipeline *prRhiCreateComputePipeline(PrRhiDevice *device, PrRhiPipeline *prRhiCreateComputePipeline(PrRhiDevice *device,
PrRhiComputePipelineDesc desc, PrRhiComputePipelineDesc desc);
WpAllocator *allocator); void prRhiDestroyPipeline(PrRhiDevice *device, PrRhiPipeline *pipeline);
void prRhiDestroyPipeline(PrRhiDevice *device, PrRhiPipeline *pipeline,
WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Descriptor set layouts // Descriptor set layouts
// ====================================================================== // ======================================================================
PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayout(PrRhiDevice *device, PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayout(PrRhiDevice *device,
PrRhiDescriptorSetLayoutDesc desc, PrRhiDescriptorSetLayoutDesc desc);
WpAllocator *allocator);
void prRhiDestroyDescriptorSetLayout(PrRhiDevice *device, void prRhiDestroyDescriptorSetLayout(PrRhiDevice *device,
PrRhiDescriptorSetLayout *layout, PrRhiDescriptorSetLayout *layout);
WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Descriptor pools // Descriptor pools
// ====================================================================== // ======================================================================
PrRhiDescriptorPool *prRhiCreateDescriptorPool(PrRhiDevice *device, PrRhiDescriptorPool *prRhiCreateDescriptorPool(PrRhiDevice *device,
PrRhiDescriptorPoolDesc desc, PrRhiDescriptorPoolDesc desc);
WpAllocator *allocator);
void prRhiDestroyDescriptorPool(PrRhiDevice *device, void prRhiDestroyDescriptorPool(PrRhiDevice *device,
PrRhiDescriptorPool *pool, PrRhiDescriptorPool *pool);
WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Descriptor sets // Descriptor sets
// ====================================================================== // ======================================================================
PrRhiDescriptorSet *prRhiAllocateDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool, PrRhiDescriptorSet *prRhiAllocateDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
PrRhiDescriptorSetLayout *layout, PrRhiDescriptorSetLayout *layout,
u32 variable_count, WpAllocator *allocator); u32 variable_count);
void prRhiFreeDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool, void prRhiFreeDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
PrRhiDescriptorSet *set, WpAllocator *allocator); PrRhiDescriptorSet *set);
void prRhiUpdateDescriptorSet(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes); void prRhiUpdateDescriptorSet(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
// ====================================================================== // ======================================================================
// Fences and semaphores // Fences and semaphores
// ====================================================================== // ======================================================================
PrRhiFence *prRhiCreateFence(PrRhiDevice *device, PrRhiFenceDesc desc, PrRhiFence *prRhiCreateFence(PrRhiDevice *device, PrRhiFenceDesc desc);
WpAllocator *allocator); void prRhiDestroyFence(PrRhiDevice *device, PrRhiFence *fence);
void prRhiDestroyFence(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *allocator);
void prRhiWaitForFences(PrRhiDevice *device, PrRhiFenceArray fences, u32 count, void prRhiWaitForFences(PrRhiDevice *device, PrRhiFenceArray fences, u32 count,
b8 wait_all, u64 timeout_ns); b8 wait_all, u64 timeout_ns);
void prRhiResetFences(PrRhiDevice *device, PrRhiFenceArray fences, u32 count); void prRhiResetFences(PrRhiDevice *device, PrRhiFenceArray fences, u32 count);
PrRhiSemaphore *prRhiCreateSemaphore(PrRhiDevice *device, WpAllocator *allocator); PrRhiSemaphore *prRhiCreateSemaphore(PrRhiDevice *device);
void prRhiDestroySemaphore(PrRhiDevice *device, PrRhiSemaphore *semaphore, void prRhiDestroySemaphore(PrRhiDevice *device, PrRhiSemaphore *semaphore);
WpAllocator *allocator);
// ====================================================================== // ======================================================================
// Command pools and command buffers // Command pools and command buffers
// ====================================================================== // ======================================================================
PrRhiCommandPool *prRhiCreateCommandPool(PrRhiDevice *device, PrRhiCommandPoolDesc desc, PrRhiCommandPool *prRhiCreateCommandPool(PrRhiDevice *device, PrRhiCommandPoolDesc desc);
WpAllocator *allocator); void prRhiDestroyCommandPool(PrRhiDevice *device, PrRhiCommandPool *pool);
void prRhiDestroyCommandPool(PrRhiDevice *device, PrRhiCommandPool *pool,
WpAllocator *allocator);
PrRhiCommandBufferArray prRhiAllocateCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool, PrRhiCommandBufferArray prRhiAllocateCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
u32 count, WpAllocator *allocator); u32 count);
void prRhiFreeCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool, void prRhiFreeCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
u32 count, PrRhiCommandBufferArray buffers); u32 count, PrRhiCommandBufferArray buffers);
+9
View File
@@ -438,6 +438,15 @@ typedef struct PrRhiPhysicalDeviceProperties {
typedef u64 PrRhiDeviceAddress; typedef u64 PrRhiDeviceAddress;
// ============================================================================
// RHI context (global, owns all RHI object lifetimes)
// ============================================================================
typedef struct PrRhiContext {
WpAllocator main;
WpAllocator scratch;
} PrRhiContext;
// --- Command buffer types --- // --- Command buffer types ---
typedef struct PrRhiDepthAttachment { typedef struct PrRhiDepthAttachment {
+108 -130
View File
@@ -6,6 +6,7 @@
#include "pr_rhi_vk.h" #include "pr_rhi_vk.h"
#include "profiles/vulkan_profiles.h" #include "profiles/vulkan_profiles.h"
#include "../pr_rhi.h"
#include <volk/volk.h> #include <volk/volk.h>
#include <vk_mem_alloc.h> #include <vk_mem_alloc.h>
#include <SDL3/SDL_vulkan.h> #include <SDL3/SDL_vulkan.h>
@@ -312,7 +313,7 @@ VkPhysicalDeviceType _toVkPhysicalDeviceType(PrRhiPhysicalDeviceType type) {
// Instance // Instance
// ============================================================================ // ============================================================================
PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *allocator) { PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc) {
_checkVk(volkInitialize(), "volkInitialize"); _checkVk(volkInitialize(), "volkInitialize");
VkBool32 supported = VK_FALSE; VkBool32 supported = VK_FALSE;
@@ -347,7 +348,7 @@ PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *alloca
volkLoadInstance(vk_instance); volkLoadInstance(vk_instance);
PrRhiInstance *inst = wpMemAllocatorAlloc(allocator, sizeof(PrRhiInstance)); PrRhiInstance *inst = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiInstance));
if (!inst) { _abort("alloc failed for PrRhiInstance"); } if (!inst) { _abort("alloc failed for PrRhiInstance"); }
inst->handle = vk_instance; inst->handle = vk_instance;
inst->debug_messenger = NULL; inst->debug_messenger = NULL;
@@ -355,34 +356,34 @@ PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *alloca
return inst; return inst;
} }
void prRhiDestroyInstanceVk(PrRhiInstance *inst, WpAllocator *allocator) { void prRhiDestroyInstanceVk(PrRhiInstance *inst) {
if (!inst) { return; } if (!inst) { return; }
vkDestroyInstance((VkInstance)inst->handle, NULL); vkDestroyInstance((VkInstance)inst->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&inst, sizeof(PrRhiInstance)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&inst, sizeof(PrRhiInstance));
} }
// ============================================================================ // ============================================================================
// Physical device enumeration // Physical device enumeration
// ============================================================================ // ============================================================================
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst, const WpAllocator *allocator) { PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst) {
VkInstance vk_inst = (VkInstance)inst->handle; VkInstance vk_inst = (VkInstance)inst->handle;
u32 count = 0; u32 count = 0;
_checkVk(vkEnumeratePhysicalDevices(vk_inst, &count, NULL), "vkEnumeratePhysicalDevices"); _checkVk(vkEnumeratePhysicalDevices(vk_inst, &count, NULL), "vkEnumeratePhysicalDevices");
if (count == 0) _abort("no physical devices"); if (count == 0) _abort("no physical devices");
VkPhysicalDeviceArray vk_devices = wpArrayAllocCapacity(VkPhysicalDevice, allocator, count, WP_ARRAY_INIT_FILLED); VkPhysicalDeviceArray vk_devices = wpArrayAllocCapacity(VkPhysicalDevice, &_G_RHI_CONTEXT.scratch, count, WP_ARRAY_INIT_FILLED);
if (!vk_devices) _abort("alloc failed for physical device array"); if (!vk_devices) _abort("alloc failed for physical device array");
_checkVk(vkEnumeratePhysicalDevices(vk_inst, &count, vk_devices), "vkEnumeratePhysicalDevices"); _checkVk(vkEnumeratePhysicalDevices(vk_inst, &count, vk_devices), "vkEnumeratePhysicalDevices");
wpArraySetCount(vk_devices, count); wpArraySetCount(vk_devices, count);
PrRhiPhysicalDeviceArray pdevs = wpArrayAllocCapacity(PrRhiPhysicalDevice *, allocator, count, WP_ARRAY_INIT_NONE); PrRhiPhysicalDeviceArray pdevs = wpArrayAllocCapacity(PrRhiPhysicalDevice *, &_G_RHI_CONTEXT.main, count, WP_ARRAY_INIT_NONE);
if (!pdevs) _abort("alloc failed for PrRhiPhysicalDevice array"); if (!pdevs) _abort("alloc failed for PrRhiPhysicalDevice array");
for (u32 i = 0; i < count; ++i) { for (u32 i = 0; i < count; ++i) {
PrRhiPhysicalDevice *pdev = (PrRhiPhysicalDevice *)wpMemAllocatorAlloc(allocator, sizeof(PrRhiPhysicalDevice)); PrRhiPhysicalDevice *pdev = (PrRhiPhysicalDevice *)wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiPhysicalDevice));
if (!pdev) _abort("alloc failed for PrRhiPhysicalDevice"); if (!pdev) _abort("alloc failed for PrRhiPhysicalDevice");
pdev->handle = vk_devices[i]; pdev->handle = vk_devices[i];
pdev->instance = inst; pdev->instance = inst;
@@ -424,8 +425,7 @@ void prRhiGetPhysicalDevicePropertiesVk(PrRhiPhysicalDevice *pdev,
// Surface // Surface
// ============================================================================ // ============================================================================
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle, PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle) {
WpAllocator *allocator) {
SDL_Window *window = (SDL_Window *)window_handle; SDL_Window *window = (SDL_Window *)window_handle;
VkInstance vk_inst = (VkInstance)inst->handle; VkInstance vk_inst = (VkInstance)inst->handle;
@@ -433,16 +433,16 @@ PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_h
if (!SDL_Vulkan_CreateSurface(window, vk_inst, NULL, &vk_surface)) if (!SDL_Vulkan_CreateSurface(window, vk_inst, NULL, &vk_surface))
_abort("SDL_Vulkan_CreateSurface failed"); _abort("SDL_Vulkan_CreateSurface failed");
PrRhiSurface *surface = wpMemAllocatorAlloc(allocator, sizeof(PrRhiSurface)); PrRhiSurface *surface = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiSurface));
if (!surface) _abort("alloc failed for PrRhiSurface"); if (!surface) _abort("alloc failed for PrRhiSurface");
surface->handle = (void *)vk_surface; surface->handle = (void *)vk_surface;
return surface; return surface;
} }
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *allocator) { void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface) {
if (!surface) return; if (!surface) return;
vkDestroySurfaceKHR((VkInstance)inst->handle, (VkSurfaceKHR)surface->handle, NULL); vkDestroySurfaceKHR((VkInstance)inst->handle, (VkSurfaceKHR)surface->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&surface, sizeof(PrRhiSurface)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&surface, sizeof(PrRhiSurface));
} }
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface) { PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface) {
@@ -469,7 +469,7 @@ PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev
// ============================================================================ // ============================================================================
PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface, PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
PrRhiDeviceDesc desc, WpAllocator *allocator) { PrRhiDeviceDesc desc) {
VkInstance vk_inst = (VkInstance)pdev->instance->handle; VkInstance vk_inst = (VkInstance)pdev->instance->handle;
VkPhysicalDevice vk_pdev = (VkPhysicalDevice)pdev->handle; VkPhysicalDevice vk_pdev = (VkPhysicalDevice)pdev->handle;
VkSurfaceKHR vk_surface = (VkSurfaceKHR)surface->handle; VkSurfaceKHR vk_surface = (VkSurfaceKHR)surface->handle;
@@ -480,7 +480,7 @@ PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surfac
if (queue_family_count == 0) _abort("no queue families"); if (queue_family_count == 0) _abort("no queue families");
VkQueueFamilyProperties2Array qf_props = VkQueueFamilyProperties2Array qf_props =
wpArrayAllocCapacity(VkQueueFamilyProperties2, allocator, queue_family_count, WP_ARRAY_INIT_FILLED); wpArrayAllocCapacity(VkQueueFamilyProperties2, &_G_RHI_CONTEXT.scratch, queue_family_count, WP_ARRAY_INIT_FILLED);
if (!qf_props) _abort("alloc failed for queue family props"); if (!qf_props) _abort("alloc failed for queue family props");
for (u32 i = 0; i < queue_family_count; ++i) { for (u32 i = 0; i < queue_family_count; ++i) {
@@ -505,7 +505,7 @@ PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surfac
"vkGetPhysicalDeviceSurfaceSupportKHR"); "vkGetPhysicalDeviceSurfaceSupportKHR");
if (!present_supported) _abort("no presentation support"); if (!present_supported) _abort("no presentation support");
wpArrayDealloc(VkQueueFamilyProperties2, allocator, &qf_props); wpArrayDealloc(VkQueueFamilyProperties2, &_G_RHI_CONTEXT.scratch, &qf_props);
// Check device profile support // Check device profile support
VkBool32 profile_supported = VK_FALSE; VkBool32 profile_supported = VK_FALSE;
@@ -557,7 +557,7 @@ PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surfac
VmaAllocator vma_allocator = VK_NULL_HANDLE; VmaAllocator vma_allocator = VK_NULL_HANDLE;
_checkVk(vmaCreateAllocator(&vma_info, &vma_allocator), "vmaCreateAllocator"); _checkVk(vmaCreateAllocator(&vma_info, &vma_allocator), "vmaCreateAllocator");
PrRhiDevice *device = wpMemAllocatorAlloc(allocator, sizeof(PrRhiDevice)); PrRhiDevice *device = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiDevice));
if (!device) _abort("alloc failed for PrRhiDevice"); if (!device) _abort("alloc failed for PrRhiDevice");
device->handle = vk_device; device->handle = vk_device;
device->queue = vk_queue; device->queue = vk_queue;
@@ -569,12 +569,12 @@ PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surfac
return device; return device;
} }
void prRhiDestroyDeviceVk(PrRhiDevice *device, WpAllocator *allocator) { void prRhiDestroyDeviceVk(PrRhiDevice *device) {
if (!device) return; if (!device) return;
vkDeviceWaitIdle((VkDevice)device->handle); vkDeviceWaitIdle((VkDevice)device->handle);
vmaDestroyAllocator((VmaAllocator)device->allocator); vmaDestroyAllocator((VmaAllocator)device->allocator);
vkDestroyDevice((VkDevice)device->handle, NULL); vkDestroyDevice((VkDevice)device->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&device, sizeof(PrRhiDevice)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&device, sizeof(PrRhiDevice));
} }
void prRhiDeviceWaitIdleVk(PrRhiDevice *device) { void prRhiDeviceWaitIdleVk(PrRhiDevice *device) {
@@ -590,9 +590,9 @@ u32 prRhiGetQueueFamilyIndexVk(PrRhiDevice *device) {
// ============================================================================ // ============================================================================
static PrRhiTexture *_createSwapchainTexture(PrRhiDevice *device, VkImage vk_image, static PrRhiTexture *_createSwapchainTexture(PrRhiDevice *device, VkImage vk_image,
VkFormat vk_format, u32 width, u32 height, VkFormat vk_format, u32 width, u32 height,
VkImageView vk_view, WpAllocator *allocator) { VkImageView vk_view) {
PrRhiTexture *tex = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture)); PrRhiTexture *tex = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
if (!tex) _abort("alloc failed for swapchain texture"); if (!tex) _abort("alloc failed for swapchain texture");
tex->image = vk_image; tex->image = vk_image;
tex->view = vk_view; tex->view = vk_view;
@@ -615,8 +615,7 @@ static VkFormat _pickDepthFormat(VkPhysicalDevice vk_pdev) {
return VK_FORMAT_UNDEFINED; return VK_FORMAT_UNDEFINED;
} }
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc, PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc) {
WpAllocator *allocator) {
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
VkPhysicalDevice vk_pdev = (VkPhysicalDevice)device->physical_device; VkPhysicalDevice vk_pdev = (VkPhysicalDevice)device->physical_device;
VkSurfaceKHR vk_surface = (VkSurfaceKHR)desc.surface->handle; VkSurfaceKHR vk_surface = (VkSurfaceKHR)desc.surface->handle;
@@ -652,13 +651,13 @@ PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc d
_checkVk(vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, NULL), _checkVk(vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, NULL),
"vkGetSwapchainImagesKHR"); "vkGetSwapchainImagesKHR");
VkImageArray vk_images = wpArrayAllocCapacity(VkImage, allocator, image_count, WP_ARRAY_INIT_FILLED); VkImageArray vk_images = wpArrayAllocCapacity(VkImage, &_G_RHI_CONTEXT.scratch, image_count, WP_ARRAY_INIT_FILLED);
if (!vk_images) _abort("alloc failed for swapchain VkImage array"); if (!vk_images) _abort("alloc failed for swapchain VkImage array");
_checkVk(vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, vk_images), _checkVk(vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, vk_images),
"vkGetSwapchainImagesKHR"); "vkGetSwapchainImagesKHR");
wpArraySetCount(vk_images, image_count); wpArraySetCount(vk_images, image_count);
PrRhiTextureArray images = wpArrayAllocCapacity(PrRhiTexture *, allocator, image_count, WP_ARRAY_INIT_NONE); PrRhiTextureArray images = wpArrayAllocCapacity(PrRhiTexture *, &_G_RHI_CONTEXT.main, image_count, WP_ARRAY_INIT_NONE);
if (!images) _abort("alloc failed for swapchain image array"); if (!images) _abort("alloc failed for swapchain image array");
for (u32 i = 0; i < image_count; ++i) { for (u32 i = 0; i < image_count; ++i) {
@@ -675,13 +674,13 @@ PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc d
_checkVk(vkCreateImageView(vk_device, &view_info, NULL, &vk_view), "vkCreateImageView"); _checkVk(vkCreateImageView(vk_device, &view_info, NULL, &vk_view), "vkCreateImageView");
PrRhiTexture *tex = _createSwapchainTexture(device, vk_images[i], _default_image_format, PrRhiTexture *tex = _createSwapchainTexture(device, vk_images[i], _default_image_format,
extent.width, extent.height, vk_view, allocator); extent.width, extent.height, vk_view);
wpArrayAppendCapped(PrRhiTexture *, images, &tex); wpArrayAppendCapped(PrRhiTexture *, images, &tex);
} }
wpArrayDealloc(VkImage, allocator, &vk_images); wpArrayDealloc(VkImage, &_G_RHI_CONTEXT.scratch, &vk_images);
PrRhiSwapchain *swapchain = wpMemAllocatorAlloc(allocator, sizeof(PrRhiSwapchain)); PrRhiSwapchain *swapchain = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiSwapchain));
if (!swapchain) _abort("alloc failed for PrRhiSwapchain"); if (!swapchain) _abort("alloc failed for PrRhiSwapchain");
swapchain->device = device; swapchain->device = device;
swapchain->handle = vk_swapchain; swapchain->handle = vk_swapchain;
@@ -741,7 +740,7 @@ PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc d
VkImageView depth_view = VK_NULL_HANDLE; VkImageView depth_view = VK_NULL_HANDLE;
_checkVk(vkCreateImageView(vk_device, &depth_view_info, NULL, &depth_view), "vkCreateImageView (depth)"); _checkVk(vkCreateImageView(vk_device, &depth_view_info, NULL, &depth_view), "vkCreateImageView (depth)");
PrRhiTexture *depth_tex = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture)); PrRhiTexture *depth_tex = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
if (!depth_tex) _abort("alloc failed for depth texture"); if (!depth_tex) _abort("alloc failed for depth texture");
depth_tex->image = depth_image; depth_tex->image = depth_image;
depth_tex->view = depth_view; depth_tex->view = depth_view;
@@ -757,7 +756,7 @@ PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc d
return swapchain; return swapchain;
} }
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, WpAllocator *allocator) { void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain) {
if (!swapchain) return; if (!swapchain) return;
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
@@ -767,9 +766,9 @@ void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, WpA
PrRhiTexture *tex = swapchain->images[i]; PrRhiTexture *tex = swapchain->images[i];
vkDestroyImageView(vk_device, (VkImageView)tex->view, NULL); vkDestroyImageView(vk_device, (VkImageView)tex->view, NULL);
// VkImage is owned by swapchain — skip vmaDestroyImage // VkImage is owned by swapchain — skip vmaDestroyImage
wpMemAllocatorFree(allocator, (void**)&tex, sizeof(PrRhiTexture)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&tex, sizeof(PrRhiTexture));
} }
wpArrayDealloc(PrRhiTexture *, allocator, &swapchain->images); wpArrayDealloc(PrRhiTexture *, &_G_RHI_CONTEXT.main, &swapchain->images);
// Destroy depth // Destroy depth
if (swapchain->depth) { if (swapchain->depth) {
@@ -777,11 +776,11 @@ void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, WpA
vkDestroyImageView(vk_device, (VkImageView)depth->view, NULL); vkDestroyImageView(vk_device, (VkImageView)depth->view, NULL);
vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)depth->image, vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)depth->image,
(VmaAllocation)depth->allocation); (VmaAllocation)depth->allocation);
wpMemAllocatorFree(allocator, (void**)&depth, sizeof(PrRhiTexture)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&depth, sizeof(PrRhiTexture));
} }
vkDestroySwapchainKHR(vk_device, (VkSwapchainKHR)swapchain->handle, NULL); vkDestroySwapchainKHR(vk_device, (VkSwapchainKHR)swapchain->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&swapchain, sizeof(PrRhiSwapchain)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&swapchain, sizeof(PrRhiSwapchain));
} }
PrRhiSwapchainResult prRhiAcquireNextImageVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, PrRhiSwapchainResult prRhiAcquireNextImageVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
@@ -816,7 +815,7 @@ PrRhiSwapchainResult prRhiPresentVk(PrRhiDevice *device, PrRhiSwapchain *swapcha
} }
void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain, void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
u32 width, u32 height, WpAllocator *allocator) { u32 width, u32 height) {
PrRhiSwapchain *old = *swapchain; PrRhiSwapchain *old = *swapchain;
if (!old) return; if (!old) return;
@@ -847,9 +846,9 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
for (u32 i = 0; i < old->image_count; ++i) { for (u32 i = 0; i < old->image_count; ++i) {
PrRhiTexture *tex = old->images[i]; PrRhiTexture *tex = old->images[i];
vkDestroyImageView(vk_device, (VkImageView)tex->view, NULL); vkDestroyImageView(vk_device, (VkImageView)tex->view, NULL);
wpMemAllocatorFree(allocator, (void**)&tex, sizeof(PrRhiTexture)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&tex, sizeof(PrRhiTexture));
} }
wpArrayDealloc(PrRhiTexture *, allocator, &old->images); wpArrayDealloc(PrRhiTexture *, &_G_RHI_CONTEXT.main, &old->images);
// Destroy old depth // Destroy old depth
if (old->depth) { if (old->depth) {
@@ -857,7 +856,7 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
vkDestroyImageView(vk_device, (VkImageView)depth->view, NULL); vkDestroyImageView(vk_device, (VkImageView)depth->view, NULL);
vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)depth->image, vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)depth->image,
(VmaAllocation)depth->allocation); (VmaAllocation)depth->allocation);
wpMemAllocatorFree(allocator, (void**)&depth, sizeof(PrRhiTexture)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&depth, sizeof(PrRhiTexture));
} }
// Destroy old swapchain // Destroy old swapchain
@@ -868,13 +867,13 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
_checkVk(vkGetSwapchainImagesKHR(vk_device, vk_new_swapchain, &new_image_count, NULL), _checkVk(vkGetSwapchainImagesKHR(vk_device, vk_new_swapchain, &new_image_count, NULL),
"vkGetSwapchainImagesKHR (recreate)"); "vkGetSwapchainImagesKHR (recreate)");
VkImageArray vk_images = wpArrayAllocCapacity(VkImage, allocator, new_image_count, WP_ARRAY_INIT_FILLED); VkImageArray vk_images = wpArrayAllocCapacity(VkImage, &_G_RHI_CONTEXT.scratch, new_image_count, WP_ARRAY_INIT_FILLED);
if (!vk_images) _abort("alloc failed for swapchain VkImage array (recreate)"); if (!vk_images) _abort("alloc failed for swapchain VkImage array (recreate)");
_checkVk(vkGetSwapchainImagesKHR(vk_device, vk_new_swapchain, &new_image_count, vk_images), _checkVk(vkGetSwapchainImagesKHR(vk_device, vk_new_swapchain, &new_image_count, vk_images),
"vkGetSwapchainImagesKHR (recreate)"); "vkGetSwapchainImagesKHR (recreate)");
wpArraySetCount(vk_images, new_image_count); wpArraySetCount(vk_images, new_image_count);
PrRhiTextureArray new_images = wpArrayAllocCapacity(PrRhiTexture *, allocator, new_image_count, WP_ARRAY_INIT_NONE); PrRhiTextureArray new_images = wpArrayAllocCapacity(PrRhiTexture *, &_G_RHI_CONTEXT.main, new_image_count, WP_ARRAY_INIT_NONE);
if (!new_images) _abort("alloc failed for swapchain image array (recreate)"); if (!new_images) _abort("alloc failed for swapchain image array (recreate)");
for (u32 i = 0; i < new_image_count; ++i) { for (u32 i = 0; i < new_image_count; ++i) {
@@ -891,11 +890,11 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
_checkVk(vkCreateImageView(vk_device, &view_info, NULL, &vk_view), "vkCreateImageView (recreate)"); _checkVk(vkCreateImageView(vk_device, &view_info, NULL, &vk_view), "vkCreateImageView (recreate)");
PrRhiTexture *tex = _createSwapchainTexture(device, vk_images[i], (VkFormat)old->format, PrRhiTexture *tex = _createSwapchainTexture(device, vk_images[i], (VkFormat)old->format,
extent.width, extent.height, vk_view, allocator); extent.width, extent.height, vk_view);
wpArrayAppendCapped(PrRhiTexture *, new_images, &tex); wpArrayAppendCapped(PrRhiTexture *, new_images, &tex);
} }
wpArrayDealloc(VkImage, allocator, &vk_images); wpArrayDealloc(VkImage, &_G_RHI_CONTEXT.scratch, &vk_images);
// Recreate depth // Recreate depth
PrRhiTexture *new_depth = NULL; PrRhiTexture *new_depth = NULL;
@@ -939,7 +938,7 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
VkImageView depth_view = VK_NULL_HANDLE; VkImageView depth_view = VK_NULL_HANDLE;
_checkVk(vkCreateImageView(vk_device, &depth_view_info, NULL, &depth_view), "vkCreateImageView (depth recreate)"); _checkVk(vkCreateImageView(vk_device, &depth_view_info, NULL, &depth_view), "vkCreateImageView (depth recreate)");
new_depth = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture)); new_depth = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
if (!new_depth) _abort("alloc failed for depth texture (recreate)"); if (!new_depth) _abort("alloc failed for depth texture (recreate)");
new_depth->image = depth_image; new_depth->image = depth_image;
new_depth->view = depth_view; new_depth->view = depth_view;
@@ -979,8 +978,7 @@ PrRhiFormat prRhiGetSwapchainFormatVk(PrRhiSwapchain *swapchain) {
// Buffers // Buffers
// ============================================================================ // ============================================================================
PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc, PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc) {
WpAllocator *allocator) {
VkBufferCreateInfo buf_info = {}; VkBufferCreateInfo buf_info = {};
buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
buf_info.size = desc.size; buf_info.size = desc.size;
@@ -1005,7 +1003,7 @@ PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc,
&vk_buffer, &vma_alloc, &vma_alloc_info), &vk_buffer, &vma_alloc, &vma_alloc_info),
"vmaCreateBuffer"); "vmaCreateBuffer");
PrRhiBuffer *buffer = wpMemAllocatorAlloc(allocator, sizeof(PrRhiBuffer)); PrRhiBuffer *buffer = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiBuffer));
if (!buffer) _abort("alloc failed for PrRhiBuffer"); if (!buffer) _abort("alloc failed for PrRhiBuffer");
buffer->handle = vk_buffer; buffer->handle = vk_buffer;
buffer->allocation = vma_alloc; buffer->allocation = vma_alloc;
@@ -1024,11 +1022,11 @@ PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc,
return buffer; return buffer;
} }
void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *allocator) { void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer) {
if (!buffer) return; if (!buffer) return;
vmaDestroyBuffer((VmaAllocator)device->allocator, (VkBuffer)buffer->handle, vmaDestroyBuffer((VmaAllocator)device->allocator, (VkBuffer)buffer->handle,
(VmaAllocation)buffer->allocation); (VmaAllocation)buffer->allocation);
wpMemAllocatorFree(allocator, (void**)&buffer, sizeof(PrRhiBuffer)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&buffer, sizeof(PrRhiBuffer));
} }
void *prRhiBufferMapVk(PrRhiDevice *device, PrRhiBuffer *buffer) { void *prRhiBufferMapVk(PrRhiDevice *device, PrRhiBuffer *buffer) {
@@ -1051,8 +1049,7 @@ PrRhiDeviceAddress prRhiGetBufferDeviceAddressVk(PrRhiDevice *device, PrRhiBuffe
// Textures // Textures
// ============================================================================ // ============================================================================
PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc, PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc) {
WpAllocator *allocator) {
VkImageCreateInfo img_info = {}; VkImageCreateInfo img_info = {};
img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
img_info.imageType = VK_IMAGE_TYPE_2D; img_info.imageType = VK_IMAGE_TYPE_2D;
@@ -1094,7 +1091,7 @@ PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc,
_checkVk(vkCreateImageView((VkDevice)device->handle, &view_info, NULL, &vk_view), _checkVk(vkCreateImageView((VkDevice)device->handle, &view_info, NULL, &vk_view),
"vkCreateImageView"); "vkCreateImageView");
PrRhiTexture *texture = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture)); PrRhiTexture *texture = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
if (!texture) _abort("alloc failed for PrRhiTexture"); if (!texture) _abort("alloc failed for PrRhiTexture");
texture->image = vk_image; texture->image = vk_image;
texture->view = vk_view; texture->view = vk_view;
@@ -1107,8 +1104,7 @@ PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc,
} }
PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path, PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb, PrRhiCommandPool *pool, PrRhiCommandBuffer *cb) {
WpAllocator *allocator) {
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
ktxTexture *ktx = NULL; ktxTexture *ktx = NULL;
@@ -1129,7 +1125,7 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
.usage = PR_RHI_BUFFER_USAGE_TRANSFER_SRC, .usage = PR_RHI_BUFFER_USAGE_TRANSFER_SRC,
.memory = PR_RHI_MEMORY_CPU_TO_GPU, .memory = PR_RHI_MEMORY_CPU_TO_GPU,
}; };
PrRhiBuffer *staging = prRhiCreateBufferVk(device, buf_desc, allocator); PrRhiBuffer *staging = prRhiCreateBufferVk(device, buf_desc);
memcpy(prRhiBufferMapVk(device, staging), data, data_size); memcpy(prRhiBufferMapVk(device, staging), data, data_size);
// Create the destination image // Create the destination image
@@ -1210,10 +1206,10 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
// Submit and wait // Submit and wait
PrRhiFenceDesc fence_desc = { .signaled = false }; PrRhiFenceDesc fence_desc = { .signaled = false };
PrRhiFence *fence = prRhiCreateFenceVk(device, fence_desc, allocator); PrRhiFence *fence = prRhiCreateFenceVk(device, fence_desc);
prRhiQueueSubmitVk(device, cb, NULL, NULL, fence); prRhiQueueSubmitVk(device, cb, NULL, NULL, fence);
prRhiWaitForFencesVk(device, &(PrRhiFence *){ fence }, 1, VK_TRUE, UINT64_MAX); prRhiWaitForFencesVk(device, &(PrRhiFence *){ fence }, 1, VK_TRUE, UINT64_MAX);
prRhiDestroyFenceVk(device, fence, allocator); prRhiDestroyFenceVk(device, fence);
vkResetCommandBuffer(vk_cb, 0); vkResetCommandBuffer(vk_cb, 0);
// Create image view // Create image view
@@ -1230,7 +1226,7 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
_checkVk(vkCreateImageView(vk_device, &view_info, NULL, &vk_view), _checkVk(vkCreateImageView(vk_device, &view_info, NULL, &vk_view),
"vkCreateImageView"); "vkCreateImageView");
PrRhiTexture *texture = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture)); PrRhiTexture *texture = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
if (!texture) _abort("alloc failed for PrRhiTexture"); if (!texture) _abort("alloc failed for PrRhiTexture");
texture->image = vk_image; texture->image = vk_image;
texture->view = vk_view; texture->view = vk_view;
@@ -1240,13 +1236,13 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
texture->format = vk_format; texture->format = vk_format;
// Cleanup staging // Cleanup staging
prRhiDestroyBufferVk(device, staging, allocator); prRhiDestroyBufferVk(device, staging);
ktxTexture_Destroy(ktx); ktxTexture_Destroy(ktx);
return texture; return texture;
} }
void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture, WpAllocator *allocator) { void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture) {
if (!texture) return; if (!texture) return;
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
@@ -1255,15 +1251,14 @@ void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture, WpAllocat
vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)texture->image, vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)texture->image,
(VmaAllocation)texture->allocation); (VmaAllocation)texture->allocation);
} }
wpMemAllocatorFree(allocator, (void**)&texture, sizeof(PrRhiTexture)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&texture, sizeof(PrRhiTexture));
} }
// ============================================================================ // ============================================================================
// Samplers // Samplers
// ============================================================================ // ============================================================================
PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc, PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc) {
WpAllocator *allocator) {
VkSamplerCreateInfo info = {}; VkSamplerCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
info.magFilter = _toVkFilter(desc.mag_filter); info.magFilter = _toVkFilter(desc.mag_filter);
@@ -1282,24 +1277,23 @@ PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc,
_checkVk(vkCreateSampler((VkDevice)device->handle, &info, NULL, &vk_sampler), _checkVk(vkCreateSampler((VkDevice)device->handle, &info, NULL, &vk_sampler),
"vkCreateSampler"); "vkCreateSampler");
PrRhiSampler *sampler = wpMemAllocatorAlloc(allocator, sizeof(PrRhiSampler)); PrRhiSampler *sampler = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiSampler));
if (!sampler) _abort("alloc failed for PrRhiSampler"); if (!sampler) _abort("alloc failed for PrRhiSampler");
sampler->handle = vk_sampler; sampler->handle = vk_sampler;
return sampler; return sampler;
} }
void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler, WpAllocator *allocator) { void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler) {
if (!sampler) return; if (!sampler) return;
vkDestroySampler((VkDevice)device->handle, (VkSampler)sampler->handle, NULL); vkDestroySampler((VkDevice)device->handle, (VkSampler)sampler->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&sampler, sizeof(PrRhiSampler)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&sampler, sizeof(PrRhiSampler));
} }
// ============================================================================ // ============================================================================
// Shaders // Shaders
// ============================================================================ // ============================================================================
PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc, PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc) {
WpAllocator *allocator) {
VkShaderModuleCreateInfo info = {}; VkShaderModuleCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
info.codeSize = desc.spirv_size; info.codeSize = desc.spirv_size;
@@ -1309,16 +1303,16 @@ PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc,
_checkVk(vkCreateShaderModule((VkDevice)device->handle, &info, NULL, &vk_module), _checkVk(vkCreateShaderModule((VkDevice)device->handle, &info, NULL, &vk_module),
"vkCreateShaderModule"); "vkCreateShaderModule");
PrRhiShader *shader = wpMemAllocatorAlloc(allocator, sizeof(PrRhiShader)); PrRhiShader *shader = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiShader));
if (!shader) _abort("alloc failed for PrRhiShader"); if (!shader) _abort("alloc failed for PrRhiShader");
shader->handle = vk_module; shader->handle = vk_module;
return shader; return shader;
} }
void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *allocator) { void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader) {
if (!shader) return; if (!shader) return;
vkDestroyShaderModule((VkDevice)device->handle, (VkShaderModule)shader->handle, NULL); vkDestroyShaderModule((VkDevice)device->handle, (VkShaderModule)shader->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&shader, sizeof(PrRhiShader)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&shader, sizeof(PrRhiShader));
} }
// ============================================================================ // ============================================================================
@@ -1326,8 +1320,7 @@ void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader, WpAllocator
// ============================================================================ // ============================================================================
PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device, PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
PrRhiPipelineLayoutDesc desc, PrRhiPipelineLayoutDesc desc) {
WpAllocator *allocator) {
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
// Gather descriptor set layouts // Gather descriptor set layouts
@@ -1337,7 +1330,7 @@ PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
VkDescriptorSetLayout *vk_layouts = vk_layouts_stack; VkDescriptorSetLayout *vk_layouts = vk_layouts_stack;
if (layout_count > 8) { if (layout_count > 8) {
vk_layouts = wpArrayAllocCapacity(VkDescriptorSetLayout, allocator, layout_count, WP_ARRAY_INIT_NONE); vk_layouts = wpArrayAllocCapacity(VkDescriptorSetLayout, &_G_RHI_CONTEXT.scratch, layout_count, WP_ARRAY_INIT_NONE);
if (!vk_layouts) _abort("alloc failed for VkDescriptorSetLayout array"); if (!vk_layouts) _abort("alloc failed for VkDescriptorSetLayout array");
} }
for (u32 i = 0; i < layout_count; ++i) { for (u32 i = 0; i < layout_count; ++i) {
@@ -1351,7 +1344,7 @@ PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
VkPushConstantRange *pc_ranges = pc_ranges_stack; VkPushConstantRange *pc_ranges = pc_ranges_stack;
if (pc_count > 8) { if (pc_count > 8) {
pc_ranges = wpArrayAllocCapacity(VkPushConstantRange, allocator, pc_count, WP_ARRAY_INIT_NONE); pc_ranges = wpArrayAllocCapacity(VkPushConstantRange, &_G_RHI_CONTEXT.scratch, pc_count, WP_ARRAY_INIT_NONE);
if (!pc_ranges) _abort("alloc failed for VkPushConstantRange array"); if (!pc_ranges) _abort("alloc failed for VkPushConstantRange array");
} }
for (u32 i = 0; i < pc_count; ++i) { for (u32 i = 0; i < pc_count; ++i) {
@@ -1372,23 +1365,22 @@ PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
"vkCreatePipelineLayout"); "vkCreatePipelineLayout");
if (layout_count > 8) { if (layout_count > 8) {
wpArrayDealloc(VkDescriptorSetLayout, allocator, &vk_layouts); wpArrayDealloc(VkDescriptorSetLayout, &_G_RHI_CONTEXT.scratch, &vk_layouts);
} }
if (pc_count > 8) { if (pc_count > 8) {
wpArrayDealloc(VkPushConstantRange, allocator, &pc_ranges); wpArrayDealloc(VkPushConstantRange, &_G_RHI_CONTEXT.scratch, &pc_ranges);
} }
PrRhiPipelineLayout *layout = wpMemAllocatorAlloc(allocator, sizeof(PrRhiPipelineLayout)); PrRhiPipelineLayout *layout = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiPipelineLayout));
if (!layout) _abort("alloc failed for PrRhiPipelineLayout"); if (!layout) _abort("alloc failed for PrRhiPipelineLayout");
layout->handle = vk_layout; layout->handle = vk_layout;
return layout; return layout;
} }
void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device, PrRhiPipelineLayout *layout, void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device, PrRhiPipelineLayout *layout) {
WpAllocator *allocator) {
if (!layout) return; if (!layout) return;
vkDestroyPipelineLayout((VkDevice)device->handle, (VkPipelineLayout)layout->handle, NULL); vkDestroyPipelineLayout((VkDevice)device->handle, (VkPipelineLayout)layout->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&layout, sizeof(PrRhiPipelineLayout)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&layout, sizeof(PrRhiPipelineLayout));
} }
// ============================================================================ // ============================================================================
@@ -1396,8 +1388,7 @@ void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device, PrRhiPipelineLayout *layo
// ============================================================================ // ============================================================================
PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device, PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device,
PrRhiGraphicsPipelineDesc desc, PrRhiGraphicsPipelineDesc desc) {
WpAllocator *allocator) {
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
// Shader stages // Shader stages
@@ -1554,15 +1545,14 @@ PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device,
_checkVk(vkCreateGraphicsPipelines(vk_device, VK_NULL_HANDLE, 1, &pi, NULL, &vk_pipeline), _checkVk(vkCreateGraphicsPipelines(vk_device, VK_NULL_HANDLE, 1, &pi, NULL, &vk_pipeline),
"vkCreateGraphicsPipelines"); "vkCreateGraphicsPipelines");
PrRhiPipeline *pipeline = wpMemAllocatorAlloc(allocator, sizeof(PrRhiPipeline)); PrRhiPipeline *pipeline = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiPipeline));
if (!pipeline) _abort("alloc failed for PrRhiPipeline"); if (!pipeline) _abort("alloc failed for PrRhiPipeline");
pipeline->handle = vk_pipeline; pipeline->handle = vk_pipeline;
return pipeline; return pipeline;
} }
PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device, PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device,
PrRhiComputePipelineDesc desc, PrRhiComputePipelineDesc desc) {
WpAllocator *allocator) {
VkComputePipelineCreateInfo pi = {}; VkComputePipelineCreateInfo pi = {};
pi.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; pi.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
pi.stage = (VkPipelineShaderStageCreateInfo){ pi.stage = (VkPipelineShaderStageCreateInfo){
@@ -1577,16 +1567,16 @@ PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device,
_checkVk(vkCreateComputePipelines((VkDevice)device->handle, VK_NULL_HANDLE, 1, &pi, NULL, &vk_pipeline), _checkVk(vkCreateComputePipelines((VkDevice)device->handle, VK_NULL_HANDLE, 1, &pi, NULL, &vk_pipeline),
"vkCreateComputePipelines"); "vkCreateComputePipelines");
PrRhiPipeline *pipeline = wpMemAllocatorAlloc(allocator, sizeof(PrRhiPipeline)); PrRhiPipeline *pipeline = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiPipeline));
if (!pipeline) _abort("alloc failed for PrRhiPipeline"); if (!pipeline) _abort("alloc failed for PrRhiPipeline");
pipeline->handle = vk_pipeline; pipeline->handle = vk_pipeline;
return pipeline; return pipeline;
} }
void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline, WpAllocator *allocator) { void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline) {
if (!pipeline) return; if (!pipeline) return;
vkDestroyPipeline((VkDevice)device->handle, (VkPipeline)pipeline->handle, NULL); vkDestroyPipeline((VkDevice)device->handle, (VkPipeline)pipeline->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&pipeline, sizeof(PrRhiPipeline)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&pipeline, sizeof(PrRhiPipeline));
} }
// ============================================================================ // ============================================================================
@@ -1594,8 +1584,7 @@ void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline, WpAllo
// ============================================================================ // ============================================================================
PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayoutVk(PrRhiDevice *device, PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayoutVk(PrRhiDevice *device,
PrRhiDescriptorSetLayoutDesc desc, PrRhiDescriptorSetLayoutDesc desc) {
WpAllocator *allocator) {
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
u32 binding_count = (desc.bindings && wpArrayCount(desc.bindings) > 0) u32 binding_count = (desc.bindings && wpArrayCount(desc.bindings) > 0)
@@ -1628,17 +1617,16 @@ PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayoutVk(PrRhiDevice *device,
_checkVk(vkCreateDescriptorSetLayout(vk_device, &info, NULL, &vk_layout), _checkVk(vkCreateDescriptorSetLayout(vk_device, &info, NULL, &vk_layout),
"vkCreateDescriptorSetLayout"); "vkCreateDescriptorSetLayout");
PrRhiDescriptorSetLayout *layout = wpMemAllocatorAlloc(allocator, sizeof(PrRhiDescriptorSetLayout)); PrRhiDescriptorSetLayout *layout = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiDescriptorSetLayout));
if (!layout) _abort("alloc failed for PrRhiDescriptorSetLayout"); if (!layout) _abort("alloc failed for PrRhiDescriptorSetLayout");
layout->handle = vk_layout; layout->handle = vk_layout;
return layout; return layout;
} }
void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device, PrRhiDescriptorSetLayout *layout, void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device, PrRhiDescriptorSetLayout *layout) {
WpAllocator *allocator) {
if (!layout) return; if (!layout) return;
vkDestroyDescriptorSetLayout((VkDevice)device->handle, (VkDescriptorSetLayout)layout->handle, NULL); vkDestroyDescriptorSetLayout((VkDevice)device->handle, (VkDescriptorSetLayout)layout->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&layout, sizeof(PrRhiDescriptorSetLayout)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&layout, sizeof(PrRhiDescriptorSetLayout));
} }
// ============================================================================ // ============================================================================
@@ -1646,8 +1634,7 @@ void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device, PrRhiDescriptorSetLa
// ============================================================================ // ============================================================================
PrRhiDescriptorPool *prRhiCreateDescriptorPoolVk(PrRhiDevice *device, PrRhiDescriptorPool *prRhiCreateDescriptorPoolVk(PrRhiDevice *device,
PrRhiDescriptorPoolDesc desc, PrRhiDescriptorPoolDesc desc) {
WpAllocator *allocator) {
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
u32 pool_size_count = (desc.pool_sizes && wpArrayCount(desc.pool_sizes) > 0) u32 pool_size_count = (desc.pool_sizes && wpArrayCount(desc.pool_sizes) > 0)
@@ -1669,17 +1656,16 @@ PrRhiDescriptorPool *prRhiCreateDescriptorPoolVk(PrRhiDevice *device,
_checkVk(vkCreateDescriptorPool(vk_device, &info, NULL, &vk_pool), _checkVk(vkCreateDescriptorPool(vk_device, &info, NULL, &vk_pool),
"vkCreateDescriptorPool"); "vkCreateDescriptorPool");
PrRhiDescriptorPool *pool = wpMemAllocatorAlloc(allocator, sizeof(PrRhiDescriptorPool)); PrRhiDescriptorPool *pool = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiDescriptorPool));
if (!pool) _abort("alloc failed for PrRhiDescriptorPool"); if (!pool) _abort("alloc failed for PrRhiDescriptorPool");
pool->handle = vk_pool; pool->handle = vk_pool;
return pool; return pool;
} }
void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device, PrRhiDescriptorPool *pool, void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device, PrRhiDescriptorPool *pool) {
WpAllocator *allocator) {
if (!pool) return; if (!pool) return;
vkDestroyDescriptorPool((VkDevice)device->handle, (VkDescriptorPool)pool->handle, NULL); vkDestroyDescriptorPool((VkDevice)device->handle, (VkDescriptorPool)pool->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&pool, sizeof(PrRhiDescriptorPool)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&pool, sizeof(PrRhiDescriptorPool));
} }
// ============================================================================ // ============================================================================
@@ -1689,7 +1675,7 @@ void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device, PrRhiDescriptorPool *pool
PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device,
PrRhiDescriptorPool *pool, PrRhiDescriptorPool *pool,
PrRhiDescriptorSetLayout *layout, PrRhiDescriptorSetLayout *layout,
u32 variable_count, WpAllocator *allocator) { u32 variable_count) {
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
VkDescriptorSetVariableDescriptorCountAllocateInfo var_info = {}; VkDescriptorSetVariableDescriptorCountAllocateInfo var_info = {};
@@ -1710,20 +1696,20 @@ PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device,
_checkVk(vkAllocateDescriptorSets(vk_device, &info, &vk_set), _checkVk(vkAllocateDescriptorSets(vk_device, &info, &vk_set),
"vkAllocateDescriptorSets"); "vkAllocateDescriptorSets");
PrRhiDescriptorSet *set = wpMemAllocatorAlloc(allocator, sizeof(PrRhiDescriptorSet)); PrRhiDescriptorSet *set = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiDescriptorSet));
if (!set) _abort("alloc failed for PrRhiDescriptorSet"); if (!set) _abort("alloc failed for PrRhiDescriptorSet");
set->handle = vk_set; set->handle = vk_set;
return set; return set;
} }
void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool, void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool,
PrRhiDescriptorSet *set, WpAllocator *allocator) { PrRhiDescriptorSet *set) {
if (!set) return; if (!set) return;
VkDevice vk_device = (VkDevice)device->handle; VkDevice vk_device = (VkDevice)device->handle;
VkDescriptorSet vk_set = (VkDescriptorSet)set->handle; VkDescriptorSet vk_set = (VkDescriptorSet)set->handle;
_checkVk(vkFreeDescriptorSets(vk_device, (VkDescriptorPool)pool->handle, 1, &vk_set), _checkVk(vkFreeDescriptorSets(vk_device, (VkDescriptorPool)pool->handle, 1, &vk_set),
"vkFreeDescriptorSets"); "vkFreeDescriptorSets");
wpMemAllocatorFree(allocator, (void**)&set, sizeof(PrRhiDescriptorSet)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&set, sizeof(PrRhiDescriptorSet));
} }
void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes) { void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes) {
@@ -1788,8 +1774,7 @@ void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArra
// Fences // Fences
// ============================================================================ // ============================================================================
PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc, PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc) {
WpAllocator *allocator) {
VkFenceCreateInfo info = {}; VkFenceCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
info.flags = desc.signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0; info.flags = desc.signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
@@ -1798,16 +1783,16 @@ PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc,
_checkVk(vkCreateFence((VkDevice)device->handle, &info, NULL, &vk_fence), _checkVk(vkCreateFence((VkDevice)device->handle, &info, NULL, &vk_fence),
"vkCreateFence"); "vkCreateFence");
PrRhiFence *fence = wpMemAllocatorAlloc(allocator, sizeof(PrRhiFence)); PrRhiFence *fence = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiFence));
if (!fence) _abort("alloc failed for PrRhiFence"); if (!fence) _abort("alloc failed for PrRhiFence");
fence->handle = vk_fence; fence->handle = vk_fence;
return fence; return fence;
} }
void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *allocator) { void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence) {
if (!fence) return; if (!fence) return;
vkDestroyFence((VkDevice)device->handle, (VkFence)fence->handle, NULL); vkDestroyFence((VkDevice)device->handle, (VkFence)fence->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&fence, sizeof(PrRhiFence)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&fence, sizeof(PrRhiFence));
} }
void prRhiWaitForFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count, void prRhiWaitForFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count,
@@ -1836,7 +1821,7 @@ void prRhiResetFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count)
// Semaphores // Semaphores
// ============================================================================ // ============================================================================
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device, WpAllocator *allocator) { PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device) {
VkSemaphoreCreateInfo info = {}; VkSemaphoreCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@@ -1844,24 +1829,23 @@ PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device, WpAllocator *allocat
_checkVk(vkCreateSemaphore((VkDevice)device->handle, &info, NULL, &vk_semaphore), _checkVk(vkCreateSemaphore((VkDevice)device->handle, &info, NULL, &vk_semaphore),
"vkCreateSemaphore"); "vkCreateSemaphore");
PrRhiSemaphore *semaphore = wpMemAllocatorAlloc(allocator, sizeof(PrRhiSemaphore)); PrRhiSemaphore *semaphore = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiSemaphore));
if (!semaphore) _abort("alloc failed for PrRhiSemaphore"); if (!semaphore) _abort("alloc failed for PrRhiSemaphore");
semaphore->handle = vk_semaphore; semaphore->handle = vk_semaphore;
return semaphore; return semaphore;
} }
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore, WpAllocator *allocator) { void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore) {
if (!semaphore) return; if (!semaphore) return;
vkDestroySemaphore((VkDevice)device->handle, (VkSemaphore)semaphore->handle, NULL); vkDestroySemaphore((VkDevice)device->handle, (VkSemaphore)semaphore->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&semaphore, sizeof(PrRhiSemaphore)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&semaphore, sizeof(PrRhiSemaphore));
} }
// ============================================================================ // ============================================================================
// Command pools // Command pools
// ============================================================================ // ============================================================================
PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device, PrRhiCommandPoolDesc desc, PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device, PrRhiCommandPoolDesc desc) {
WpAllocator *allocator) {
VkCommandPoolCreateInfo info = {}; VkCommandPoolCreateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
@@ -1871,20 +1855,20 @@ PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool
_checkVk(vkCreateCommandPool((VkDevice)device->handle, &info, NULL, &vk_pool), _checkVk(vkCreateCommandPool((VkDevice)device->handle, &info, NULL, &vk_pool),
"vkCreateCommandPool"); "vkCreateCommandPool");
PrRhiCommandPool *pool = wpMemAllocatorAlloc(allocator, sizeof(PrRhiCommandPool)); PrRhiCommandPool *pool = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiCommandPool));
if (!pool) _abort("alloc failed for PrRhiCommandPool"); if (!pool) _abort("alloc failed for PrRhiCommandPool");
pool->handle = vk_pool; pool->handle = vk_pool;
return pool; return pool;
} }
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool, WpAllocator *allocator) { void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool) {
if (!pool) return; if (!pool) return;
vkDestroyCommandPool((VkDevice)device->handle, (VkCommandPool)pool->handle, NULL); vkDestroyCommandPool((VkDevice)device->handle, (VkCommandPool)pool->handle, NULL);
wpMemAllocatorFree(allocator, (void**)&pool, sizeof(PrRhiCommandPool)); wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&pool, sizeof(PrRhiCommandPool));
} }
PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool, PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
u32 count, WpAllocator *allocator) { u32 count) {
VkCommandBufferAllocateInfo info = {}; VkCommandBufferAllocateInfo info = {};
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
info.commandPool = (VkCommandPool)pool->handle; info.commandPool = (VkCommandPool)pool->handle;
@@ -1894,7 +1878,7 @@ PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhi
VkCommandBuffer vk_cbs[16] = {0}; VkCommandBuffer vk_cbs[16] = {0};
u32 real_count = count < 16 ? count : 16; u32 real_count = count < 16 ? count : 16;
VkCommandBufferArray vk_cb_array = wpArrayAllocCapacity(VkCommandBuffer, allocator, real_count, WP_ARRAY_INIT_NONE); VkCommandBufferArray vk_cb_array = wpArrayAllocCapacity(VkCommandBuffer, &_G_RHI_CONTEXT.scratch, real_count, WP_ARRAY_INIT_NONE);
if (!vk_cb_array) _abort("alloc failed for VkCommandBuffer array"); if (!vk_cb_array) _abort("alloc failed for VkCommandBuffer array");
_checkVk(vkAllocateCommandBuffers((VkDevice)device->handle, &info, vk_cbs), _checkVk(vkAllocateCommandBuffers((VkDevice)device->handle, &info, vk_cbs),
@@ -1904,17 +1888,17 @@ PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhi
wpArrayAppendCapped(VkCommandBuffer, vk_cb_array, &vk_cbs[i]); wpArrayAppendCapped(VkCommandBuffer, vk_cb_array, &vk_cbs[i]);
} }
PrRhiCommandBufferArray cbs = wpArrayAllocCapacity(PrRhiCommandBuffer *, allocator, real_count, WP_ARRAY_INIT_NONE); PrRhiCommandBufferArray cbs = wpArrayAllocCapacity(PrRhiCommandBuffer *, &_G_RHI_CONTEXT.main, real_count, WP_ARRAY_INIT_NONE);
if (!cbs) _abort("alloc failed for PrRhiCommandBuffer array"); if (!cbs) _abort("alloc failed for PrRhiCommandBuffer array");
for (u32 i = 0; i < real_count; ++i) { for (u32 i = 0; i < real_count; ++i) {
PrRhiCommandBuffer *cb = (PrRhiCommandBuffer *)wpMemAllocatorAlloc(allocator, sizeof(PrRhiCommandBuffer)); PrRhiCommandBuffer *cb = (PrRhiCommandBuffer *)wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiCommandBuffer));
if (!cb) _abort("alloc failed for PrRhiCommandBuffer"); if (!cb) _abort("alloc failed for PrRhiCommandBuffer");
cb->handle = vk_cb_array[i]; cb->handle = vk_cb_array[i];
wpArrayAppendCapped(PrRhiCommandBuffer *, cbs, &cb); wpArrayAppendCapped(PrRhiCommandBuffer *, cbs, &cb);
} }
wpArrayDealloc(VkCommandBuffer, allocator, &vk_cb_array); wpArrayDealloc(VkCommandBuffer, &_G_RHI_CONTEXT.scratch, &vk_cb_array);
return cbs; return cbs;
} }
@@ -1933,12 +1917,6 @@ void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
} }
vkFreeCommandBuffers(vk_device, vk_pool, real_count, vk_cbs); vkFreeCommandBuffers(vk_device, vk_pool, real_count, vk_cbs);
// Free PrRhiCommandBuffer structs
for (u32 i = 0; i < real_count; ++i) {
// These were allocated from the same allocator
// Since they're in an array, we need root allocator — skip, caller handles
}
} }
// ============================================================================ // ============================================================================
+39 -62
View File
@@ -122,123 +122,100 @@ struct PrRhiSemaphore {
// Function declarations // Function declarations
// ============================================================================ // ============================================================================
PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *allocator); PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc);
void prRhiDestroyInstanceVk(PrRhiInstance *inst, WpAllocator *allocator); void prRhiDestroyInstanceVk(PrRhiInstance *inst);
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst, const WpAllocator *allocator); PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst);
void prRhiGetPhysicalDeviceNameVk(PrRhiPhysicalDevice *pdev, WpStr8 *out); void prRhiGetPhysicalDeviceNameVk(PrRhiPhysicalDevice *pdev, WpStr8 *out);
void prRhiGetPhysicalDeviceDriverInfoVk(PrRhiPhysicalDevice *pdev, WpStr8 *out); void prRhiGetPhysicalDeviceDriverInfoVk(PrRhiPhysicalDevice *pdev, WpStr8 *out);
void prRhiGetPhysicalDevicePropertiesVk(PrRhiPhysicalDevice *pdev, void prRhiGetPhysicalDevicePropertiesVk(PrRhiPhysicalDevice *pdev,
PrRhiPhysicalDeviceProperties *out); PrRhiPhysicalDeviceProperties *out);
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle, PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle);
WpAllocator *allocator); void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface);
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *allocator);
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev, PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev,
PrRhiSurface *surface); PrRhiSurface *surface);
PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface, PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
PrRhiDeviceDesc desc, WpAllocator *allocator); PrRhiDeviceDesc desc);
void prRhiDestroyDeviceVk(PrRhiDevice *device, WpAllocator *allocator); void prRhiDestroyDeviceVk(PrRhiDevice *device);
void prRhiDeviceWaitIdleVk(PrRhiDevice *device); void prRhiDeviceWaitIdleVk(PrRhiDevice *device);
u32 prRhiGetQueueFamilyIndexVk(PrRhiDevice *device); u32 prRhiGetQueueFamilyIndexVk(PrRhiDevice *device);
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc, PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc);
WpAllocator *allocator); void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain);
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
WpAllocator *allocator);
PrRhiSwapchainResult prRhiAcquireNextImageVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, PrRhiSwapchainResult prRhiAcquireNextImageVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
PrRhiSemaphore *signal_semaphore, u32 *out_image_index); PrRhiSemaphore *signal_semaphore, u32 *out_image_index);
PrRhiSwapchainResult prRhiPresentVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, PrRhiSwapchainResult prRhiPresentVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
PrRhiSemaphore *wait_semaphore); PrRhiSemaphore *wait_semaphore);
void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain, void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
u32 width, u32 height, WpAllocator *allocator); u32 width, u32 height);
PrRhiTexture *prRhiGetSwapchainTextureVk(PrRhiSwapchain *swapchain, u32 image_index); PrRhiTexture *prRhiGetSwapchainTextureVk(PrRhiSwapchain *swapchain, u32 image_index);
PrRhiTexture *prRhiGetSwapchainDepthTextureVk(PrRhiSwapchain *swapchain); PrRhiTexture *prRhiGetSwapchainDepthTextureVk(PrRhiSwapchain *swapchain);
PrRhiFormat prRhiGetSwapchainFormatVk(PrRhiSwapchain *swapchain); PrRhiFormat prRhiGetSwapchainFormatVk(PrRhiSwapchain *swapchain);
PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc, PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc);
WpAllocator *allocator); void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer);
void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *allocator);
void *prRhiBufferMapVk(PrRhiDevice *device, PrRhiBuffer *buffer); void *prRhiBufferMapVk(PrRhiDevice *device, PrRhiBuffer *buffer);
void prRhiBufferUnmapVk(PrRhiDevice *device, PrRhiBuffer *buffer); void prRhiBufferUnmapVk(PrRhiDevice *device, PrRhiBuffer *buffer);
PrRhiDeviceAddress prRhiGetBufferDeviceAddressVk(PrRhiDevice *device, PrRhiBuffer *buffer); PrRhiDeviceAddress prRhiGetBufferDeviceAddressVk(PrRhiDevice *device, PrRhiBuffer *buffer);
PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc, PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc);
WpAllocator *allocator);
PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path, PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb, PrRhiCommandPool *pool, PrRhiCommandBuffer *cb);
WpAllocator *allocator); void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture);
void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture,
WpAllocator *allocator);
PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc, PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc);
WpAllocator *allocator); void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler);
void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler,
WpAllocator *allocator);
PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc, PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc);
WpAllocator *allocator); void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader);
void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *allocator);
PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device, PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
PrRhiPipelineLayoutDesc desc, PrRhiPipelineLayoutDesc desc);
WpAllocator *allocator);
void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device, void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device,
PrRhiPipelineLayout *layout, PrRhiPipelineLayout *layout);
WpAllocator *allocator);
PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device, PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device,
PrRhiGraphicsPipelineDesc desc, PrRhiGraphicsPipelineDesc desc);
WpAllocator *allocator);
PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device, PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device,
PrRhiComputePipelineDesc desc, PrRhiComputePipelineDesc desc);
WpAllocator *allocator); void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline);
void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline,
WpAllocator *allocator);
PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayoutVk(PrRhiDevice *device, PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayoutVk(PrRhiDevice *device,
PrRhiDescriptorSetLayoutDesc desc, PrRhiDescriptorSetLayoutDesc desc);
WpAllocator *allocator);
void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device, void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device,
PrRhiDescriptorSetLayout *layout, PrRhiDescriptorSetLayout *layout);
WpAllocator *allocator);
PrRhiDescriptorPool *prRhiCreateDescriptorPoolVk(PrRhiDevice *device, PrRhiDescriptorPool *prRhiCreateDescriptorPoolVk(PrRhiDevice *device,
PrRhiDescriptorPoolDesc desc, PrRhiDescriptorPoolDesc desc);
WpAllocator *allocator);
void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device, void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device,
PrRhiDescriptorPool *pool, PrRhiDescriptorPool *pool);
WpAllocator *allocator);
PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device,
PrRhiDescriptorPool *pool, PrRhiDescriptorPool *pool,
PrRhiDescriptorSetLayout *layout, PrRhiDescriptorSetLayout *layout,
u32 variable_count, WpAllocator *allocator); u32 variable_count);
void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool, void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool,
PrRhiDescriptorSet *set, WpAllocator *allocator); PrRhiDescriptorSet *set);
void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes); void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc, PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc);
WpAllocator *allocator); void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence);
void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *allocator);
void prRhiWaitForFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count, void prRhiWaitForFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count,
b8 wait_all, u64 timeout_ns); b8 wait_all, u64 timeout_ns);
void prRhiResetFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count); void prRhiResetFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count);
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device, WpAllocator *allocator); PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device);
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore, void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore);
WpAllocator *allocator);
PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device,
PrRhiCommandPoolDesc desc, PrRhiCommandPoolDesc desc);
WpAllocator *allocator); void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool);
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool,
WpAllocator *allocator);
PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool, PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
u32 count, WpAllocator *allocator); u32 count);
void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool, void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
u32 count, PrRhiCommandBufferArray buffers); u32 count, PrRhiCommandBufferArray buffers);