RHI vulkan updates
This commit is contained in:
@@ -16,6 +16,21 @@ Use this when working on any file in `src/prism/rhi/`, or when creating a new ba
|
|||||||
|
|
||||||
## Conventions
|
## Conventions
|
||||||
|
|
||||||
|
### Global context
|
||||||
|
|
||||||
|
RHI functions do **not** take allocator parameters. A global `PrRhiContext` provides two allocators:
|
||||||
|
- `allocator` — for user-facing objects (buffers, textures, pipelines, etc.)
|
||||||
|
- `tmp` — for short-lived internal temporaries
|
||||||
|
|
||||||
|
```c
|
||||||
|
extern PrRhiContext _G_RHI_CONTEXT;
|
||||||
|
|
||||||
|
void prRhiInit(void); // sets up both allocators
|
||||||
|
void prRhiDestroy(void); // tears down context
|
||||||
|
```
|
||||||
|
|
||||||
|
All RHI functions access `_G_RHI_CONTEXT` directly. Do not pass allocators to RHI API calls.
|
||||||
|
|
||||||
### Backend dispatch
|
### Backend dispatch
|
||||||
|
|
||||||
Backend selection is compile-time via `-D PR_RHI_VULKAN` / `-D PR_RHI_D3D12` / `-D PR_RHI_METAL`. The umbrella header `pr_rhi.h` includes the appropriate alias file:
|
Backend selection is compile-time via `-D PR_RHI_VULKAN` / `-D PR_RHI_D3D12` / `-D PR_RHI_METAL`. The umbrella header `pr_rhi.h` includes the appropriate alias file:
|
||||||
@@ -49,22 +64,95 @@ All descriptor structs are passed **by value**, not `const *`:
|
|||||||
|
|
||||||
```c
|
```c
|
||||||
// correct
|
// correct
|
||||||
PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
|
PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface, PrRhiDeviceDesc desc);
|
||||||
PrRhiDeviceDesc desc, WpAllocator *alloc);
|
|
||||||
|
|
||||||
// wrong
|
// wrong
|
||||||
PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface,
|
PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface, const PrRhiDeviceDesc *desc);
|
||||||
const PrRhiDeviceDesc *desc, WpAllocator *alloc);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Frame-by-frame command batching
|
||||||
|
|
||||||
|
Commands that run every frame must avoid arena allocation. Use stack arrays with a while-loop to batch operations:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// correct — stack array, batched submission
|
||||||
|
void prRhiCmdBindDescriptorSetsVk(PrRhiCommandBuffer *cb, PrRhiPipelineBindPoint bind_point,
|
||||||
|
PrRhiPipelineLayout *layout, u32 first_set,
|
||||||
|
PrRhiDescriptorSetArray sets) {
|
||||||
|
u32 set_count = sets ? (u32)wpArrayCount(sets) : 0;
|
||||||
|
while (set_count > 0) {
|
||||||
|
VkDescriptorSetArray vk_sets = wpArrayWithCapacity(VkDescriptorSet, 16, WP_ARRAY_INIT_FILLED);
|
||||||
|
u32 total_capacity = (u32)wpArrayCapacity(vk_sets);
|
||||||
|
u32 real_count = set_count < total_capacity ? set_count : total_capacity;
|
||||||
|
for (u32 i = 0; i < real_count; ++i) {
|
||||||
|
vk_sets[i] = sets[i]->handle;
|
||||||
|
}
|
||||||
|
vkCmdBindDescriptorSets(cb->handle, vk_bp, vk_layout, first_set, real_count, vk_sets, 0, NULL);
|
||||||
|
set_count -= real_count;
|
||||||
|
first_set += real_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrong — allocates from arena on every call
|
||||||
|
void prRhiCmdBindDescriptorSetsBad(PrRhiCommandBuffer *cb, ...) {
|
||||||
|
VkDescriptorSetArray vk_sets = wpArrayAllocCapacity(VkDescriptorSet, &_G_RHI_CONTEXT.allocator, count, ...);
|
||||||
|
// ... this leaks every frame
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Apply this pattern to: `prRhiCmdBindDescriptorSets`, `prRhiCmdBindVertexBuffers`, `prRhiCmdCopyBufferToImage`, and any other command that processes user-provided arrays.
|
||||||
|
|
||||||
|
### Opaque struct handles — no casts
|
||||||
|
|
||||||
|
Handle types in opaque structs are already the correct Vulkan type. Do not cast:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// correct
|
||||||
|
vk_device = device->handle;
|
||||||
|
vk_buffer = buffer->handle;
|
||||||
|
|
||||||
|
// wrong
|
||||||
|
vk_device = (VkDevice)device->handle;
|
||||||
|
vk_buffer = (VkBuffer)buffer->handle;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vulkan struct initialisation — designated initializers
|
||||||
|
|
||||||
|
Always use C99 designated initializers for Vulkan info structs:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// correct
|
||||||
|
VkBufferCreateInfo buf_info = {
|
||||||
|
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||||
|
.size = desc.size,
|
||||||
|
.usage = _toVkBufferUsage(desc.usage),
|
||||||
|
};
|
||||||
|
|
||||||
|
// wrong
|
||||||
|
VkBufferCreateInfo buf_info = {};
|
||||||
|
buf_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
|
buf_info.size = desc.size;
|
||||||
|
buf_info.usage = _toVkBufferUsage(desc.usage);
|
||||||
|
```
|
||||||
|
|
||||||
|
### API patterns
|
||||||
|
|
||||||
|
- **`prRhiCreateCommandPool`**: Takes only `PrRhiDevice *device` (uses `device->queue_family_index` internally)
|
||||||
|
- **`prRhiFreeCommandBuffers`**: Takes `PrRhiCommandBufferArray buffers` (count derived from `wpArrayCount`)
|
||||||
|
- **`prRhiAllocateDescriptorSet`**: Takes `WpU32Array variable_descriptor_counts` for variable descriptor support
|
||||||
|
- **`prRhiCmdBindVertexBuffers`**: Takes `WpU64Array offsets` (count matched to buffers internally)
|
||||||
|
- **Shader entry points**: Configurable via `vertex_shader_entry_point` / `fragment_shader_entry_point` in pipeline desc (not hardcoded to "main")
|
||||||
|
|
||||||
### File layout
|
### File layout
|
||||||
|
|
||||||
```
|
```
|
||||||
src/prism/rhi/
|
src/prism/rhi/
|
||||||
├── pr_rhi.h ← umbrella header (API declarations + backend dispatch)
|
├── pr_rhi.h ← umbrella header (API declarations + backend dispatch)
|
||||||
|
├── pr_rhi.c ← global context definition (prRhiInit, prRhiDestroy)
|
||||||
├── pr_rhi_types.h ← shared types (enums, element types, array aliases, desc structs, opaque handles)
|
├── pr_rhi_types.h ← shared types (enums, element types, array aliases, desc structs, opaque handles)
|
||||||
├── vulkan/
|
├── vulkan/
|
||||||
│ ├── pr_rhi_vk.h ← Vulkan backend header (opaque struct defs + Vk-suffixed decls)
|
│ ├── pr_rhi_vk.h ← Vulkan backend header (opaque struct defs + Vk-suffixed decls)
|
||||||
|
│ ├── pr_rhi_vk.c ← Vulkan backend implementation
|
||||||
│ ├── pr_rhi_vk_aliases.h ← #define alias mapping
|
│ ├── pr_rhi_vk_aliases.h ← #define alias mapping
|
||||||
│ └── profiles/ ← generated Vulkan Profiles library
|
│ └── profiles/ ← generated Vulkan Profiles library
|
||||||
├── d3d12/
|
├── d3d12/
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ All code follows the patterns established in `src/wapp/`. The project prefix is
|
|||||||
|
|
||||||
- **Tabs for indentation**, 8-column tab width.
|
- **Tabs for indentation**, 8-column tab width.
|
||||||
- **Braces** on the same line as control statements (Attach style).
|
- **Braces** on the same line as control statements (Attach style).
|
||||||
|
- **Braces on single-line if statements**: Always use braces, even for single-line bodies:
|
||||||
|
```c
|
||||||
|
// correct
|
||||||
|
if (!buffer) { return; }
|
||||||
|
if (!texture) { _abort("alloc failed"); }
|
||||||
|
|
||||||
|
// wrong
|
||||||
|
if (!buffer) return;
|
||||||
|
if (!texture) _abort("alloc failed");
|
||||||
|
```
|
||||||
- **Pointers**: `*` against the name, not the type (`PrRhiBuffer *buf`, not `PrRhiBuffer* buf`).
|
- **Pointers**: `*` against the name, not the type (`PrRhiBuffer *buf`, not `PrRhiBuffer* buf`).
|
||||||
- **Line width**: 120 columns.
|
- **Line width**: 120 columns.
|
||||||
- **Continuation lines** align to the opening parenthesis.
|
- **Continuation lines** align to the opening parenthesis.
|
||||||
@@ -117,6 +127,24 @@ prefer SoA layouts, batch processing, and minimise pointer chasing. Keep
|
|||||||
the DAG in contiguous arrays (e.g. adjacency lists packed in flat buffers)
|
the DAG in contiguous arrays (e.g. adjacency lists packed in flat buffers)
|
||||||
rather than individually allocated linked structures.
|
rather than individually allocated linked structures.
|
||||||
|
|
||||||
|
### Frame-by-frame command batching
|
||||||
|
|
||||||
|
Commands that execute every frame must avoid arena allocation. Use stack
|
||||||
|
arrays with a while-loop to batch operations in fixed-size chunks:
|
||||||
|
|
||||||
|
```c
|
||||||
|
while (count > 0) {
|
||||||
|
VkTypeArray batch = wpArrayWithCapacity(VkType, 16, WP_ARRAY_INIT_FILLED);
|
||||||
|
u32 batch_size = count < wpArrayCapacity(batch) ? count : (u32)wpArrayCapacity(batch);
|
||||||
|
// ... process batch ...
|
||||||
|
vkCmd*(cb->handle, ...);
|
||||||
|
count -= batch_size;
|
||||||
|
first += batch_size;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This avoids per-frame arena churn while handling arbitrarily large inputs.
|
||||||
|
|
||||||
### Graph / adjacency lists
|
### Graph / adjacency lists
|
||||||
|
|
||||||
Adjacency list nodes must be **separately allocated from the vertex array**.
|
Adjacency list nodes must be **separately allocated from the vertex array**.
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ build: vendor
|
|||||||
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/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 {{VK_FLAGS}} -Wno-nullability-completeness -DVK_NO_PROTOTYPES \
|
||||||
{{APP_INC}} \
|
{{APP_INC}} \
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
-o {{BUILDDIR}}/main.o
|
-o {{BUILDDIR}}/main.o
|
||||||
@@ -55,6 +55,9 @@ build: vendor
|
|||||||
-o {{BUILDDIR}}/prism
|
-o {{BUILDDIR}}/prism
|
||||||
@echo "--- build done: {{BUILDDIR}}/prism ---"
|
@echo "--- build done: {{BUILDDIR}}/prism ---"
|
||||||
|
|
||||||
|
run:
|
||||||
|
./{{BUILDDIR}}/prism
|
||||||
|
|
||||||
# Clean
|
# Clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf {{BUILDDIR}}
|
rm -rf {{BUILDDIR}}
|
||||||
|
|||||||
+109
-114
@@ -3,8 +3,7 @@
|
|||||||
// Prism port of how-to-vulkan's main.cpp — uses the RHI API instead of
|
// Prism port of how-to-vulkan's main.cpp — uses the RHI API instead of
|
||||||
// direct Vulkan calls.
|
// direct Vulkan calls.
|
||||||
|
|
||||||
#define PR_RHI_VULKAN
|
#include "prism/rhi/pr_rhi_types.h"
|
||||||
|
|
||||||
#include "prism/rhi/pr_rhi.h"
|
#include "prism/rhi/pr_rhi.h"
|
||||||
#include <SDL3/SDL_timer.h>
|
#include <SDL3/SDL_timer.h>
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
@@ -95,6 +94,8 @@ struct AppState {
|
|||||||
PrRhiSurface *surface;
|
PrRhiSurface *surface;
|
||||||
PrRhiSwapchain *swapchain;
|
PrRhiSwapchain *swapchain;
|
||||||
|
|
||||||
|
PrRhiFormat swapchain_format;
|
||||||
|
|
||||||
PrRhiBuffer *vert_index_buf;
|
PrRhiBuffer *vert_index_buf;
|
||||||
u64 vertex_buf_size;
|
u64 vertex_buf_size;
|
||||||
u64 index_count;
|
u64 index_count;
|
||||||
@@ -136,9 +137,10 @@ struct AppState {
|
|||||||
int main() {
|
int main() {
|
||||||
AppState app = {};
|
AppState app = {};
|
||||||
WpAllocator arena = wpMemArenaAllocatorInitZero(MiB(128));
|
WpAllocator arena = wpMemArenaAllocatorInitZero(MiB(128));
|
||||||
prRhiInit();
|
|
||||||
|
|
||||||
// {{{ Initialisation
|
// {{{ Initialisation
|
||||||
|
prRhiInit();
|
||||||
|
|
||||||
check(SDL_Init(SDL_INIT_VIDEO), EXIT_CODE_SDL_INIT_FAILED);
|
check(SDL_Init(SDL_INIT_VIDEO), EXIT_CODE_SDL_INIT_FAILED);
|
||||||
|
|
||||||
f32 display_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
f32 display_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||||
@@ -149,8 +151,7 @@ int main() {
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Instance creation
|
// {{{ Instance creation
|
||||||
PrRhiInstanceDesc inst_desc = {};
|
app.inst = prRhiCreateInstance(PrRhiInstanceDesc{});
|
||||||
app.inst = prRhiCreateInstance(inst_desc);
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Physical device selection
|
// {{{ Physical device selection
|
||||||
@@ -159,8 +160,7 @@ int main() {
|
|||||||
|
|
||||||
i32 selected = -1;
|
i32 selected = -1;
|
||||||
for (u32 i = 0; i < wpArrayCount(pdevs); ++i) {
|
for (u32 i = 0; i < wpArrayCount(pdevs); ++i) {
|
||||||
PrRhiPhysicalDeviceProperties props;
|
PrRhiPhysicalDeviceProperties props = prRhiGetPhysicalDeviceProperties(pdevs[i]);
|
||||||
prRhiGetPhysicalDeviceProperties(pdevs[i], &props);
|
|
||||||
switch (props.device_type) {
|
switch (props.device_type) {
|
||||||
case PR_RHI_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
|
case PR_RHI_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
|
||||||
selected = (i32)i;
|
selected = (i32)i;
|
||||||
@@ -176,7 +176,8 @@ int main() {
|
|||||||
app.pdev = pdevs[selected];
|
app.pdev = pdevs[selected];
|
||||||
|
|
||||||
// Print device info
|
// Print device info
|
||||||
WpStr8 dev_name, driver_info;
|
WpStr8 dev_name = wpStr8Buf(512);
|
||||||
|
WpStr8 driver_info = wpStr8Buf(512);
|
||||||
prRhiGetPhysicalDeviceName(app.pdev, &dev_name);
|
prRhiGetPhysicalDeviceName(app.pdev, &dev_name);
|
||||||
prRhiGetPhysicalDeviceDriverInfo(app.pdev, &driver_info);
|
prRhiGetPhysicalDeviceDriverInfo(app.pdev, &driver_info);
|
||||||
std::cout << "Selected GPU: " << std::string_view((const char *)dev_name.buf, dev_name.size) << '\n'
|
std::cout << "Selected GPU: " << std::string_view((const char *)dev_name.buf, dev_name.size) << '\n'
|
||||||
@@ -186,14 +187,14 @@ 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);
|
app.surface = prRhiCreateSurfaceFromWindow(app.inst, 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);
|
app.device = prRhiCreateDevice(app.pdev, app.surface, dev_desc);
|
||||||
u32 qfi = prRhiGetQueueFamilyIndex(app.device);
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Swapchain creation
|
// {{{ Swapchain creation
|
||||||
@@ -203,9 +204,9 @@ 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);
|
|
||||||
|
|
||||||
PrRhiFormat swapchain_format = prRhiGetSwapchainFormat(app.swapchain);
|
app.swapchain = prRhiCreateSwapchain(app.device, swap_desc);
|
||||||
|
app.swapchain_format = prRhiGetSwapchainFormat(app.swapchain);
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Vertex/Index buffers
|
// {{{ Vertex/Index buffers
|
||||||
@@ -252,6 +253,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);
|
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);
|
||||||
@@ -271,6 +273,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);
|
app.shader_data_bufs[i] = prRhiCreateBuffer(app.device, buf_desc);
|
||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
@@ -294,7 +297,7 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Render completed semaphores (per swapchain image)
|
// Render completed semaphores (per swapchain image)
|
||||||
u32 swapchain_image_count = app.swapchain->image_count;
|
u32 swapchain_image_count = prRhiGetSwapchainImageCount(app.swapchain);
|
||||||
app.render_completed_semaphores = wpArrayAllocCapacity(PrRhiSemaphore *, &arena,
|
app.render_completed_semaphores = wpArrayAllocCapacity(PrRhiSemaphore *, &arena,
|
||||||
swapchain_image_count,
|
swapchain_image_count,
|
||||||
WP_ARRAY_INIT_FILLED);
|
WP_ARRAY_INIT_FILLED);
|
||||||
@@ -304,10 +307,7 @@ int main() {
|
|||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Command pool and buffers
|
// {{{ Command pool and buffers
|
||||||
PrRhiCommandPoolDesc pool_desc = {};
|
app.cmd_pool = prRhiCreateCommandPool(app.device);
|
||||||
pool_desc.queue_family_index = qfi;
|
|
||||||
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);
|
AppState::max_frames_in_flight);
|
||||||
// }}}
|
// }}}
|
||||||
@@ -331,27 +331,28 @@ 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);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
prRhiFreeCommandBuffers(app.device, app.cmd_pool, 1, upload_cbs);
|
prRhiFreeCommandBuffers(app.device, app.cmd_pool, upload_cbs);
|
||||||
wpArrayDealloc(PrRhiCommandBuffer *, &arena, &upload_cbs);
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Descriptor set layout, pool, set
|
// {{{ Descriptor set layout, pool, set
|
||||||
PrRhiDescriptorSetLayoutBinding bindings[1] = {};
|
PrRhiDescriptorSetLayoutBindingArray ds_layouts = wpArray(
|
||||||
bindings[0].type = PR_RHI_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
PrRhiDescriptorSetLayoutBinding,
|
||||||
bindings[0].descriptor_count = AppState::texture_count;
|
PrRhiDescriptorSetLayoutBinding{
|
||||||
bindings[0].stage_flags = PR_RHI_SHADER_STAGE_FRAGMENT;
|
PR_RHI_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
|
||||||
bindings[0].binding_flags = PR_RHI_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT;
|
AppState::texture_count,
|
||||||
|
PR_RHI_SHADER_STAGE_FRAGMENT,
|
||||||
|
PR_RHI_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
PrRhiDescriptorSetLayoutBindingArray ds_layouts = wpArray(PrRhiDescriptorSetLayoutBinding, bindings[0]);
|
PrRhiDescriptorSetLayoutDesc layout_desc = { ds_layouts };
|
||||||
|
|
||||||
PrRhiDescriptorSetLayoutDesc layout_desc = {};
|
|
||||||
layout_desc.bindings = ds_layouts;
|
|
||||||
app.desc_set_layout = prRhiCreateDescriptorSetLayout(app.device, layout_desc);
|
app.desc_set_layout = prRhiCreateDescriptorSetLayout(app.device, layout_desc);
|
||||||
|
|
||||||
// Pool
|
// Pool
|
||||||
@@ -359,15 +360,16 @@ int main() {
|
|||||||
pool_size.type = PR_RHI_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
pool_size.type = PR_RHI_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
|
||||||
pool_size.descriptor_count = AppState::texture_count;
|
pool_size.descriptor_count = AppState::texture_count;
|
||||||
|
|
||||||
PrRhiDescriptorPoolDesc pool_desc2 = {};
|
PrRhiDescriptorPoolDesc ds_pool_desc = {};
|
||||||
pool_desc2.max_sets = 1;
|
ds_pool_desc.max_sets = 1;
|
||||||
pool_desc2.pool_sizes = wpArray(PrRhiDescriptorPoolSize, pool_size);
|
ds_pool_desc.pool_sizes = wpArray(PrRhiDescriptorPoolSize, pool_size);
|
||||||
app.desc_pool = prRhiCreateDescriptorPool(app.device, pool_desc2);
|
|
||||||
|
app.desc_pool = prRhiCreateDescriptorPool(app.device, ds_pool_desc);
|
||||||
|
|
||||||
// Allocate descriptor set (variable count)
|
// Allocate descriptor set (variable count)
|
||||||
app.desc_set = prRhiAllocateDescriptorSet(app.device, app.desc_pool,
|
WpU32Array var_counts = wpArray(u32, AppState::texture_count);
|
||||||
app.desc_set_layout,
|
app.desc_set = prRhiAllocateDescriptorSet(app.device, app.desc_pool, app.desc_set_layout,
|
||||||
AppState::texture_count);
|
var_counts);
|
||||||
|
|
||||||
// Write descriptor set
|
// Write descriptor set
|
||||||
PrRhiDescriptorImageInfoArray img_infos = wpArrayAllocCapacity(PrRhiDescriptorImageInfo,
|
PrRhiDescriptorImageInfoArray img_infos = wpArrayAllocCapacity(PrRhiDescriptorImageInfo,
|
||||||
@@ -417,6 +419,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);
|
app.shader = prRhiCreateShader(app.device, shader_desc);
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
@@ -425,56 +428,56 @@ int main() {
|
|||||||
pc_range.stage_flags = PR_RHI_SHADER_STAGE_VERTEX;
|
pc_range.stage_flags = PR_RHI_SHADER_STAGE_VERTEX;
|
||||||
pc_range.size = sizeof(u64);
|
pc_range.size = sizeof(u64);
|
||||||
|
|
||||||
PrRhiDescriptorSetLayout *set_layouts_pl[] = { app.desc_set_layout };
|
PrRhiDescriptorSetLayoutArray pl_layouts = wpArray(PrRhiDescriptorSetLayout *, app.desc_set_layout);
|
||||||
PrRhiDescriptorSetLayoutArray pl_layouts = wpArray(PrRhiDescriptorSetLayout *, set_layouts_pl[0]);
|
|
||||||
|
|
||||||
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);
|
app.pipeline_layout = prRhiCreatePipelineLayout(app.device, pl_desc);
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Graphics pipeline
|
// {{{ Graphics pipeline
|
||||||
PrRhiVertexInputBinding vertex_binding = {};
|
PrRhiVertexInputBindingArray vertex_bindings = wpArray(
|
||||||
vertex_binding.binding = 0;
|
PrRhiVertexInputBinding,
|
||||||
vertex_binding.stride = sizeof(Vertex);
|
PrRhiVertexInputBinding{ 0, sizeof(Vertex) }
|
||||||
|
);
|
||||||
|
|
||||||
PrRhiVertexAttribute vertex_attrs[3] = {};
|
PrRhiVertexAttributeArray vertex_attrs = wpArray(
|
||||||
vertex_attrs[0].location = 0;
|
PrRhiVertexAttribute,
|
||||||
vertex_attrs[0].binding = 0;
|
PrRhiVertexAttribute{ 0, 0, PR_RHI_FORMAT_R32G32B32_SFLOAT, 0 },
|
||||||
vertex_attrs[0].format = PR_RHI_FORMAT_R32G32B32_SFLOAT;
|
PrRhiVertexAttribute{ 1, 0, PR_RHI_FORMAT_R32G32B32_SFLOAT, offsetof(Vertex, normal) },
|
||||||
vertex_attrs[0].offset = 0;
|
PrRhiVertexAttribute{ 2, 0, PR_RHI_FORMAT_R32G32_SFLOAT, offsetof(Vertex, uv) }
|
||||||
vertex_attrs[1].location = 1;
|
);
|
||||||
vertex_attrs[1].binding = 0;
|
|
||||||
vertex_attrs[1].format = PR_RHI_FORMAT_R32G32B32_SFLOAT;
|
|
||||||
vertex_attrs[1].offset = offsetof(Vertex, normal);
|
|
||||||
vertex_attrs[2].location = 2;
|
|
||||||
vertex_attrs[2].binding = 0;
|
|
||||||
vertex_attrs[2].format = PR_RHI_FORMAT_R32G32_SFLOAT;
|
|
||||||
vertex_attrs[2].offset = offsetof(Vertex, uv);
|
|
||||||
|
|
||||||
PrRhiColorBlendAttachment blend_attachment = {};
|
PrRhiColorBlendAttachmentArray blend_attachments = wpArray(
|
||||||
blend_attachment.color_write_mask = 0xf;
|
PrRhiColorBlendAttachment,
|
||||||
|
PrRhiColorBlendAttachment{ 0xf }
|
||||||
|
);
|
||||||
|
|
||||||
PrRhiFormat color_fmts[] = { swapchain_format };
|
PrRhiFormatArray color_fmt_array = wpArray(PrRhiFormat, app.swapchain_format);
|
||||||
PrRhiFormatArray color_fmt_array = wpArray(PrRhiFormat, color_fmts[0]);
|
|
||||||
|
|
||||||
PrRhiGraphicsPipelineDesc pipe_desc = {};
|
PrRhiGraphicsPipelineDesc pipe_desc = {};
|
||||||
pipe_desc.vertex_shader = app.shader;
|
pipe_desc.vertex_shader = app.shader;
|
||||||
|
pipe_desc.vertex_shader_entry_point = "main";
|
||||||
pipe_desc.fragment_shader = app.shader;
|
pipe_desc.fragment_shader = app.shader;
|
||||||
pipe_desc.vertex_bindings = wpArray(PrRhiVertexInputBinding, vertex_binding);
|
pipe_desc.fragment_shader_entry_point = "main";
|
||||||
pipe_desc.vertex_attributes = wpArray(PrRhiVertexAttribute, vertex_attrs[0],
|
pipe_desc.vertex_bindings = vertex_bindings;
|
||||||
vertex_attrs[1], vertex_attrs[2]);
|
pipe_desc.vertex_attributes = vertex_attrs;
|
||||||
pipe_desc.topology = PR_RHI_TOPOLOGY_TRIANGLE_LIST;
|
pipe_desc.topology = PR_RHI_TOPOLOGY_TRIANGLE_LIST;
|
||||||
pipe_desc.color_attachment_formats = color_fmt_array;
|
pipe_desc.color_attachment_formats = color_fmt_array;
|
||||||
pipe_desc.depth_attachment_format = swap_desc.depth_format;
|
pipe_desc.depth_attachment_format = swap_desc.depth_format;
|
||||||
pipe_desc.depth_test_enable = true;
|
pipe_desc.depth_test_enable = true;
|
||||||
pipe_desc.depth_write_enable = true;
|
pipe_desc.depth_write_enable = true;
|
||||||
pipe_desc.depth_compare_op = PR_RHI_COMPARE_OP_LESS_OR_EQUAL;
|
pipe_desc.depth_compare_op = PR_RHI_COMPARE_OP_LESS_OR_EQUAL;
|
||||||
pipe_desc.blend_attachments = wpArray(PrRhiColorBlendAttachment, blend_attachment);
|
pipe_desc.blend_attachments = blend_attachments;
|
||||||
pipe_desc.dynamic_viewport = true;
|
pipe_desc.dynamic_viewport = true;
|
||||||
pipe_desc.dynamic_scissor = true;
|
pipe_desc.dynamic_scissor = true;
|
||||||
|
pipe_desc.cull_mode = PR_RHI_CULL_MODE_BACK;
|
||||||
|
pipe_desc.front_face = PR_RHI_FRONT_FACE_COUNTER_CLOCKWISE;
|
||||||
|
pipe_desc.line_width = 1.0f;
|
||||||
pipe_desc.layout = app.pipeline_layout;
|
pipe_desc.layout = app.pipeline_layout;
|
||||||
|
|
||||||
app.pipeline = prRhiCreateGraphicsPipeline(app.device, pipe_desc);
|
app.pipeline = prRhiCreateGraphicsPipeline(app.device, pipe_desc);
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
@@ -516,8 +519,7 @@ int main() {
|
|||||||
glm::mat4_cast(glm::quat(app.object_rotations[i]));
|
glm::mat4_cast(glm::quat(app.object_rotations[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *shader_data_ptr = prRhiBufferMap(app.device,
|
void *shader_data_ptr = prRhiBufferMap(app.device, app.shader_data_bufs[app.frame_index]);
|
||||||
app.shader_data_bufs[app.frame_index]);
|
|
||||||
memcpy(shader_data_ptr, &app.shader_data, sizeof(ShaderData));
|
memcpy(shader_data_ptr, &app.shader_data, sizeof(ShaderData));
|
||||||
prRhiBufferUnmap(app.device, app.shader_data_bufs[app.frame_index]);
|
prRhiBufferUnmap(app.device, app.shader_data_bufs[app.frame_index]);
|
||||||
// }}}
|
// }}}
|
||||||
@@ -529,43 +531,43 @@ int main() {
|
|||||||
|
|
||||||
// Transition images to attachment optimal
|
// Transition images to attachment optimal
|
||||||
{
|
{
|
||||||
PrRhiImageMemoryBarrier img_barriers[2] = {};
|
PrRhiImageMemoryBarrierArray barriers_arr =
|
||||||
|
wpArrayWithCapacity(PrRhiImageMemoryBarrier, 2, WP_ARRAY_INIT_FILLED);
|
||||||
|
|
||||||
// Color attachment
|
// Color attachment
|
||||||
PrRhiTexture *color_tex = prRhiGetSwapchainTexture(app.swapchain, image_index);
|
PrRhiTexture *color_tex = prRhiGetSwapchainTexture(app.swapchain, image_index);
|
||||||
img_barriers[0].texture = color_tex;
|
barriers_arr[0].texture = color_tex;
|
||||||
img_barriers[0].old_layout = PR_RHI_LAYOUT_UNDEFINED;
|
barriers_arr[0].old_layout = PR_RHI_LAYOUT_UNDEFINED;
|
||||||
img_barriers[0].new_layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
barriers_arr[0].new_layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
||||||
img_barriers[0].src_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
barriers_arr[0].src_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
||||||
img_barriers[0].src_access_mask = PR_RHI_ACCESS_NONE;
|
barriers_arr[0].src_access_mask = PR_RHI_ACCESS_NONE;
|
||||||
img_barriers[0].dst_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
barriers_arr[0].dst_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
||||||
img_barriers[0].dst_access_mask = (PrRhiAccess)(PR_RHI_ACCESS_COLOR_ATTACHMENT_READ | PR_RHI_ACCESS_COLOR_ATTACHMENT_WRITE);
|
barriers_arr[0].dst_access_mask = (PrRhiAccess)(PR_RHI_ACCESS_COLOR_ATTACHMENT_READ | PR_RHI_ACCESS_COLOR_ATTACHMENT_WRITE);
|
||||||
|
|
||||||
// Depth attachment
|
// Depth attachment
|
||||||
PrRhiTexture *depth_tex = prRhiGetSwapchainDepthTexture(app.swapchain);
|
PrRhiTexture *depth_tex = prRhiGetSwapchainDepthTexture(app.swapchain);
|
||||||
img_barriers[1].texture = depth_tex;
|
barriers_arr[1].texture = depth_tex;
|
||||||
img_barriers[1].old_layout = PR_RHI_LAYOUT_UNDEFINED;
|
barriers_arr[1].old_layout = PR_RHI_LAYOUT_UNDEFINED;
|
||||||
img_barriers[1].new_layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
barriers_arr[1].new_layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
||||||
img_barriers[1].src_stage_mask = PR_RHI_PIPELINE_STAGE_LATE_FRAGMENT_TESTS;
|
barriers_arr[1].src_stage_mask = PR_RHI_PIPELINE_STAGE_LATE_FRAGMENT_TESTS;
|
||||||
img_barriers[1].src_access_mask = PR_RHI_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE;
|
barriers_arr[1].src_access_mask = PR_RHI_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE;
|
||||||
img_barriers[1].dst_stage_mask = PR_RHI_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS;
|
barriers_arr[1].dst_stage_mask = PR_RHI_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS;
|
||||||
img_barriers[1].dst_access_mask = PR_RHI_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE;
|
barriers_arr[1].dst_access_mask = PR_RHI_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE;
|
||||||
|
|
||||||
PrRhiImageMemoryBarrierArray barriers_arr = wpArray(PrRhiImageMemoryBarrier,
|
|
||||||
img_barriers[0], img_barriers[1]);
|
|
||||||
prRhiCmdPipelineBarrier(cb, barriers_arr, NULL);
|
prRhiCmdPipelineBarrier(cb, barriers_arr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
{
|
{
|
||||||
PrRhiColorAttachment color_att = {};
|
PrRhiColorAttachmentArray color_arr =
|
||||||
color_att.texture = prRhiGetSwapchainTexture(app.swapchain, image_index);
|
wpArrayWithCapacity(PrRhiColorAttachment, 1, WP_ARRAY_INIT_FILLED);
|
||||||
color_att.layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
color_arr[0].texture = prRhiGetSwapchainTexture(app.swapchain, image_index);
|
||||||
color_att.clear = true;
|
color_arr[0].layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
||||||
color_att.clear_color[0] = 0.0f;
|
color_arr[0].clear = true;
|
||||||
color_att.clear_color[1] = 0.0f;
|
color_arr[0].clear_color[0] = 0.0f;
|
||||||
color_att.clear_color[2] = 0.0f;
|
color_arr[0].clear_color[1] = 0.0f;
|
||||||
color_att.clear_color[3] = 0.0f;
|
color_arr[0].clear_color[2] = 0.0f;
|
||||||
|
color_arr[0].clear_color[3] = 0.0f;
|
||||||
|
|
||||||
PrRhiDepthAttachment depth_att = {};
|
PrRhiDepthAttachment depth_att = {};
|
||||||
depth_att.texture = prRhiGetSwapchainDepthTexture(app.swapchain);
|
depth_att.texture = prRhiGetSwapchainDepthTexture(app.swapchain);
|
||||||
@@ -573,7 +575,6 @@ int main() {
|
|||||||
depth_att.clear = true;
|
depth_att.clear = true;
|
||||||
depth_att.clear_depth = 1.0f;
|
depth_att.clear_depth = 1.0f;
|
||||||
|
|
||||||
PrRhiColorAttachmentArray color_arr = wpArray(PrRhiColorAttachment, color_att);
|
|
||||||
prRhiCmdBeginRendering(cb, color_arr, &depth_att);
|
prRhiCmdBeginRendering(cb, color_arr, &depth_att);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,44 +587,39 @@ int main() {
|
|||||||
prRhiCmdBindDescriptorSets(cb, PR_RHI_PIPELINE_BIND_POINT_GRAPHICS,
|
prRhiCmdBindDescriptorSets(cb, PR_RHI_PIPELINE_BIND_POINT_GRAPHICS,
|
||||||
app.pipeline_layout, 0, sets);
|
app.pipeline_layout, 0, sets);
|
||||||
|
|
||||||
PrRhiBuffer *vert_bufs[] = { app.vert_index_buf };
|
PrRhiBufferArray vert_buf_arr = wpArray(PrRhiBuffer *, app.vert_index_buf);
|
||||||
u64 vert_offsets[] = { 0 };
|
WpU64Array vert_offsets = wpArray(u64, 0);
|
||||||
PrRhiBufferArray vert_buf_arr = wpArray(PrRhiBuffer *, vert_bufs[0]);
|
prRhiCmdBindVertexBuffers(cb, 0, vert_buf_arr, vert_offsets);
|
||||||
prRhiCmdBindVertexBuffers(cb, 0, vert_buf_arr, vert_offsets, 1);
|
prRhiCmdBindIndexBuffer(cb, app.vert_index_buf, app.vertex_buf_size, PR_RHI_INDEX_TYPE_UINT16);
|
||||||
prRhiCmdBindIndexBuffer(cb, app.vert_index_buf, app.vertex_buf_size,
|
|
||||||
PR_RHI_INDEX_TYPE_UINT16);
|
|
||||||
|
|
||||||
// Push shader data buffer device address
|
// Push shader data buffer device address
|
||||||
u64 buf_addr = prRhiGetBufferDeviceAddress(app.device,
|
u64 buf_addr = prRhiGetBufferDeviceAddress(app.device, app.shader_data_bufs[app.frame_index]);
|
||||||
app.shader_data_bufs[app.frame_index]);
|
prRhiCmdPushConstants(cb, app.pipeline_layout, PR_RHI_SHADER_STAGE_VERTEX, 0, sizeof(u64), &buf_addr);
|
||||||
prRhiCmdPushConstants(cb, app.pipeline_layout, PR_RHI_SHADER_STAGE_VERTEX,
|
|
||||||
0, sizeof(u64), &buf_addr);
|
|
||||||
|
|
||||||
prRhiCmdDrawIndexed(cb, (u32)app.index_count, AppState::instance_count, 0, 0, 0);
|
prRhiCmdDrawIndexed(cb, (u32)app.index_count, AppState::instance_count, 0, 0, 0);
|
||||||
prRhiCmdEndRendering(cb);
|
prRhiCmdEndRendering(cb);
|
||||||
|
|
||||||
// Transition to present
|
// Transition to present
|
||||||
{
|
{
|
||||||
PrRhiImageMemoryBarrier present_barrier = {};
|
PrRhiImageMemoryBarrierArray present_barriers =
|
||||||
present_barrier.texture = prRhiGetSwapchainTexture(app.swapchain, image_index);
|
wpArrayWithCapacity(PrRhiImageMemoryBarrier, 1, WP_ARRAY_INIT_FILLED);
|
||||||
present_barrier.old_layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
present_barriers[0].texture = prRhiGetSwapchainTexture(app.swapchain, image_index);
|
||||||
present_barrier.new_layout = PR_RHI_LAYOUT_PRESENT_SRC;
|
present_barriers[0].old_layout = PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL;
|
||||||
present_barrier.src_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
present_barriers[0].new_layout = PR_RHI_LAYOUT_PRESENT_SRC;
|
||||||
present_barrier.src_access_mask = PR_RHI_ACCESS_COLOR_ATTACHMENT_WRITE;
|
present_barriers[0].src_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
||||||
present_barrier.dst_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
present_barriers[0].src_access_mask = PR_RHI_ACCESS_COLOR_ATTACHMENT_WRITE;
|
||||||
present_barrier.dst_access_mask = PR_RHI_ACCESS_NONE;
|
present_barriers[0].dst_stage_mask = PR_RHI_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT;
|
||||||
|
present_barriers[0].dst_access_mask = PR_RHI_ACCESS_NONE;
|
||||||
|
|
||||||
prRhiCmdPipelineBarrier(cb, wpArray(PrRhiImageMemoryBarrier, present_barrier), NULL);
|
prRhiCmdPipelineBarrier(cb, present_barriers, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
prRhiEndCommandBuffer(cb);
|
prRhiEndCommandBuffer(cb);
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Submit
|
// {{{ Submit
|
||||||
prRhiQueueSubmit(app.device, cb,
|
prRhiQueueSubmit(app.device, cb, app.image_acquired_semaphores[app.frame_index],
|
||||||
app.image_acquired_semaphores[app.frame_index],
|
app.render_completed_semaphores[image_index], app.fences[app.frame_index]);
|
||||||
app.render_completed_semaphores[image_index],
|
|
||||||
app.fences[app.frame_index]);
|
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
// {{{ Present
|
// {{{ Present
|
||||||
@@ -709,8 +705,7 @@ int main() {
|
|||||||
prRhiDestroyTexture(app.device, app.textures[i].texture);
|
prRhiDestroyTexture(app.device, app.textures[i].texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
prRhiFreeCommandBuffers(app.device, app.cmd_pool, AppState::max_frames_in_flight,
|
prRhiFreeCommandBuffers(app.device, app.cmd_pool, app.cmd_buffers);
|
||||||
app.cmd_buffers);
|
|
||||||
prRhiDestroyCommandPool(app.device, app.cmd_pool);
|
prRhiDestroyCommandPool(app.device, app.cmd_pool);
|
||||||
|
|
||||||
for (u32 i = 0; i < swapchain_image_count; ++i) {
|
for (u32 i = 0; i < swapchain_image_count; ++i) {
|
||||||
|
|||||||
@@ -7,11 +7,9 @@
|
|||||||
PrRhiContext _G_RHI_CONTEXT;
|
PrRhiContext _G_RHI_CONTEXT;
|
||||||
|
|
||||||
void prRhiInit(void) {
|
void prRhiInit(void) {
|
||||||
_G_RHI_CONTEXT.main = wpMemArenaAllocatorInit(MiB(64));
|
_G_RHI_CONTEXT.allocator = wpMemArenaAllocatorInit(MiB(64));
|
||||||
_G_RHI_CONTEXT.scratch = wpMemArenaAllocatorInit(MiB(32));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void prRhiDestroy(void) {
|
void prRhiDestroy(void) {
|
||||||
wpMemArenaAllocatorDestroy(&_G_RHI_CONTEXT.scratch);
|
wpMemArenaAllocatorDestroy(&_G_RHI_CONTEXT.allocator);
|
||||||
wpMemArenaAllocatorDestroy(&_G_RHI_CONTEXT.main);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-8
@@ -24,6 +24,7 @@
|
|||||||
#define PR_RHI_H
|
#define PR_RHI_H
|
||||||
|
|
||||||
#include "pr_rhi_types.h"
|
#include "pr_rhi_types.h"
|
||||||
|
#include <SDL3/SDL_video.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -48,14 +49,13 @@ void prRhiDestroyInstance(PrRhiInstance *inst);
|
|||||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevices(PrRhiInstance *inst);
|
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,
|
PrRhiPhysicalDeviceProperties prRhiGetPhysicalDeviceProperties(PrRhiPhysicalDevice *pdev);
|
||||||
PrRhiPhysicalDeviceProperties *out);
|
|
||||||
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
// Surface (platform-specific)
|
// Surface (platform-specific)
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
PrRhiSurface *prRhiCreateSurfaceFromWindow(PrRhiInstance *inst, void *window_handle);
|
PrRhiSurface *prRhiCreateSurfaceFromWindow(PrRhiInstance *inst, SDL_Window *window);
|
||||||
void prRhiDestroySurface(PrRhiInstance *inst, PrRhiSurface *surface);
|
void prRhiDestroySurface(PrRhiInstance *inst, PrRhiSurface *surface);
|
||||||
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev,
|
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev,
|
||||||
PrRhiSurface *surface);
|
PrRhiSurface *surface);
|
||||||
@@ -77,6 +77,7 @@ u32 prRhiGetQueueFamilyIndex(PrRhiDevice *device);
|
|||||||
PrRhiSwapchain *prRhiCreateSwapchain(PrRhiDevice *device, PrRhiSwapchainDesc desc);
|
PrRhiSwapchain *prRhiCreateSwapchain(PrRhiDevice *device, PrRhiSwapchainDesc desc);
|
||||||
void prRhiDestroySwapchain(PrRhiDevice *device, PrRhiSwapchain *swapchain);
|
void prRhiDestroySwapchain(PrRhiDevice *device, PrRhiSwapchain *swapchain);
|
||||||
|
|
||||||
|
u32 prRhiGetSwapchainImageCount(PrRhiSwapchain *swapchain);
|
||||||
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);
|
||||||
|
|
||||||
@@ -168,7 +169,7 @@ void prRhiDestroyDescriptorPool(PrRhiDevice *device,
|
|||||||
|
|
||||||
PrRhiDescriptorSet *prRhiAllocateDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
PrRhiDescriptorSet *prRhiAllocateDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||||
PrRhiDescriptorSetLayout *layout,
|
PrRhiDescriptorSetLayout *layout,
|
||||||
u32 variable_count);
|
WpU32Array variable_descriptor_counts);
|
||||||
void prRhiFreeDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
void prRhiFreeDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||||
PrRhiDescriptorSet *set);
|
PrRhiDescriptorSet *set);
|
||||||
void prRhiUpdateDescriptorSet(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
|
void prRhiUpdateDescriptorSet(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
|
||||||
@@ -191,13 +192,14 @@ void prRhiDestroySemaphore(PrRhiDevice *device, PrRhiSemaphore *semap
|
|||||||
// Command pools and command buffers
|
// Command pools and command buffers
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
PrRhiCommandPool *prRhiCreateCommandPool(PrRhiDevice *device, PrRhiCommandPoolDesc desc);
|
PrRhiCommandPool *prRhiCreateCommandPool(PrRhiDevice *device);
|
||||||
void prRhiDestroyCommandPool(PrRhiDevice *device, PrRhiCommandPool *pool);
|
void prRhiDestroyCommandPool(PrRhiDevice *device, PrRhiCommandPool *pool);
|
||||||
|
|
||||||
PrRhiCommandBufferArray prRhiAllocateCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
|
PrRhiCommandBufferArray prRhiAllocateCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||||
u32 count);
|
u32 count);
|
||||||
|
|
||||||
void prRhiFreeCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
|
void prRhiFreeCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||||
u32 count, PrRhiCommandBufferArray buffers);
|
PrRhiCommandBufferArray buffers);
|
||||||
|
|
||||||
// ======================================================================
|
// ======================================================================
|
||||||
// Command buffer recording
|
// Command buffer recording
|
||||||
@@ -238,8 +240,8 @@ void prRhiCmdPushConstants(PrRhiCommandBuffer *cb, PrRhiPipelineLayout *layout,
|
|||||||
|
|
||||||
// --- Vertex / index buffers ---
|
// --- Vertex / index buffers ---
|
||||||
|
|
||||||
void prRhiCmdBindVertexBuffers(PrRhiCommandBuffer *cb, u32 first_binding,
|
void prRhiCmdBindVertexBuffers(PrRhiCommandBuffer *cb, u32 first_binding, PrRhiBufferArray buffers,
|
||||||
PrRhiBufferArray buffers, const u64 *offsets, u32 count);
|
WpU64Array offsets);
|
||||||
void prRhiCmdBindIndexBuffer(PrRhiCommandBuffer *cb, PrRhiBuffer *buffer, u64 offset,
|
void prRhiCmdBindIndexBuffer(PrRhiCommandBuffer *cb, PrRhiBuffer *buffer, u64 offset,
|
||||||
PrRhiIndexType index_type);
|
PrRhiIndexType index_type);
|
||||||
|
|
||||||
|
|||||||
@@ -357,9 +357,40 @@ typedef struct PrRhiPipelineLayoutDesc {
|
|||||||
PrRhiPushConstantRangeArray push_constant_ranges;
|
PrRhiPushConstantRangeArray push_constant_ranges;
|
||||||
} PrRhiPipelineLayoutDesc;
|
} PrRhiPipelineLayoutDesc;
|
||||||
|
|
||||||
|
typedef enum PrRhiPolygonMode {
|
||||||
|
PR_RHI_POLYGON_MODE_FILL = 0,
|
||||||
|
PR_RHI_POLYGON_MODE_LINE = 1,
|
||||||
|
PR_RHI_POLYGON_MODE_POINT = 2,
|
||||||
|
} PrRhiPolygonMode;
|
||||||
|
|
||||||
|
typedef enum PrRhiCullMode {
|
||||||
|
PR_RHI_CULL_MODE_NONE = 0,
|
||||||
|
PR_RHI_CULL_MODE_FRONT = 0x00000001,
|
||||||
|
PR_RHI_CULL_MODE_BACK = 0x00000002,
|
||||||
|
PR_RHI_CULL_MODE_FRONT_AND_BACK = 0x00000003,
|
||||||
|
} PrRhiCullMode;
|
||||||
|
|
||||||
|
typedef enum PrRhiFrontFace {
|
||||||
|
PR_RHI_FRONT_FACE_COUNTER_CLOCKWISE = 0,
|
||||||
|
PR_RHI_FRONT_FACE_CLOCKWISE = 1,
|
||||||
|
} PrRhiFrontFace;
|
||||||
|
|
||||||
|
typedef enum PrRhiMultisampleCount {
|
||||||
|
PR_RHI_SAMPLE_COUNT_1 = 0x00000001,
|
||||||
|
PR_RHI_SAMPLE_COUNT_2 = 0x00000002,
|
||||||
|
PR_RHI_SAMPLE_COUNT_4 = 0x00000004,
|
||||||
|
PR_RHI_SAMPLE_COUNT_8 = 0x00000008,
|
||||||
|
PR_RHI_SAMPLE_COUNT_16 = 0x00000010,
|
||||||
|
PR_RHI_SAMPLE_COUNT_32 = 0x00000020,
|
||||||
|
PR_RHI_SAMPLE_COUNT_64 = 0x00000040,
|
||||||
|
} PrRhiMultisampleCount;
|
||||||
|
|
||||||
typedef struct PrRhiGraphicsPipelineDesc {
|
typedef struct PrRhiGraphicsPipelineDesc {
|
||||||
PrRhiShader *vertex_shader;
|
PrRhiShader *vertex_shader;
|
||||||
|
const char *vertex_shader_entry_point;
|
||||||
|
|
||||||
PrRhiShader *fragment_shader;
|
PrRhiShader *fragment_shader;
|
||||||
|
const char *fragment_shader_entry_point;
|
||||||
|
|
||||||
PrRhiVertexInputBindingArray vertex_bindings;
|
PrRhiVertexInputBindingArray vertex_bindings;
|
||||||
PrRhiVertexAttributeArray vertex_attributes;
|
PrRhiVertexAttributeArray vertex_attributes;
|
||||||
@@ -378,11 +409,22 @@ typedef struct PrRhiGraphicsPipelineDesc {
|
|||||||
b8 dynamic_viewport;
|
b8 dynamic_viewport;
|
||||||
b8 dynamic_scissor;
|
b8 dynamic_scissor;
|
||||||
|
|
||||||
|
PrRhiPolygonMode polygon_mode;
|
||||||
|
|
||||||
|
PrRhiCullMode cull_mode;
|
||||||
|
|
||||||
|
PrRhiFrontFace front_face;
|
||||||
|
|
||||||
|
f32 line_width;
|
||||||
|
|
||||||
|
PrRhiMultisampleCount multisample_count;
|
||||||
|
|
||||||
PrRhiPipelineLayout *layout;
|
PrRhiPipelineLayout *layout;
|
||||||
} PrRhiGraphicsPipelineDesc;
|
} PrRhiGraphicsPipelineDesc;
|
||||||
|
|
||||||
typedef struct PrRhiComputePipelineDesc {
|
typedef struct PrRhiComputePipelineDesc {
|
||||||
PrRhiShader *shader;
|
PrRhiShader *shader;
|
||||||
|
const char *shader_entry_point;
|
||||||
PrRhiPipelineLayout *layout;
|
PrRhiPipelineLayout *layout;
|
||||||
} PrRhiComputePipelineDesc;
|
} PrRhiComputePipelineDesc;
|
||||||
|
|
||||||
@@ -408,10 +450,6 @@ typedef struct PrRhiFenceDesc {
|
|||||||
b8 signaled;
|
b8 signaled;
|
||||||
} PrRhiFenceDesc;
|
} PrRhiFenceDesc;
|
||||||
|
|
||||||
typedef struct PrRhiCommandPoolDesc {
|
|
||||||
u32 queue_family_index;
|
|
||||||
} PrRhiCommandPoolDesc;
|
|
||||||
|
|
||||||
typedef struct PrRhiSwapchainDesc {
|
typedef struct PrRhiSwapchainDesc {
|
||||||
PrRhiSurface *surface;
|
PrRhiSurface *surface;
|
||||||
u32 width;
|
u32 width;
|
||||||
@@ -443,8 +481,7 @@ typedef u64 PrRhiDeviceAddress;
|
|||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|
||||||
typedef struct PrRhiContext {
|
typedef struct PrRhiContext {
|
||||||
WpAllocator main;
|
WpAllocator allocator;
|
||||||
WpAllocator scratch;
|
|
||||||
} PrRhiContext;
|
} PrRhiContext;
|
||||||
|
|
||||||
// --- Command buffer types ---
|
// --- Command buffer types ---
|
||||||
|
|||||||
+873
-746
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@
|
|||||||
#define PR_RHI_VK_H
|
#define PR_RHI_VK_H
|
||||||
|
|
||||||
#include "../pr_rhi_types.h"
|
#include "../pr_rhi_types.h"
|
||||||
|
#include <SDL3/SDL_video.h>
|
||||||
#include <volk/volk.h>
|
#include <volk/volk.h>
|
||||||
#include <vk_mem_alloc.h>
|
#include <vk_mem_alloc.h>
|
||||||
|
|
||||||
@@ -128,10 +129,9 @@ void prRhiDestroyInstanceVk(PrRhiInstance *inst);
|
|||||||
PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst);
|
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,
|
PrRhiPhysicalDeviceProperties prRhiGetPhysicalDevicePropertiesVk(PrRhiPhysicalDevice *pdev);
|
||||||
PrRhiPhysicalDeviceProperties *out);
|
|
||||||
|
|
||||||
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, void *window_handle);
|
PrRhiSurface *prRhiCreateSurfaceFromWindowVk(PrRhiInstance *inst, SDL_Window *window);
|
||||||
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface);
|
void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface);
|
||||||
|
|
||||||
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev,
|
PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev,
|
||||||
@@ -145,6 +145,7 @@ u32 prRhiGetQueueFamilyIndexVk(PrRhiDevice *device);
|
|||||||
|
|
||||||
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc);
|
PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc);
|
||||||
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain);
|
void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain);
|
||||||
|
u32 prRhiGetSwapchainImageCountVk(PrRhiSwapchain *swapchain);
|
||||||
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,
|
||||||
@@ -196,7 +197,7 @@ void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device,
|
|||||||
PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device,
|
PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device,
|
||||||
PrRhiDescriptorPool *pool,
|
PrRhiDescriptorPool *pool,
|
||||||
PrRhiDescriptorSetLayout *layout,
|
PrRhiDescriptorSetLayout *layout,
|
||||||
u32 variable_count);
|
WpU32Array variable_descriptor_counts);
|
||||||
void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool,
|
||||||
PrRhiDescriptorSet *set);
|
PrRhiDescriptorSet *set);
|
||||||
void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
|
void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes);
|
||||||
@@ -211,13 +212,12 @@ void prRhiResetFencesVk(PrRhiDevice *device, PrRhiFenceArray fences, u32 count);
|
|||||||
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device);
|
PrRhiSemaphore *prRhiCreateSemaphoreVk(PrRhiDevice *device);
|
||||||
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore);
|
void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore);
|
||||||
|
|
||||||
PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device,
|
PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device);
|
||||||
PrRhiCommandPoolDesc desc);
|
|
||||||
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool);
|
void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool);
|
||||||
PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
|
PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
|
||||||
u32 count);
|
u32 count);
|
||||||
void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool,
|
|
||||||
u32 count, PrRhiCommandBufferArray buffers);
|
void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool, PrRhiCommandBufferArray buffers);
|
||||||
|
|
||||||
void prRhiBeginCommandBufferVk(PrRhiCommandBuffer *cb);
|
void prRhiBeginCommandBufferVk(PrRhiCommandBuffer *cb);
|
||||||
void prRhiEndCommandBufferVk(PrRhiCommandBuffer *cb);
|
void prRhiEndCommandBufferVk(PrRhiCommandBuffer *cb);
|
||||||
@@ -243,8 +243,8 @@ void prRhiCmdBindDescriptorSetsVk(PrRhiCommandBuffer *cb, PrRhiPipelineBindPoint
|
|||||||
void prRhiCmdPushConstantsVk(PrRhiCommandBuffer *cb, PrRhiPipelineLayout *layout,
|
void prRhiCmdPushConstantsVk(PrRhiCommandBuffer *cb, PrRhiPipelineLayout *layout,
|
||||||
PrRhiShaderStage stage_flags, u32 offset, u32 size,
|
PrRhiShaderStage stage_flags, u32 offset, u32 size,
|
||||||
const void *data);
|
const void *data);
|
||||||
void prRhiCmdBindVertexBuffersVk(PrRhiCommandBuffer *cb, u32 first_binding,
|
void prRhiCmdBindVertexBuffersVk(PrRhiCommandBuffer *cb, u32 first_binding, PrRhiBufferArray buffers,
|
||||||
PrRhiBufferArray buffers, const u64 *offsets, u32 count);
|
WpU64Array offsets);
|
||||||
void prRhiCmdBindIndexBufferVk(PrRhiCommandBuffer *cb, PrRhiBuffer *buffer, u64 offset,
|
void prRhiCmdBindIndexBufferVk(PrRhiCommandBuffer *cb, PrRhiBuffer *buffer, u64 offset,
|
||||||
PrRhiIndexType index_type);
|
PrRhiIndexType index_type);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#define prRhiGetQueueFamilyIndex prRhiGetQueueFamilyIndexVk
|
#define prRhiGetQueueFamilyIndex prRhiGetQueueFamilyIndexVk
|
||||||
#define prRhiCreateSwapchain prRhiCreateSwapchainVk
|
#define prRhiCreateSwapchain prRhiCreateSwapchainVk
|
||||||
#define prRhiDestroySwapchain prRhiDestroySwapchainVk
|
#define prRhiDestroySwapchain prRhiDestroySwapchainVk
|
||||||
|
#define prRhiGetSwapchainImageCount prRhiGetSwapchainImageCountVk
|
||||||
#define prRhiAcquireNextImage prRhiAcquireNextImageVk
|
#define prRhiAcquireNextImage prRhiAcquireNextImageVk
|
||||||
#define prRhiPresent prRhiPresentVk
|
#define prRhiPresent prRhiPresentVk
|
||||||
#define prRhiRecreateSwapchain prRhiRecreateSwapchainVk
|
#define prRhiRecreateSwapchain prRhiRecreateSwapchainVk
|
||||||
|
|||||||
Reference in New Issue
Block a user