Add RHI global context allocator
This commit is contained in:
@@ -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) |
|
||||
@@ -12,7 +12,7 @@ VK_SDK := `echo $VULKAN_SDK`
|
||||
VENDOR_INC := "vendor/include"
|
||||
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"
|
||||
|
||||
# Build KTX from source
|
||||
@@ -40,13 +40,14 @@ build: vendor
|
||||
src/prism/rhi/vulkan/pr_rhi_vk_vma.cpp \
|
||||
-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}} 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 src/wapp/wapp.c -o {{BUILDDIR}}/wapp.o
|
||||
bear -a -- {{CXX}} -g -c -Wno-nullability-completeness -DVK_NO_PROTOTYPES \
|
||||
{{APP_INC}} \
|
||||
src/main.cpp \
|
||||
-o {{BUILDDIR}}/main.o
|
||||
bear -a -- {{CXX}} -g -DVK_NO_PROTOTYPES \
|
||||
bear -a -- {{CXX}} -g {{VK_FLAGS}} \
|
||||
-L{{VK_SDK}}/lib -L{{VENDOR_LIB}} \
|
||||
build/*.o \
|
||||
-lSDL3 -lglm -ltinyobjloader -lktx -lslang -lvulkan \
|
||||
|
||||
+42
-40
@@ -136,6 +136,7 @@ struct AppState {
|
||||
int main() {
|
||||
AppState app = {};
|
||||
WpAllocator arena = wpMemArenaAllocatorInitZero(MiB(128));
|
||||
prRhiInit();
|
||||
|
||||
// {{{ Initialisation
|
||||
check(SDL_Init(SDL_INIT_VIDEO), EXIT_CODE_SDL_INIT_FAILED);
|
||||
@@ -149,11 +150,11 @@ int main() {
|
||||
|
||||
// {{{ Instance creation
|
||||
PrRhiInstanceDesc inst_desc = {};
|
||||
app.inst = prRhiCreateInstance(inst_desc, &arena);
|
||||
app.inst = prRhiCreateInstance(inst_desc);
|
||||
// }}}
|
||||
|
||||
// {{{ Physical device selection
|
||||
PrRhiPhysicalDeviceArray pdevs = prRhiGetPhysicalDevices(app.inst, &arena);
|
||||
PrRhiPhysicalDeviceArray pdevs = prRhiGetPhysicalDevices(app.inst);
|
||||
check(wpArrayCount(pdevs) > 0, EXIT_CODE_NO_PHYSICAL_DEVICES);
|
||||
|
||||
i32 selected = -1;
|
||||
@@ -185,13 +186,13 @@ int main() {
|
||||
// {{{ Surface creation
|
||||
check(SDL_GetWindowSize(app.window, &app.window_size.x, &app.window_size.y),
|
||||
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
|
||||
PrRhiDeviceDesc dev_desc = {};
|
||||
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);
|
||||
// }}}
|
||||
|
||||
@@ -202,7 +203,7 @@ int main() {
|
||||
swap_desc.height = (u32)app.window_size.y;
|
||||
swap_desc.has_depth = true;
|
||||
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);
|
||||
// }}}
|
||||
@@ -251,7 +252,7 @@ int main() {
|
||||
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.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);
|
||||
memcpy(mapped, vertices, app.vertex_buf_size);
|
||||
@@ -270,7 +271,7 @@ int main() {
|
||||
buf_desc.usage = (PrRhiBufferUsage)(PR_RHI_BUFFER_USAGE_STORAGE |
|
||||
PR_RHI_BUFFER_USAGE_SHADER_DEVICE_ADDRESS);
|
||||
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) {
|
||||
PrRhiFenceDesc fd = {};
|
||||
fd.signaled = true;
|
||||
app.fences[i] = prRhiCreateFence(app.device, fd, &arena);
|
||||
app.fences[i] = prRhiCreateFence(app.device, fd);
|
||||
}
|
||||
|
||||
// Image acquired semaphores (per frame)
|
||||
@@ -289,7 +290,7 @@ int main() {
|
||||
AppState::max_frames_in_flight,
|
||||
WP_ARRAY_INIT_FILLED);
|
||||
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)
|
||||
@@ -298,30 +299,30 @@ int main() {
|
||||
swapchain_image_count,
|
||||
WP_ARRAY_INIT_FILLED);
|
||||
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
|
||||
PrRhiCommandPoolDesc pool_desc = {};
|
||||
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,
|
||||
AppState::max_frames_in_flight, &arena);
|
||||
AppState::max_frames_in_flight);
|
||||
// }}}
|
||||
|
||||
// {{{ Texture loading
|
||||
app.textures = wpArrayAllocCapacity(TextureResources, &arena, AppState::texture_count,
|
||||
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];
|
||||
|
||||
for (u32 i = 0; i < AppState::texture_count; ++i) {
|
||||
char buf[2048] = {};
|
||||
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
|
||||
PrRhiSamplerDesc samp_desc = {};
|
||||
@@ -330,7 +331,7 @@ int main() {
|
||||
samp_desc.mipmap_mode = PR_RHI_MIPMAP_MODE_LINEAR;
|
||||
samp_desc.max_anisotropy = 8.0f;
|
||||
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].sampler = sampler;
|
||||
@@ -351,7 +352,7 @@ int main() {
|
||||
|
||||
PrRhiDescriptorSetLayoutDesc layout_desc = {};
|
||||
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
|
||||
PrRhiDescriptorPoolSize pool_size = {};
|
||||
@@ -361,12 +362,12 @@ int main() {
|
||||
PrRhiDescriptorPoolDesc pool_desc2 = {};
|
||||
pool_desc2.max_sets = 1;
|
||||
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)
|
||||
app.desc_set = prRhiAllocateDescriptorSet(app.device, app.desc_pool,
|
||||
app.desc_set_layout,
|
||||
AppState::texture_count, &arena);
|
||||
AppState::texture_count);
|
||||
|
||||
// Write descriptor set
|
||||
PrRhiDescriptorImageInfoArray img_infos = wpArrayAllocCapacity(PrRhiDescriptorImageInfo,
|
||||
@@ -416,7 +417,7 @@ int main() {
|
||||
PrRhiShaderDesc shader_desc = {};
|
||||
shader_desc.spirv_code = spirv->getBufferPointer();
|
||||
shader_desc.spirv_size = spirv->getBufferSize();
|
||||
app.shader = prRhiCreateShader(app.device, shader_desc, &arena);
|
||||
app.shader = prRhiCreateShader(app.device, shader_desc);
|
||||
// }}}
|
||||
|
||||
// {{{ Pipeline layout
|
||||
@@ -430,7 +431,7 @@ int main() {
|
||||
PrRhiPipelineLayoutDesc pl_desc = {};
|
||||
pl_desc.set_layouts = pl_layouts;
|
||||
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
|
||||
@@ -474,7 +475,7 @@ int main() {
|
||||
pipe_desc.dynamic_viewport = true;
|
||||
pipe_desc.dynamic_scissor = true;
|
||||
pipe_desc.layout = app.pipeline_layout;
|
||||
app.pipeline = prRhiCreateGraphicsPipeline(app.device, pipe_desc, &arena);
|
||||
app.pipeline = prRhiCreateGraphicsPipeline(app.device, pipe_desc);
|
||||
// }}}
|
||||
|
||||
// {{{ Render loop
|
||||
@@ -673,7 +674,7 @@ int main() {
|
||||
if (app.update_swapchain) {
|
||||
prRhiDeviceWaitIdle(app.device);
|
||||
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
|
||||
// TODO: proper cleanup — for now, just leak old ones
|
||||
@@ -682,7 +683,7 @@ int main() {
|
||||
app.render_completed_semaphores = wpArrayAllocCapacity(PrRhiSemaphore *, &arena,
|
||||
new_count, WP_ARRAY_INIT_FILLED);
|
||||
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;
|
||||
@@ -697,39 +698,40 @@ int main() {
|
||||
// {{{ Cleanup
|
||||
prRhiDeviceWaitIdle(app.device);
|
||||
|
||||
prRhiDestroyPipeline(app.device, app.pipeline, &arena);
|
||||
prRhiDestroyPipelineLayout(app.device, app.pipeline_layout, &arena);
|
||||
prRhiDestroyShader(app.device, app.shader, &arena);
|
||||
prRhiDestroyDescriptorPool(app.device, app.desc_pool, &arena);
|
||||
prRhiDestroyDescriptorSetLayout(app.device, app.desc_set_layout, &arena);
|
||||
prRhiDestroyPipeline(app.device, app.pipeline);
|
||||
prRhiDestroyPipelineLayout(app.device, app.pipeline_layout);
|
||||
prRhiDestroyShader(app.device, app.shader);
|
||||
prRhiDestroyDescriptorPool(app.device, app.desc_pool);
|
||||
prRhiDestroyDescriptorSetLayout(app.device, app.desc_set_layout);
|
||||
|
||||
for (u32 i = 0; i < AppState::texture_count; ++i) {
|
||||
prRhiDestroySampler(app.device, app.textures[i].sampler, &arena);
|
||||
prRhiDestroyTexture(app.device, app.textures[i].texture, &arena);
|
||||
prRhiDestroySampler(app.device, app.textures[i].sampler);
|
||||
prRhiDestroyTexture(app.device, app.textures[i].texture);
|
||||
}
|
||||
|
||||
prRhiFreeCommandBuffers(app.device, app.cmd_pool, AppState::max_frames_in_flight,
|
||||
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) {
|
||||
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) {
|
||||
prRhiDestroySemaphore(app.device, app.image_acquired_semaphores[i], &arena);
|
||||
prRhiDestroyFence(app.device, app.fences[i], &arena);
|
||||
prRhiDestroyBuffer(app.device, app.shader_data_bufs[i], &arena);
|
||||
prRhiDestroySemaphore(app.device, app.image_acquired_semaphores[i]);
|
||||
prRhiDestroyFence(app.device, app.fences[i]);
|
||||
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);
|
||||
prRhiDestroyDevice(app.device, &arena);
|
||||
prRhiDestroySurface(app.inst, app.surface, &arena);
|
||||
prRhiDestroyInstance(app.inst, &arena);
|
||||
prRhiDestroySwapchain(app.device, app.swapchain);
|
||||
prRhiDestroyDevice(app.device);
|
||||
prRhiDestroySurface(app.inst, app.surface);
|
||||
prRhiDestroyInstance(app.inst);
|
||||
|
||||
SDL_DestroyWindow(app.window);
|
||||
SDL_Quit();
|
||||
|
||||
prRhiDestroy();
|
||||
wpMemArenaAllocatorDestroy(&arena);
|
||||
// }}}
|
||||
|
||||
|
||||
@@ -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
@@ -29,18 +29,23 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
wp_extern PrRhiContext _G_RHI_CONTEXT;
|
||||
|
||||
wp_extern void prRhiInit(void);
|
||||
wp_extern void prRhiDestroy(void);
|
||||
|
||||
// ======================================================================
|
||||
// Instance
|
||||
// ======================================================================
|
||||
|
||||
PrRhiInstance *prRhiCreateInstance(PrRhiInstanceDesc desc, WpAllocator *allocator);
|
||||
void prRhiDestroyInstance(PrRhiInstance *inst, WpAllocator *allocator);
|
||||
PrRhiInstance *prRhiCreateInstance(PrRhiInstanceDesc desc);
|
||||
void prRhiDestroyInstance(PrRhiInstance *inst);
|
||||
|
||||
// ======================================================================
|
||||
// Physical device enumeration
|
||||
// ======================================================================
|
||||
|
||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevices(PrRhiInstance *inst, const WpAllocator *allocator);
|
||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevices(PrRhiInstance *inst);
|
||||
void prRhiGetPhysicalDeviceName(PrRhiPhysicalDevice *pdev, WpStr8 *out);
|
||||
void prRhiGetPhysicalDeviceDriverInfo(PrRhiPhysicalDevice *pdev, WpStr8 *out);
|
||||
void prRhiGetPhysicalDeviceProperties(PrRhiPhysicalDevice *pdev,
|
||||
@@ -50,9 +55,8 @@ void prRhiGetPhysicalDeviceProperties(PrRhiPhysicalDevice *p
|
||||
// Surface (platform-specific)
|
||||
// ======================================================================
|
||||
|
||||
PrRhiSurface *prRhiCreateSurfaceFromWindow(PrRhiInstance *inst, void *window_handle,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroySurface(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *allocator);
|
||||
PrRhiSurface *prRhiCreateSurfaceFromWindow(PrRhiInstance *inst, void *window_handle);
|
||||
void prRhiDestroySurface(PrRhiInstance *inst, PrRhiSurface *surface);
|
||||
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev,
|
||||
PrRhiSurface *surface);
|
||||
|
||||
@@ -61,8 +65,8 @@ PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev,
|
||||
// ======================================================================
|
||||
|
||||
PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
|
||||
PrRhiDeviceDesc desc, WpAllocator *allocator);
|
||||
void prRhiDestroyDevice(PrRhiDevice *device, WpAllocator *allocator);
|
||||
PrRhiDeviceDesc desc);
|
||||
void prRhiDestroyDevice(PrRhiDevice *device);
|
||||
void prRhiDeviceWaitIdle(PrRhiDevice *device);
|
||||
u32 prRhiGetQueueFamilyIndex(PrRhiDevice *device);
|
||||
|
||||
@@ -70,10 +74,8 @@ u32 prRhiGetQueueFamilyIndex(PrRhiDevice *device);
|
||||
// Swapchain
|
||||
// ======================================================================
|
||||
|
||||
PrRhiSwapchain *prRhiCreateSwapchain(PrRhiDevice *device, PrRhiSwapchainDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroySwapchain(PrRhiDevice *device, PrRhiSwapchain *swapchain,
|
||||
WpAllocator *allocator);
|
||||
PrRhiSwapchain *prRhiCreateSwapchain(PrRhiDevice *device, PrRhiSwapchainDesc desc);
|
||||
void prRhiDestroySwapchain(PrRhiDevice *device, PrRhiSwapchain *swapchain);
|
||||
|
||||
PrRhiSwapchainResult prRhiAcquireNextImage(PrRhiDevice *device, PrRhiSwapchain *swapchain,
|
||||
PrRhiSemaphore *signal_semaphore, u32 *out_image_index);
|
||||
@@ -82,7 +84,7 @@ PrRhiSwapchainResult prRhiPresent(PrRhiDevice *device, PrRhiSwapchain *swapchain
|
||||
PrRhiSemaphore *wait_semaphore);
|
||||
|
||||
void prRhiRecreateSwapchain(PrRhiDevice *device, PrRhiSwapchain **swapchain,
|
||||
u32 width, u32 height, WpAllocator *allocator);
|
||||
u32 width, u32 height);
|
||||
|
||||
PrRhiTexture *prRhiGetSwapchainTexture(PrRhiSwapchain *swapchain, u32 image_index);
|
||||
PrRhiTexture *prRhiGetSwapchainDepthTexture(PrRhiSwapchain *swapchain);
|
||||
@@ -92,9 +94,8 @@ PrRhiFormat prRhiGetSwapchainFormat(PrRhiSwapchain *swapchain);
|
||||
// Buffers
|
||||
// ======================================================================
|
||||
|
||||
PrRhiBuffer *prRhiCreateBuffer(PrRhiDevice *device, PrRhiBufferDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyBuffer(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *allocator);
|
||||
PrRhiBuffer *prRhiCreateBuffer(PrRhiDevice *device, PrRhiBufferDesc desc);
|
||||
void prRhiDestroyBuffer(PrRhiDevice *device, PrRhiBuffer *buffer);
|
||||
|
||||
void *prRhiBufferMap(PrRhiDevice *device, PrRhiBuffer *buffer);
|
||||
void prRhiBufferUnmap(PrRhiDevice *device, PrRhiBuffer *buffer);
|
||||
@@ -105,115 +106,96 @@ PrRhiDeviceAddress prRhiGetBufferDeviceAddress(PrRhiDevice *device, PrRhiBuffer
|
||||
// Textures
|
||||
// ======================================================================
|
||||
|
||||
PrRhiTexture *prRhiCreateTexture(PrRhiDevice *device, PrRhiTextureDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiTexture *prRhiCreateTexture(PrRhiDevice *device, PrRhiTextureDesc desc);
|
||||
PrRhiTexture *prRhiCreateTextureFromKtx(PrRhiDevice *device, const char *path,
|
||||
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyTexture(PrRhiDevice *device, PrRhiTexture *texture,
|
||||
WpAllocator *allocator);
|
||||
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb);
|
||||
void prRhiDestroyTexture(PrRhiDevice *device, PrRhiTexture *texture);
|
||||
|
||||
// ======================================================================
|
||||
// Samplers
|
||||
// ======================================================================
|
||||
|
||||
PrRhiSampler *prRhiCreateSampler(PrRhiDevice *device, PrRhiSamplerDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroySampler(PrRhiDevice *device, PrRhiSampler *sampler,
|
||||
WpAllocator *allocator);
|
||||
PrRhiSampler *prRhiCreateSampler(PrRhiDevice *device, PrRhiSamplerDesc desc);
|
||||
void prRhiDestroySampler(PrRhiDevice *device, PrRhiSampler *sampler);
|
||||
|
||||
// ======================================================================
|
||||
// Shaders (from SPIR-V)
|
||||
// ======================================================================
|
||||
|
||||
PrRhiShader *prRhiCreateShader(PrRhiDevice *device, PrRhiShaderDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyShader(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *allocator);
|
||||
PrRhiShader *prRhiCreateShader(PrRhiDevice *device, PrRhiShaderDesc desc);
|
||||
void prRhiDestroyShader(PrRhiDevice *device, PrRhiShader *shader);
|
||||
|
||||
// ======================================================================
|
||||
// Pipeline layouts
|
||||
// ======================================================================
|
||||
|
||||
PrRhiPipelineLayout *prRhiCreatePipelineLayout(PrRhiDevice *device,
|
||||
PrRhiPipelineLayoutDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiPipelineLayoutDesc desc);
|
||||
void prRhiDestroyPipelineLayout(PrRhiDevice *device,
|
||||
PrRhiPipelineLayout *layout,
|
||||
WpAllocator *allocator);
|
||||
PrRhiPipelineLayout *layout);
|
||||
|
||||
// ======================================================================
|
||||
// Pipelines
|
||||
// ======================================================================
|
||||
|
||||
PrRhiPipeline *prRhiCreateGraphicsPipeline(PrRhiDevice *device,
|
||||
PrRhiGraphicsPipelineDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiGraphicsPipelineDesc desc);
|
||||
PrRhiPipeline *prRhiCreateComputePipeline(PrRhiDevice *device,
|
||||
PrRhiComputePipelineDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyPipeline(PrRhiDevice *device, PrRhiPipeline *pipeline,
|
||||
WpAllocator *allocator);
|
||||
PrRhiComputePipelineDesc desc);
|
||||
void prRhiDestroyPipeline(PrRhiDevice *device, PrRhiPipeline *pipeline);
|
||||
|
||||
// ======================================================================
|
||||
// Descriptor set layouts
|
||||
// ======================================================================
|
||||
|
||||
PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayout(PrRhiDevice *device,
|
||||
PrRhiDescriptorSetLayoutDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorSetLayoutDesc desc);
|
||||
void prRhiDestroyDescriptorSetLayout(PrRhiDevice *device,
|
||||
PrRhiDescriptorSetLayout *layout,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorSetLayout *layout);
|
||||
|
||||
// ======================================================================
|
||||
// Descriptor pools
|
||||
// ======================================================================
|
||||
|
||||
PrRhiDescriptorPool *prRhiCreateDescriptorPool(PrRhiDevice *device,
|
||||
PrRhiDescriptorPoolDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorPoolDesc desc);
|
||||
void prRhiDestroyDescriptorPool(PrRhiDevice *device,
|
||||
PrRhiDescriptorPool *pool,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorPool *pool);
|
||||
|
||||
// ======================================================================
|
||||
// Descriptor sets
|
||||
// ======================================================================
|
||||
|
||||
PrRhiDescriptorSet *prRhiAllocateDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||
PrRhiDescriptorSetLayout *layout,
|
||||
u32 variable_count, WpAllocator *allocator);
|
||||
PrRhiDescriptorSetLayout *layout,
|
||||
u32 variable_count);
|
||||
void prRhiFreeDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||
PrRhiDescriptorSet *set, WpAllocator *allocator);
|
||||
PrRhiDescriptorSet *set);
|
||||
void prRhiUpdateDescriptorSet(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
|
||||
|
||||
// ======================================================================
|
||||
// Fences and semaphores
|
||||
// ======================================================================
|
||||
|
||||
PrRhiFence *prRhiCreateFence(PrRhiDevice *device, PrRhiFenceDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyFence(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *allocator);
|
||||
PrRhiFence *prRhiCreateFence(PrRhiDevice *device, PrRhiFenceDesc desc);
|
||||
void prRhiDestroyFence(PrRhiDevice *device, PrRhiFence *fence);
|
||||
|
||||
void prRhiWaitForFences(PrRhiDevice *device, PrRhiFenceArray fences, u32 count,
|
||||
b8 wait_all, u64 timeout_ns);
|
||||
void prRhiResetFences(PrRhiDevice *device, PrRhiFenceArray fences, u32 count);
|
||||
|
||||
PrRhiSemaphore *prRhiCreateSemaphore(PrRhiDevice *device, WpAllocator *allocator);
|
||||
void prRhiDestroySemaphore(PrRhiDevice *device, PrRhiSemaphore *semaphore,
|
||||
WpAllocator *allocator);
|
||||
PrRhiSemaphore *prRhiCreateSemaphore(PrRhiDevice *device);
|
||||
void prRhiDestroySemaphore(PrRhiDevice *device, PrRhiSemaphore *semaphore);
|
||||
|
||||
// ======================================================================
|
||||
// Command pools and command buffers
|
||||
// ======================================================================
|
||||
|
||||
PrRhiCommandPool *prRhiCreateCommandPool(PrRhiDevice *device, PrRhiCommandPoolDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyCommandPool(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||
WpAllocator *allocator);
|
||||
PrRhiCommandPool *prRhiCreateCommandPool(PrRhiDevice *device, PrRhiCommandPoolDesc desc);
|
||||
void prRhiDestroyCommandPool(PrRhiDevice *device, PrRhiCommandPool *pool);
|
||||
|
||||
PrRhiCommandBufferArray prRhiAllocateCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||
u32 count, WpAllocator *allocator);
|
||||
u32 count);
|
||||
void prRhiFreeCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||
u32 count, PrRhiCommandBufferArray buffers);
|
||||
|
||||
|
||||
@@ -438,6 +438,15 @@ typedef struct PrRhiPhysicalDeviceProperties {
|
||||
|
||||
typedef u64 PrRhiDeviceAddress;
|
||||
|
||||
// ============================================================================
|
||||
// RHI context (global, owns all RHI object lifetimes)
|
||||
// ============================================================================
|
||||
|
||||
typedef struct PrRhiContext {
|
||||
WpAllocator main;
|
||||
WpAllocator scratch;
|
||||
} PrRhiContext;
|
||||
|
||||
// --- Command buffer types ---
|
||||
|
||||
typedef struct PrRhiDepthAttachment {
|
||||
|
||||
+108
-130
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "pr_rhi_vk.h"
|
||||
#include "profiles/vulkan_profiles.h"
|
||||
#include "../pr_rhi.h"
|
||||
#include <volk/volk.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <SDL3/SDL_vulkan.h>
|
||||
@@ -312,7 +313,7 @@ VkPhysicalDeviceType _toVkPhysicalDeviceType(PrRhiPhysicalDeviceType type) {
|
||||
// Instance
|
||||
// ============================================================================
|
||||
|
||||
PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *allocator) {
|
||||
PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc) {
|
||||
_checkVk(volkInitialize(), "volkInitialize");
|
||||
|
||||
VkBool32 supported = VK_FALSE;
|
||||
@@ -347,7 +348,7 @@ PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *alloca
|
||||
|
||||
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"); }
|
||||
inst->handle = vk_instance;
|
||||
inst->debug_messenger = NULL;
|
||||
@@ -355,34 +356,34 @@ PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *alloca
|
||||
return inst;
|
||||
}
|
||||
|
||||
void prRhiDestroyInstanceVk(PrRhiInstance *inst, WpAllocator *allocator) {
|
||||
void prRhiDestroyInstanceVk(PrRhiInstance *inst) {
|
||||
if (!inst) { return; }
|
||||
vkDestroyInstance((VkInstance)inst->handle, NULL);
|
||||
wpMemAllocatorFree(allocator, (void**)&inst, sizeof(PrRhiInstance));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&inst, sizeof(PrRhiInstance));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Physical device enumeration
|
||||
// ============================================================================
|
||||
|
||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst, const WpAllocator *allocator) {
|
||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst) {
|
||||
VkInstance vk_inst = (VkInstance)inst->handle;
|
||||
|
||||
u32 count = 0;
|
||||
_checkVk(vkEnumeratePhysicalDevices(vk_inst, &count, NULL), "vkEnumeratePhysicalDevices");
|
||||
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");
|
||||
|
||||
_checkVk(vkEnumeratePhysicalDevices(vk_inst, &count, vk_devices), "vkEnumeratePhysicalDevices");
|
||||
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");
|
||||
|
||||
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");
|
||||
pdev->handle = vk_devices[i];
|
||||
pdev->instance = inst;
|
||||
@@ -424,8 +425,7 @@ void prRhiGetPhysicalDevicePropertiesVk(PrRhiPhysicalDevice *pdev,
|
||||
// Surface
|
||||
// ============================================================================
|
||||
|
||||
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle) {
|
||||
SDL_Window *window = (SDL_Window *)window_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))
|
||||
_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");
|
||||
surface->handle = (void *)vk_surface;
|
||||
return surface;
|
||||
}
|
||||
|
||||
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *allocator) {
|
||||
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface) {
|
||||
if (!surface) return;
|
||||
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) {
|
||||
@@ -469,7 +469,7 @@ PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev
|
||||
// ============================================================================
|
||||
|
||||
PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
|
||||
PrRhiDeviceDesc desc, WpAllocator *allocator) {
|
||||
PrRhiDeviceDesc desc) {
|
||||
VkInstance vk_inst = (VkInstance)pdev->instance->handle;
|
||||
VkPhysicalDevice vk_pdev = (VkPhysicalDevice)pdev->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");
|
||||
|
||||
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");
|
||||
|
||||
for (u32 i = 0; i < queue_family_count; ++i) {
|
||||
@@ -505,7 +505,7 @@ PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surfac
|
||||
"vkGetPhysicalDeviceSurfaceSupportKHR");
|
||||
if (!present_supported) _abort("no presentation support");
|
||||
|
||||
wpArrayDealloc(VkQueueFamilyProperties2, allocator, &qf_props);
|
||||
wpArrayDealloc(VkQueueFamilyProperties2, &_G_RHI_CONTEXT.scratch, &qf_props);
|
||||
|
||||
// Check device profile support
|
||||
VkBool32 profile_supported = VK_FALSE;
|
||||
@@ -557,7 +557,7 @@ PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surfac
|
||||
VmaAllocator vma_allocator = VK_NULL_HANDLE;
|
||||
_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");
|
||||
device->handle = vk_device;
|
||||
device->queue = vk_queue;
|
||||
@@ -569,12 +569,12 @@ PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surfac
|
||||
return device;
|
||||
}
|
||||
|
||||
void prRhiDestroyDeviceVk(PrRhiDevice *device, WpAllocator *allocator) {
|
||||
void prRhiDestroyDeviceVk(PrRhiDevice *device) {
|
||||
if (!device) return;
|
||||
vkDeviceWaitIdle((VkDevice)device->handle);
|
||||
vmaDestroyAllocator((VmaAllocator)device->allocator);
|
||||
vkDestroyDevice((VkDevice)device->handle, NULL);
|
||||
wpMemAllocatorFree(allocator, (void**)&device, sizeof(PrRhiDevice));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&device, sizeof(PrRhiDevice));
|
||||
}
|
||||
|
||||
void prRhiDeviceWaitIdleVk(PrRhiDevice *device) {
|
||||
@@ -590,9 +590,9 @@ u32 prRhiGetQueueFamilyIndexVk(PrRhiDevice *device) {
|
||||
// ============================================================================
|
||||
|
||||
static PrRhiTexture *_createSwapchainTexture(PrRhiDevice *device, VkImage vk_image,
|
||||
VkFormat vk_format, u32 width, u32 height,
|
||||
VkImageView vk_view, WpAllocator *allocator) {
|
||||
PrRhiTexture *tex = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture));
|
||||
VkFormat vk_format, u32 width, u32 height,
|
||||
VkImageView vk_view) {
|
||||
PrRhiTexture *tex = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
|
||||
if (!tex) _abort("alloc failed for swapchain texture");
|
||||
tex->image = vk_image;
|
||||
tex->view = vk_view;
|
||||
@@ -615,8 +615,7 @@ static VkFormat _pickDepthFormat(VkPhysicalDevice vk_pdev) {
|
||||
return VK_FORMAT_UNDEFINED;
|
||||
}
|
||||
|
||||
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc) {
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
VkPhysicalDevice vk_pdev = (VkPhysicalDevice)device->physical_device;
|
||||
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),
|
||||
"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");
|
||||
_checkVk(vkGetSwapchainImagesKHR(vk_device, vk_swapchain, &image_count, vk_images),
|
||||
"vkGetSwapchainImagesKHR");
|
||||
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");
|
||||
|
||||
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");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
swapchain->device = device;
|
||||
swapchain->handle = vk_swapchain;
|
||||
@@ -741,7 +740,7 @@ PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc d
|
||||
VkImageView depth_view = VK_NULL_HANDLE;
|
||||
_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");
|
||||
depth_tex->image = depth_image;
|
||||
depth_tex->view = depth_view;
|
||||
@@ -757,7 +756,7 @@ PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc d
|
||||
return swapchain;
|
||||
}
|
||||
|
||||
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, WpAllocator *allocator) {
|
||||
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain) {
|
||||
if (!swapchain) return;
|
||||
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
@@ -767,9 +766,9 @@ void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, WpA
|
||||
PrRhiTexture *tex = swapchain->images[i];
|
||||
vkDestroyImageView(vk_device, (VkImageView)tex->view, NULL);
|
||||
// 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
|
||||
if (swapchain->depth) {
|
||||
@@ -777,11 +776,11 @@ void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, WpA
|
||||
vkDestroyImageView(vk_device, (VkImageView)depth->view, NULL);
|
||||
vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)depth->image,
|
||||
(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);
|
||||
wpMemAllocatorFree(allocator, (void**)&swapchain, sizeof(PrRhiSwapchain));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&swapchain, sizeof(PrRhiSwapchain));
|
||||
}
|
||||
|
||||
PrRhiSwapchainResult prRhiAcquireNextImageVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
|
||||
@@ -816,7 +815,7 @@ PrRhiSwapchainResult prRhiPresentVk(PrRhiDevice *device, PrRhiSwapchain *swapcha
|
||||
}
|
||||
|
||||
void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
|
||||
u32 width, u32 height, WpAllocator *allocator) {
|
||||
u32 width, u32 height) {
|
||||
PrRhiSwapchain *old = *swapchain;
|
||||
if (!old) return;
|
||||
|
||||
@@ -847,9 +846,9 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
|
||||
for (u32 i = 0; i < old->image_count; ++i) {
|
||||
PrRhiTexture *tex = old->images[i];
|
||||
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
|
||||
if (old->depth) {
|
||||
@@ -857,7 +856,7 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
|
||||
vkDestroyImageView(vk_device, (VkImageView)depth->view, NULL);
|
||||
vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)depth->image,
|
||||
(VmaAllocation)depth->allocation);
|
||||
wpMemAllocatorFree(allocator, (void**)&depth, sizeof(PrRhiTexture));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&depth, sizeof(PrRhiTexture));
|
||||
}
|
||||
|
||||
// Destroy old swapchain
|
||||
@@ -868,13 +867,13 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
|
||||
_checkVk(vkGetSwapchainImagesKHR(vk_device, vk_new_swapchain, &new_image_count, NULL),
|
||||
"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)");
|
||||
_checkVk(vkGetSwapchainImagesKHR(vk_device, vk_new_swapchain, &new_image_count, vk_images),
|
||||
"vkGetSwapchainImagesKHR (recreate)");
|
||||
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)");
|
||||
|
||||
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)");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
wpArrayDealloc(VkImage, allocator, &vk_images);
|
||||
wpArrayDealloc(VkImage, &_G_RHI_CONTEXT.scratch, &vk_images);
|
||||
|
||||
// Recreate depth
|
||||
PrRhiTexture *new_depth = NULL;
|
||||
@@ -939,7 +938,7 @@ void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
|
||||
VkImageView depth_view = VK_NULL_HANDLE;
|
||||
_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)");
|
||||
new_depth->image = depth_image;
|
||||
new_depth->view = depth_view;
|
||||
@@ -979,8 +978,7 @@ PrRhiFormat prRhiGetSwapchainFormatVk(PrRhiSwapchain *swapchain) {
|
||||
// Buffers
|
||||
// ============================================================================
|
||||
|
||||
PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc) {
|
||||
VkBufferCreateInfo buf_info = {};
|
||||
buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||
buf_info.size = desc.size;
|
||||
@@ -1005,7 +1003,7 @@ PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc,
|
||||
&vk_buffer, &vma_alloc, &vma_alloc_info),
|
||||
"vmaCreateBuffer");
|
||||
|
||||
PrRhiBuffer *buffer = wpMemAllocatorAlloc(allocator, sizeof(PrRhiBuffer));
|
||||
PrRhiBuffer *buffer = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiBuffer));
|
||||
if (!buffer) _abort("alloc failed for PrRhiBuffer");
|
||||
buffer->handle = vk_buffer;
|
||||
buffer->allocation = vma_alloc;
|
||||
@@ -1024,11 +1022,11 @@ PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc,
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *allocator) {
|
||||
void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer) {
|
||||
if (!buffer) return;
|
||||
vmaDestroyBuffer((VmaAllocator)device->allocator, (VkBuffer)buffer->handle,
|
||||
(VmaAllocation)buffer->allocation);
|
||||
wpMemAllocatorFree(allocator, (void**)&buffer, sizeof(PrRhiBuffer));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&buffer, sizeof(PrRhiBuffer));
|
||||
}
|
||||
|
||||
void *prRhiBufferMapVk(PrRhiDevice *device, PrRhiBuffer *buffer) {
|
||||
@@ -1051,8 +1049,7 @@ PrRhiDeviceAddress prRhiGetBufferDeviceAddressVk(PrRhiDevice *device, PrRhiBuffe
|
||||
// Textures
|
||||
// ============================================================================
|
||||
|
||||
PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc) {
|
||||
VkImageCreateInfo img_info = {};
|
||||
img_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||
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),
|
||||
"vkCreateImageView");
|
||||
|
||||
PrRhiTexture *texture = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture));
|
||||
PrRhiTexture *texture = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
|
||||
if (!texture) _abort("alloc failed for PrRhiTexture");
|
||||
texture->image = vk_image;
|
||||
texture->view = vk_view;
|
||||
@@ -1107,8 +1104,7 @@ PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc,
|
||||
}
|
||||
|
||||
PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
|
||||
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb) {
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
|
||||
ktxTexture *ktx = NULL;
|
||||
@@ -1129,7 +1125,7 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
|
||||
.usage = PR_RHI_BUFFER_USAGE_TRANSFER_SRC,
|
||||
.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);
|
||||
|
||||
// Create the destination image
|
||||
@@ -1210,10 +1206,10 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
|
||||
|
||||
// Submit and wait
|
||||
PrRhiFenceDesc fence_desc = { .signaled = false };
|
||||
PrRhiFence *fence = prRhiCreateFenceVk(device, fence_desc, allocator);
|
||||
PrRhiFence *fence = prRhiCreateFenceVk(device, fence_desc);
|
||||
prRhiQueueSubmitVk(device, cb, NULL, NULL, fence);
|
||||
prRhiWaitForFencesVk(device, &(PrRhiFence *){ fence }, 1, VK_TRUE, UINT64_MAX);
|
||||
prRhiDestroyFenceVk(device, fence, allocator);
|
||||
prRhiDestroyFenceVk(device, fence);
|
||||
vkResetCommandBuffer(vk_cb, 0);
|
||||
|
||||
// Create image view
|
||||
@@ -1230,7 +1226,7 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
|
||||
_checkVk(vkCreateImageView(vk_device, &view_info, NULL, &vk_view),
|
||||
"vkCreateImageView");
|
||||
|
||||
PrRhiTexture *texture = wpMemAllocatorAlloc(allocator, sizeof(PrRhiTexture));
|
||||
PrRhiTexture *texture = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiTexture));
|
||||
if (!texture) _abort("alloc failed for PrRhiTexture");
|
||||
texture->image = vk_image;
|
||||
texture->view = vk_view;
|
||||
@@ -1240,13 +1236,13 @@ PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
|
||||
texture->format = vk_format;
|
||||
|
||||
// Cleanup staging
|
||||
prRhiDestroyBufferVk(device, staging, allocator);
|
||||
prRhiDestroyBufferVk(device, staging);
|
||||
ktxTexture_Destroy(ktx);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture, WpAllocator *allocator) {
|
||||
void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture) {
|
||||
if (!texture) return;
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
|
||||
@@ -1255,15 +1251,14 @@ void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture, WpAllocat
|
||||
vmaDestroyImage((VmaAllocator)device->allocator, (VkImage)texture->image,
|
||||
(VmaAllocation)texture->allocation);
|
||||
}
|
||||
wpMemAllocatorFree(allocator, (void**)&texture, sizeof(PrRhiTexture));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&texture, sizeof(PrRhiTexture));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Samplers
|
||||
// ============================================================================
|
||||
|
||||
PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc) {
|
||||
VkSamplerCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||
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),
|
||||
"vkCreateSampler");
|
||||
|
||||
PrRhiSampler *sampler = wpMemAllocatorAlloc(allocator, sizeof(PrRhiSampler));
|
||||
PrRhiSampler *sampler = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiSampler));
|
||||
if (!sampler) _abort("alloc failed for PrRhiSampler");
|
||||
sampler->handle = vk_sampler;
|
||||
return sampler;
|
||||
}
|
||||
|
||||
void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler, WpAllocator *allocator) {
|
||||
void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler) {
|
||||
if (!sampler) return;
|
||||
vkDestroySampler((VkDevice)device->handle, (VkSampler)sampler->handle, NULL);
|
||||
wpMemAllocatorFree(allocator, (void**)&sampler, sizeof(PrRhiSampler));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&sampler, sizeof(PrRhiSampler));
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Shaders
|
||||
// ============================================================================
|
||||
|
||||
PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc) {
|
||||
VkShaderModuleCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
info.codeSize = desc.spirv_size;
|
||||
@@ -1309,16 +1303,16 @@ PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc,
|
||||
_checkVk(vkCreateShaderModule((VkDevice)device->handle, &info, NULL, &vk_module),
|
||||
"vkCreateShaderModule");
|
||||
|
||||
PrRhiShader *shader = wpMemAllocatorAlloc(allocator, sizeof(PrRhiShader));
|
||||
PrRhiShader *shader = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiShader));
|
||||
if (!shader) _abort("alloc failed for PrRhiShader");
|
||||
shader->handle = vk_module;
|
||||
return shader;
|
||||
}
|
||||
|
||||
void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *allocator) {
|
||||
void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader) {
|
||||
if (!shader) return;
|
||||
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,
|
||||
PrRhiPipelineLayoutDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiPipelineLayoutDesc desc) {
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
|
||||
// Gather descriptor set layouts
|
||||
@@ -1337,7 +1330,7 @@ PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
|
||||
VkDescriptorSetLayout *vk_layouts = vk_layouts_stack;
|
||||
|
||||
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");
|
||||
}
|
||||
for (u32 i = 0; i < layout_count; ++i) {
|
||||
@@ -1351,7 +1344,7 @@ PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
|
||||
VkPushConstantRange *pc_ranges = pc_ranges_stack;
|
||||
|
||||
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");
|
||||
}
|
||||
for (u32 i = 0; i < pc_count; ++i) {
|
||||
@@ -1372,23 +1365,22 @@ PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
|
||||
"vkCreatePipelineLayout");
|
||||
|
||||
if (layout_count > 8) {
|
||||
wpArrayDealloc(VkDescriptorSetLayout, allocator, &vk_layouts);
|
||||
wpArrayDealloc(VkDescriptorSetLayout, &_G_RHI_CONTEXT.scratch, &vk_layouts);
|
||||
}
|
||||
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");
|
||||
layout->handle = vk_layout;
|
||||
return layout;
|
||||
}
|
||||
|
||||
void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device, PrRhiPipelineLayout *layout,
|
||||
WpAllocator *allocator) {
|
||||
void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device, PrRhiPipelineLayout *layout) {
|
||||
if (!layout) return;
|
||||
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,
|
||||
PrRhiGraphicsPipelineDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiGraphicsPipelineDesc desc) {
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
|
||||
// Shader stages
|
||||
@@ -1554,15 +1545,14 @@ PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device,
|
||||
_checkVk(vkCreateGraphicsPipelines(vk_device, VK_NULL_HANDLE, 1, &pi, NULL, &vk_pipeline),
|
||||
"vkCreateGraphicsPipelines");
|
||||
|
||||
PrRhiPipeline *pipeline = wpMemAllocatorAlloc(allocator, sizeof(PrRhiPipeline));
|
||||
PrRhiPipeline *pipeline = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiPipeline));
|
||||
if (!pipeline) _abort("alloc failed for PrRhiPipeline");
|
||||
pipeline->handle = vk_pipeline;
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device,
|
||||
PrRhiComputePipelineDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiComputePipelineDesc desc) {
|
||||
VkComputePipelineCreateInfo pi = {};
|
||||
pi.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
|
||||
pi.stage = (VkPipelineShaderStageCreateInfo){
|
||||
@@ -1577,16 +1567,16 @@ PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device,
|
||||
_checkVk(vkCreateComputePipelines((VkDevice)device->handle, VK_NULL_HANDLE, 1, &pi, NULL, &vk_pipeline),
|
||||
"vkCreateComputePipelines");
|
||||
|
||||
PrRhiPipeline *pipeline = wpMemAllocatorAlloc(allocator, sizeof(PrRhiPipeline));
|
||||
PrRhiPipeline *pipeline = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiPipeline));
|
||||
if (!pipeline) _abort("alloc failed for PrRhiPipeline");
|
||||
pipeline->handle = vk_pipeline;
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline, WpAllocator *allocator) {
|
||||
void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline) {
|
||||
if (!pipeline) return;
|
||||
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,
|
||||
PrRhiDescriptorSetLayoutDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiDescriptorSetLayoutDesc desc) {
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
|
||||
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),
|
||||
"vkCreateDescriptorSetLayout");
|
||||
|
||||
PrRhiDescriptorSetLayout *layout = wpMemAllocatorAlloc(allocator, sizeof(PrRhiDescriptorSetLayout));
|
||||
PrRhiDescriptorSetLayout *layout = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiDescriptorSetLayout));
|
||||
if (!layout) _abort("alloc failed for PrRhiDescriptorSetLayout");
|
||||
layout->handle = vk_layout;
|
||||
return layout;
|
||||
}
|
||||
|
||||
void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device, PrRhiDescriptorSetLayout *layout,
|
||||
WpAllocator *allocator) {
|
||||
void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device, PrRhiDescriptorSetLayout *layout) {
|
||||
if (!layout) return;
|
||||
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,
|
||||
PrRhiDescriptorPoolDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiDescriptorPoolDesc desc) {
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
|
||||
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),
|
||||
"vkCreateDescriptorPool");
|
||||
|
||||
PrRhiDescriptorPool *pool = wpMemAllocatorAlloc(allocator, sizeof(PrRhiDescriptorPool));
|
||||
PrRhiDescriptorPool *pool = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiDescriptorPool));
|
||||
if (!pool) _abort("alloc failed for PrRhiDescriptorPool");
|
||||
pool->handle = vk_pool;
|
||||
return pool;
|
||||
}
|
||||
|
||||
void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||
WpAllocator *allocator) {
|
||||
void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device, PrRhiDescriptorPool *pool) {
|
||||
if (!pool) return;
|
||||
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,
|
||||
PrRhiDescriptorPool *pool,
|
||||
PrRhiDescriptorSetLayout *layout,
|
||||
u32 variable_count, WpAllocator *allocator) {
|
||||
u32 variable_count) {
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
|
||||
VkDescriptorSetVariableDescriptorCountAllocateInfo var_info = {};
|
||||
@@ -1710,20 +1696,20 @@ PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device,
|
||||
_checkVk(vkAllocateDescriptorSets(vk_device, &info, &vk_set),
|
||||
"vkAllocateDescriptorSets");
|
||||
|
||||
PrRhiDescriptorSet *set = wpMemAllocatorAlloc(allocator, sizeof(PrRhiDescriptorSet));
|
||||
PrRhiDescriptorSet *set = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiDescriptorSet));
|
||||
if (!set) _abort("alloc failed for PrRhiDescriptorSet");
|
||||
set->handle = vk_set;
|
||||
return set;
|
||||
}
|
||||
|
||||
void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||
PrRhiDescriptorSet *set, WpAllocator *allocator) {
|
||||
PrRhiDescriptorSet *set) {
|
||||
if (!set) return;
|
||||
VkDevice vk_device = (VkDevice)device->handle;
|
||||
VkDescriptorSet vk_set = (VkDescriptorSet)set->handle;
|
||||
_checkVk(vkFreeDescriptorSets(vk_device, (VkDescriptorPool)pool->handle, 1, &vk_set),
|
||||
"vkFreeDescriptorSets");
|
||||
wpMemAllocatorFree(allocator, (void**)&set, sizeof(PrRhiDescriptorSet));
|
||||
wpMemAllocatorFree(&_G_RHI_CONTEXT.main, (void**)&set, sizeof(PrRhiDescriptorSet));
|
||||
}
|
||||
|
||||
void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes) {
|
||||
@@ -1788,8 +1774,7 @@ void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArra
|
||||
// Fences
|
||||
// ============================================================================
|
||||
|
||||
PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc) {
|
||||
VkFenceCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
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),
|
||||
"vkCreateFence");
|
||||
|
||||
PrRhiFence *fence = wpMemAllocatorAlloc(allocator, sizeof(PrRhiFence));
|
||||
PrRhiFence *fence = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiFence));
|
||||
if (!fence) _abort("alloc failed for PrRhiFence");
|
||||
fence->handle = vk_fence;
|
||||
return fence;
|
||||
}
|
||||
|
||||
void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *allocator) {
|
||||
void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence) {
|
||||
if (!fence) return;
|
||||
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,
|
||||
@@ -1836,7 +1821,7 @@ void prRhiResetFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count)
|
||||
// Semaphores
|
||||
// ============================================================================
|
||||
|
||||
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device, WpAllocator *allocator) {
|
||||
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device) {
|
||||
VkSemaphoreCreateInfo 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),
|
||||
"vkCreateSemaphore");
|
||||
|
||||
PrRhiSemaphore *semaphore = wpMemAllocatorAlloc(allocator, sizeof(PrRhiSemaphore));
|
||||
PrRhiSemaphore *semaphore = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiSemaphore));
|
||||
if (!semaphore) _abort("alloc failed for PrRhiSemaphore");
|
||||
semaphore->handle = vk_semaphore;
|
||||
return semaphore;
|
||||
}
|
||||
|
||||
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore, WpAllocator *allocator) {
|
||||
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore) {
|
||||
if (!semaphore) return;
|
||||
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
|
||||
// ============================================================================
|
||||
|
||||
PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device, PrRhiCommandPoolDesc desc,
|
||||
WpAllocator *allocator) {
|
||||
PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device, PrRhiCommandPoolDesc desc) {
|
||||
VkCommandPoolCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||
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),
|
||||
"vkCreateCommandPool");
|
||||
|
||||
PrRhiCommandPool *pool = wpMemAllocatorAlloc(allocator, sizeof(PrRhiCommandPool));
|
||||
PrRhiCommandPool *pool = wpMemAllocatorAlloc(&_G_RHI_CONTEXT.main, sizeof(PrRhiCommandPool));
|
||||
if (!pool) _abort("alloc failed for PrRhiCommandPool");
|
||||
pool->handle = vk_pool;
|
||||
return pool;
|
||||
}
|
||||
|
||||
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool, WpAllocator *allocator) {
|
||||
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool) {
|
||||
if (!pool) return;
|
||||
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,
|
||||
u32 count, WpAllocator *allocator) {
|
||||
u32 count) {
|
||||
VkCommandBufferAllocateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||
info.commandPool = (VkCommandPool)pool->handle;
|
||||
@@ -1894,7 +1878,7 @@ PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhi
|
||||
VkCommandBuffer vk_cbs[16] = {0};
|
||||
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");
|
||||
|
||||
_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]);
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
cb->handle = vk_cb_array[i];
|
||||
wpArrayAppendCapped(PrRhiCommandBuffer *, cbs, &cb);
|
||||
}
|
||||
|
||||
wpArrayDealloc(VkCommandBuffer, allocator, &vk_cb_array);
|
||||
wpArrayDealloc(VkCommandBuffer, &_G_RHI_CONTEXT.scratch, &vk_cb_array);
|
||||
|
||||
return cbs;
|
||||
}
|
||||
@@ -1933,12 +1917,6 @@ void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -122,123 +122,100 @@ struct PrRhiSemaphore {
|
||||
// Function declarations
|
||||
// ============================================================================
|
||||
|
||||
PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *allocator);
|
||||
void prRhiDestroyInstanceVk(PrRhiInstance *inst, WpAllocator *allocator);
|
||||
PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc);
|
||||
void prRhiDestroyInstanceVk(PrRhiInstance *inst);
|
||||
|
||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst, const WpAllocator *allocator);
|
||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst);
|
||||
void prRhiGetPhysicalDeviceNameVk(PrRhiPhysicalDevice *pdev, WpStr8 *out);
|
||||
void prRhiGetPhysicalDeviceDriverInfoVk(PrRhiPhysicalDevice *pdev, WpStr8 *out);
|
||||
void prRhiGetPhysicalDevicePropertiesVk(PrRhiPhysicalDevice *pdev,
|
||||
PrRhiPhysicalDeviceProperties *out);
|
||||
|
||||
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *allocator);
|
||||
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle);
|
||||
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface);
|
||||
|
||||
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev,
|
||||
PrRhiSurface *surface);
|
||||
|
||||
PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
|
||||
PrRhiDeviceDesc desc, WpAllocator *allocator);
|
||||
void prRhiDestroyDeviceVk(PrRhiDevice *device, WpAllocator *allocator);
|
||||
PrRhiDeviceDesc desc);
|
||||
void prRhiDestroyDeviceVk(PrRhiDevice *device);
|
||||
void prRhiDeviceWaitIdleVk(PrRhiDevice *device);
|
||||
u32 prRhiGetQueueFamilyIndexVk(PrRhiDevice *device);
|
||||
|
||||
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
|
||||
WpAllocator *allocator);
|
||||
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc);
|
||||
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain);
|
||||
PrRhiSwapchainResult prRhiAcquireNextImageVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
|
||||
PrRhiSemaphore *signal_semaphore, u32 *out_image_index);
|
||||
PrRhiSwapchainResult prRhiPresentVk(PrRhiDevice *device, PrRhiSwapchain *swapchain,
|
||||
PrRhiSemaphore *wait_semaphore);
|
||||
void prRhiRecreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchain **swapchain,
|
||||
u32 width, u32 height, WpAllocator *allocator);
|
||||
u32 width, u32 height);
|
||||
PrRhiTexture *prRhiGetSwapchainTextureVk(PrRhiSwapchain *swapchain, u32 image_index);
|
||||
PrRhiTexture *prRhiGetSwapchainDepthTextureVk(PrRhiSwapchain *swapchain);
|
||||
PrRhiFormat prRhiGetSwapchainFormatVk(PrRhiSwapchain *swapchain);
|
||||
|
||||
PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *allocator);
|
||||
PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc);
|
||||
void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer);
|
||||
void *prRhiBufferMapVk(PrRhiDevice *device, PrRhiBuffer *buffer);
|
||||
void prRhiBufferUnmapVk(PrRhiDevice *device, PrRhiBuffer *buffer);
|
||||
PrRhiDeviceAddress prRhiGetBufferDeviceAddressVk(PrRhiDevice *device, PrRhiBuffer *buffer);
|
||||
|
||||
PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiTexture *prRhiCreateTextureVk(PrRhiDevice *device, PrRhiTextureDesc desc);
|
||||
PrRhiTexture *prRhiCreateTextureFromKtxVk(PrRhiDevice *device, const char *path,
|
||||
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture,
|
||||
WpAllocator *allocator);
|
||||
PrRhiCommandPool *pool, PrRhiCommandBuffer *cb);
|
||||
void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture);
|
||||
|
||||
PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler,
|
||||
WpAllocator *allocator);
|
||||
PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc);
|
||||
void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler);
|
||||
|
||||
PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *allocator);
|
||||
PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc);
|
||||
void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader);
|
||||
|
||||
PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device,
|
||||
PrRhiPipelineLayoutDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiPipelineLayoutDesc desc);
|
||||
void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device,
|
||||
PrRhiPipelineLayout *layout,
|
||||
WpAllocator *allocator);
|
||||
PrRhiPipelineLayout *layout);
|
||||
|
||||
PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device,
|
||||
PrRhiGraphicsPipelineDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiGraphicsPipelineDesc desc);
|
||||
PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device,
|
||||
PrRhiComputePipelineDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline,
|
||||
WpAllocator *allocator);
|
||||
PrRhiComputePipelineDesc desc);
|
||||
void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline);
|
||||
|
||||
PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayoutVk(PrRhiDevice *device,
|
||||
PrRhiDescriptorSetLayoutDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorSetLayoutDesc desc);
|
||||
void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device,
|
||||
PrRhiDescriptorSetLayout *layout,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorSetLayout *layout);
|
||||
|
||||
PrRhiDescriptorPool *prRhiCreateDescriptorPoolVk(PrRhiDevice *device,
|
||||
PrRhiDescriptorPoolDesc desc,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorPoolDesc desc);
|
||||
void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device,
|
||||
PrRhiDescriptorPool *pool,
|
||||
WpAllocator *allocator);
|
||||
PrRhiDescriptorPool *pool);
|
||||
|
||||
PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device,
|
||||
PrRhiDescriptorPool *pool,
|
||||
PrRhiDescriptorSetLayout *layout,
|
||||
u32 variable_count, WpAllocator *allocator);
|
||||
PrRhiDescriptorPool *pool,
|
||||
PrRhiDescriptorSetLayout *layout,
|
||||
u32 variable_count);
|
||||
void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||
PrRhiDescriptorSet *set, WpAllocator *allocator);
|
||||
PrRhiDescriptorSet *set);
|
||||
void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
|
||||
|
||||
PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *allocator);
|
||||
PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc);
|
||||
void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence);
|
||||
|
||||
void prRhiWaitForFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count,
|
||||
b8 wait_all, u64 timeout_ns);
|
||||
void prRhiResetFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count);
|
||||
|
||||
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device, WpAllocator *allocator);
|
||||
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore,
|
||||
WpAllocator *allocator);
|
||||
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device);
|
||||
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore);
|
||||
|
||||
PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device,
|
||||
PrRhiCommandPoolDesc desc,
|
||||
WpAllocator *allocator);
|
||||
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||
WpAllocator *allocator);
|
||||
PrRhiCommandPoolDesc desc);
|
||||
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool);
|
||||
PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||
u32 count, WpAllocator *allocator);
|
||||
u32 count);
|
||||
void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||
u32 count, PrRhiCommandBufferArray buffers);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user