diff --git a/scratchpad/rhi/pr_rhi.h b/scratchpad/rhi/pr_rhi.h new file mode 100644 index 0000000..562644a --- /dev/null +++ b/scratchpad/rhi/pr_rhi.h @@ -0,0 +1,286 @@ +// vim:fileencoding=utf-8:foldmethod=marker +// +// Prism RHI — Render Hardware Interface +// +// Design based on the How To Vulkan tutorial (https://www.howtovulkan.com/) +// which uses these modern Vulkan features: +// - Vulkan 1.3 core (dynamic rendering, synchronization2, buffer device +// address) +// - Descriptor indexing (bindless with variable descriptor count) +// - Dynamic state (viewport, scissor) +// - VMA for memory management +// - Vulkan profiles for device selection +// - Slang for shader compilation (SPIR-V output) +// +// This RHI abstracts those features behind platform-agnostic types. +// Backend selection is compile-time — define PR_RHI_VULKAN, PR_RHI_D3D12, +// or PR_RHI_METAL at build time. +// +// Creation functions return the object directly or abort on failure. +// Only swapchain acquire/present return a b8 — the caller can detect +// out-of-date and recreate. + +#ifndef PR_RHI_H +#define PR_RHI_H + +#include "pr_rhi_types.h" + +// ====================================================================== +// Instance +// ====================================================================== + +PrRhiInstance *prRhiCreateInstance(PrRhiInstanceDesc desc, WpAllocator *alloc); +void prRhiDestroyInstance(PrRhiInstance *inst, WpAllocator *alloc); + +// ====================================================================== +// Physical device enumeration +// ====================================================================== + +PrRhiPhysicalDeviceArray prRhiGetPhysicalDevices(PrRhiInstance *inst, const WpAllocator *scratch); +void prRhiGetPhysicalDeviceName(PrRhiPhysicalDevice *pdev, WpStr8 *out); +void prRhiGetPhysicalDeviceDriverInfo(PrRhiPhysicalDevice *pdev, WpStr8 *out); + +// ====================================================================== +// Surface (platform-specific) +// ====================================================================== + +PrRhiSurface *prRhiCreateSurface(PrRhiInstance *inst, void *window_handle, WpAllocator *alloc); +void prRhiDestroySurface(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *alloc); +PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilities(PrRhiPhysicalDevice *pdev, + PrRhiSurface *surface); + +// ====================================================================== +// Device +// ====================================================================== + +PrRhiDevice *prRhiCreateDevice(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface, + PrRhiDeviceDesc desc, WpAllocator *alloc); +void prRhiDestroyDevice(PrRhiDevice *device, WpAllocator *alloc); +void prRhiDeviceWaitIdle(PrRhiDevice *device); + +// ====================================================================== +// Swapchain +// ====================================================================== + +PrRhiSwapchain *prRhiCreateSwapchain(PrRhiDevice *device, PrRhiSwapchainDesc desc, + WpAllocator *alloc); +void prRhiDestroySwapchain(PrRhiDevice *device, PrRhiSwapchain *swapchain, + WpAllocator *alloc); + +PrRhiSwapchainResult prRhiAcquireNextImage(PrRhiDevice *device, PrRhiSwapchain *swapchain, + PrRhiSemaphore *signal_semaphore, u32 *out_image_index); + +PrRhiSwapchainResult prRhiPresent(PrRhiDevice *device, PrRhiSwapchain *swapchain, + PrRhiSemaphore *wait_semaphore); + +void prRhiRecreateSwapchain(PrRhiDevice *device, PrRhiSwapchain **swapchain, + u32 width, u32 height, WpAllocator *alloc); + +PrRhiTexture *prRhiGetSwapchainTexture(PrRhiSwapchain *swapchain, u32 image_index); +PrRhiTexture *prRhiGetSwapchainDepthTexture(PrRhiSwapchain *swapchain); + +// ====================================================================== +// Buffers +// ====================================================================== + +PrRhiBuffer *prRhiCreateBuffer(PrRhiDevice *device, PrRhiBufferDesc desc, + WpAllocator *alloc); +void prRhiDestroyBuffer(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *alloc); + +void *prRhiBufferMap(PrRhiDevice *device, PrRhiBuffer *buffer); +void prRhiBufferUnmap(PrRhiDevice *device, PrRhiBuffer *buffer); + +PrRhiDeviceAddress prRhiGetBufferDeviceAddress(PrRhiDevice *device, PrRhiBuffer *buffer); + +// ====================================================================== +// Textures +// ====================================================================== + +PrRhiTexture *prRhiCreateTexture(PrRhiDevice *device, PrRhiTextureDesc desc, + WpAllocator *alloc); +void prRhiDestroyTexture(PrRhiDevice *device, PrRhiTexture *texture, + WpAllocator *alloc); + +// ====================================================================== +// Samplers +// ====================================================================== + +PrRhiSampler *prRhiCreateSampler(PrRhiDevice *device, PrRhiSamplerDesc desc, + WpAllocator *alloc); +void prRhiDestroySampler(PrRhiDevice *device, PrRhiSampler *sampler, + WpAllocator *alloc); + +// ====================================================================== +// Shaders (from SPIR-V) +// ====================================================================== + +PrRhiShader *prRhiCreateShader(PrRhiDevice *device, PrRhiShaderDesc desc, + WpAllocator *alloc); +void prRhiDestroyShader(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *alloc); + +// ====================================================================== +// Pipeline layouts +// ====================================================================== + +PrRhiPipelineLayout *prRhiCreatePipelineLayout(PrRhiDevice *device, + PrRhiPipelineLayoutDesc desc, + WpAllocator *alloc); +void prRhiDestroyPipelineLayout(PrRhiDevice *device, + PrRhiPipelineLayout *layout, + WpAllocator *alloc); + +// ====================================================================== +// Pipelines +// ====================================================================== + +PrRhiPipeline *prRhiCreateGraphicsPipeline(PrRhiDevice *device, + PrRhiGraphicsPipelineDesc desc, + WpAllocator *alloc); +PrRhiPipeline *prRhiCreateComputePipeline(PrRhiDevice *device, + PrRhiComputePipelineDesc desc, + WpAllocator *alloc); +void prRhiDestroyPipeline(PrRhiDevice *device, PrRhiPipeline *pipeline, + WpAllocator *alloc); + +// ====================================================================== +// Descriptor set layouts +// ====================================================================== + +PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayout(PrRhiDevice *device, + PrRhiDescriptorSetLayoutDesc desc, + WpAllocator *alloc); +void prRhiDestroyDescriptorSetLayout(PrRhiDevice *device, + PrRhiDescriptorSetLayout *layout, + WpAllocator *alloc); + +// ====================================================================== +// Descriptor pools +// ====================================================================== + +PrRhiDescriptorPool *prRhiCreateDescriptorPool(PrRhiDevice *device, + PrRhiDescriptorPoolDesc desc, + WpAllocator *alloc); +void prRhiDestroyDescriptorPool(PrRhiDevice *device, + PrRhiDescriptorPool *pool, + WpAllocator *alloc); + +// ====================================================================== +// Descriptor sets +// ====================================================================== + +PrRhiDescriptorSet *prRhiAllocateDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool, + PrRhiDescriptorSetLayout *layout, + u32 variable_count, WpAllocator *alloc); +void prRhiFreeDescriptorSet(PrRhiDevice *device, PrRhiDescriptorPool *pool, + PrRhiDescriptorSet *set, WpAllocator *alloc); +void prRhiUpdateDescriptorSet(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes); + +// ====================================================================== +// Fences and semaphores +// ====================================================================== + +PrRhiFence *prRhiCreateFence(PrRhiDevice *device, PrRhiFenceDesc desc, + WpAllocator *alloc); +void prRhiDestroyFence(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *alloc); + +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 *alloc); +void prRhiDestroySemaphore(PrRhiDevice *device, PrRhiSemaphore *semaphore, + WpAllocator *alloc); + +// ====================================================================== +// Command pools and command buffers +// ====================================================================== + +PrRhiCommandPool *prRhiCreateCommandPool(PrRhiDevice *device, PrRhiCommandPoolDesc desc, + WpAllocator *alloc); +void prRhiDestroyCommandPool(PrRhiDevice *device, PrRhiCommandPool *pool, + WpAllocator *alloc); + +PrRhiCommandBufferArray prRhiAllocateCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool, + u32 count, WpAllocator *alloc); +void prRhiFreeCommandBuffers(PrRhiDevice *device, PrRhiCommandPool *pool, + u32 count, PrRhiCommandBufferArray buffers); + +// ====================================================================== +// Command buffer recording +// ====================================================================== + +void prRhiBeginCommandBuffer(PrRhiCommandBuffer *cb); +void prRhiEndCommandBuffer(PrRhiCommandBuffer *cb); +void prRhiResetCommandBuffer(PrRhiCommandBuffer *cb); + +// --- Pipeline barriers (synchronization2 style) --- + +void prRhiCmdPipelineBarrier(PrRhiCommandBuffer *cb, + PrRhiImageMemoryBarrierArray image_barriers, + PrRhiBufferMemoryBarrierArray buffer_barriers); + +// --- Dynamic rendering --- + +void prRhiCmdBeginRendering(PrRhiCommandBuffer *cb, + PrRhiColorAttachmentArray color_attachments, + const PrRhiDepthAttachment *depth_attachment); +void prRhiCmdEndRendering(PrRhiCommandBuffer *cb); + +// --- Dynamic state --- + +void prRhiCmdSetViewport(PrRhiCommandBuffer *cb, f32 x, f32 y, f32 width, f32 height); +void prRhiCmdSetScissor(PrRhiCommandBuffer *cb, i32 x, i32 y, u32 width, u32 height); + +// --- Binding --- + +void prRhiCmdBindPipeline(PrRhiCommandBuffer *cb, PrRhiPipelineBindPoint bind_point, + PrRhiPipeline *pipeline); +void prRhiCmdBindDescriptorSets(PrRhiCommandBuffer *cb, PrRhiPipelineBindPoint bind_point, + PrRhiPipelineLayout *layout, u32 first_set, + PrRhiDescriptorSetArray sets); +void prRhiCmdPushConstants(PrRhiCommandBuffer *cb, PrRhiPipelineLayout *layout, + PrRhiShaderStage stage_flags, u32 offset, u32 size, + const void *data); + +// --- Vertex / index buffers --- + +void prRhiCmdBindVertexBuffers(PrRhiCommandBuffer *cb, u32 first_binding, + PrRhiBufferArray buffers, const u64 *offsets, u32 count); +void prRhiCmdBindIndexBuffer(PrRhiCommandBuffer *cb, PrRhiBuffer *buffer, u64 offset, + PrRhiIndexType index_type); + +// --- Draw calls --- + +void prRhiCmdDraw(PrRhiCommandBuffer *cb, u32 vertex_count, u32 instance_count, + u32 first_vertex, u32 first_instance); +void prRhiCmdDrawIndexed(PrRhiCommandBuffer *cb, u32 index_count, u32 instance_count, + u32 first_index, i32 vertex_offset, u32 first_instance); + +// --- Copy --- + +void prRhiCmdCopyBufferToImage(PrRhiCommandBuffer *cb, PrRhiBuffer *src, PrRhiTexture *dst); + +// ====================================================================== +// Queue submission +// ====================================================================== + +void prRhiQueueSubmit(PrRhiDevice *device, PrRhiCommandBuffer *cb, + PrRhiSemaphore *wait_semaphore, + PrRhiSemaphore *signal_semaphore, PrRhiFence *fence); + +// ====================================================================== +// Backend dispatch +// ====================================================================== + +#if defined(PR_RHI_VULKAN) +# include "vulkan/pr_rhi_vk_aliases.h" +#elif defined(PR_RHI_D3D12) +# error "D3D12 backend not yet implemented" +#elif defined(PR_RHI_METAL) +# error "Metal backend not yet implemented" +#else +# error "Define one of: PR_RHI_VULKAN, PR_RHI_D3D12, PR_RHI_METAL" +#endif + +#endif + diff --git a/scratchpad/rhi/pr_rhi_types.h b/scratchpad/rhi/pr_rhi_types.h new file mode 100644 index 0000000..7519560 --- /dev/null +++ b/scratchpad/rhi/pr_rhi_types.h @@ -0,0 +1,394 @@ +// vim:fileencoding=utf-8:foldmethod=marker +// +// Shared RHI types — enums, description structs, and opaque handle +// forward declarations. Included by both the umbrella pr_rhi.h and +// backend headers. + +#ifndef PR_RHI_TYPES_H +#define PR_RHI_TYPES_H + +#include "../../src/wapp/wapp.h" + +// ============================================================================ +// Opaque handle types +// ============================================================================ + +typedef struct PrRhiInstance PrRhiInstance; +typedef struct PrRhiPhysicalDevice PrRhiPhysicalDevice; +typedef struct PrRhiDevice PrRhiDevice; +typedef struct PrRhiSurface PrRhiSurface; +typedef struct PrRhiSwapchain PrRhiSwapchain; +typedef struct PrRhiBuffer PrRhiBuffer; +typedef struct PrRhiTexture PrRhiTexture; +typedef struct PrRhiSampler PrRhiSampler; +typedef struct PrRhiShader PrRhiShader; +typedef struct PrRhiPipelineLayout PrRhiPipelineLayout; +typedef struct PrRhiPipeline PrRhiPipeline; +typedef struct PrRhiDescriptorSetLayout PrRhiDescriptorSetLayout; +typedef struct PrRhiDescriptorPool PrRhiDescriptorPool; +typedef struct PrRhiDescriptorSet PrRhiDescriptorSet; +typedef struct PrRhiCommandPool PrRhiCommandPool; +typedef struct PrRhiCommandBuffer PrRhiCommandBuffer; +typedef struct PrRhiFence PrRhiFence; +typedef struct PrRhiSemaphore PrRhiSemaphore; + +// ============================================================================ +// Enums and flags +// ============================================================================ + +typedef enum PrRhiSwapchainResult { + PR_RHI_SWAPCHAIN_SUCCESS = 0, + PR_RHI_SWAPCHAIN_OUT_OF_DATE, +} PrRhiSwapchainResult; + +typedef enum PrRhiBufferUsage { + PR_RHI_BUFFER_USAGE_VERTEX = 1 << 0, + PR_RHI_BUFFER_USAGE_INDEX = 1 << 1, + PR_RHI_BUFFER_USAGE_UNIFORM = 1 << 2, + PR_RHI_BUFFER_USAGE_STORAGE = 1 << 3, + PR_RHI_BUFFER_USAGE_TRANSFER_SRC = 1 << 4, + PR_RHI_BUFFER_USAGE_TRANSFER_DST = 1 << 5, + PR_RHI_BUFFER_USAGE_SHADER_DEVICE_ADDRESS = 1 << 6, +} PrRhiBufferUsage; + +typedef enum PrRhiTextureUsage { + PR_RHI_TEXTURE_USAGE_SAMPLED = 1 << 0, + PR_RHI_TEXTURE_USAGE_COLOR_ATTACHMENT = 1 << 1, + PR_RHI_TEXTURE_USAGE_DEPTH_ATTACHMENT = 1 << 2, + PR_RHI_TEXTURE_USAGE_STORAGE = 1 << 3, + PR_RHI_TEXTURE_USAGE_TRANSFER_SRC = 1 << 4, + PR_RHI_TEXTURE_USAGE_TRANSFER_DST = 1 << 5, +} PrRhiTextureUsage; + +typedef enum PrRhiMemoryUsage { + PR_RHI_MEMORY_GPU_ONLY, + PR_RHI_MEMORY_CPU_TO_GPU, + PR_RHI_MEMORY_CPU_ONLY, +} PrRhiMemoryUsage; + +typedef enum PrRhiFormat { + PR_RHI_FORMAT_UNDEFINED, + PR_RHI_FORMAT_R8G8B8A8_SRGB, + PR_RHI_FORMAT_R8G8B8A8_UNORM, + PR_RHI_FORMAT_R16G16B16A16_SFLOAT, + PR_RHI_FORMAT_R32G32B32A32_SFLOAT, + PR_RHI_FORMAT_R32G32B32_SFLOAT, + PR_RHI_FORMAT_R32G32_SFLOAT, + PR_RHI_FORMAT_R32_SFLOAT, + PR_RHI_FORMAT_D24_UNORM_S8_UINT, + PR_RHI_FORMAT_D32_SFLOAT_S8_UINT, + PR_RHI_FORMAT_B8G8R8A8_SRGB, +} PrRhiFormat; + +typedef enum PrRhiImageLayout { + PR_RHI_LAYOUT_UNDEFINED, + PR_RHI_LAYOUT_ATTACHMENT_OPTIMAL, + PR_RHI_LAYOUT_READ_ONLY_OPTIMAL, + PR_RHI_LAYOUT_TRANSFER_SRC_OPTIMAL, + PR_RHI_LAYOUT_TRANSFER_DST_OPTIMAL, + PR_RHI_LAYOUT_PRESENT_SRC, + PR_RHI_LAYOUT_GENERAL, +} PrRhiImageLayout; + +typedef enum PrRhiShaderStage { + PR_RHI_SHADER_STAGE_VERTEX = 1 << 0, + PR_RHI_SHADER_STAGE_FRAGMENT = 1 << 1, + PR_RHI_SHADER_STAGE_COMPUTE = 1 << 2, +} PrRhiShaderStage; + +typedef enum PrRhiDescriptorType { + PR_RHI_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + PR_RHI_DESCRIPTOR_TYPE_STORAGE_IMAGE, + PR_RHI_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + PR_RHI_DESCRIPTOR_TYPE_STORAGE_BUFFER, +} PrRhiDescriptorType; + +typedef enum PrRhiDescriptorBindingFlag { + PR_RHI_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND = 1 << 0, + PR_RHI_DESCRIPTOR_BINDING_PARTIALLY_BOUND = 1 << 1, + PR_RHI_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT = 1 << 2, +} PrRhiDescriptorBindingFlag; + +typedef enum PrRhiPipelineBindPoint { + PR_RHI_PIPELINE_BIND_POINT_GRAPHICS, + PR_RHI_PIPELINE_BIND_POINT_COMPUTE, +} PrRhiPipelineBindPoint; + +typedef enum PrRhiCompareOp { + PR_RHI_COMPARE_OP_NEVER, + PR_RHI_COMPARE_OP_LESS, + PR_RHI_COMPARE_OP_EQUAL, + PR_RHI_COMPARE_OP_LESS_OR_EQUAL, + PR_RHI_COMPARE_OP_GREATER, + PR_RHI_COMPARE_OP_NOT_EQUAL, + PR_RHI_COMPARE_OP_GREATER_OR_EQUAL, + PR_RHI_COMPARE_OP_ALWAYS, +} PrRhiCompareOp; + +typedef enum PrRhiPrimitiveTopology { + PR_RHI_TOPOLOGY_POINT_LIST, + PR_RHI_TOPOLOGY_LINE_LIST, + PR_RHI_TOPOLOGY_LINE_STRIP, + PR_RHI_TOPOLOGY_TRIANGLE_LIST, + PR_RHI_TOPOLOGY_TRIANGLE_STRIP, + PR_RHI_TOPOLOGY_TRIANGLE_FAN, + PR_RHI_TOPOLOGY_LINE_LIST_WITH_ADJACENCY, + PR_RHI_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY, + PR_RHI_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY, + PR_RHI_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY, + PR_RHI_TOPOLOGY_PATCH_LIST, +} PrRhiPrimitiveTopology; + +typedef enum PrRhiIndexType { + PR_RHI_INDEX_TYPE_UINT16, + PR_RHI_INDEX_TYPE_UINT32, +} PrRhiIndexType; + +typedef enum PrRhiPresentMode { + PR_RHI_PRESENT_MODE_IMMEDIATE, + PR_RHI_PRESENT_MODE_FIFO, + PR_RHI_PRESENT_MODE_MAILBOX, +} PrRhiPresentMode; + +typedef enum PrRhiFilter { PR_RHI_FILTER_NEAREST, PR_RHI_FILTER_LINEAR } PrRhiFilter; +typedef enum PrRhiMipmapMode { PR_RHI_MIPMAP_MODE_NEAREST, PR_RHI_MIPMAP_MODE_LINEAR } PrRhiMipmapMode; +typedef enum PrRhiAddressMode { + PR_RHI_ADDRESS_MODE_REPEAT, + PR_RHI_ADDRESS_MODE_CLAMP_TO_EDGE, + PR_RHI_ADDRESS_MODE_CLAMP_TO_BORDER, +} PrRhiAddressMode; + +// ============================================================================ +// Element types (referenced by array aliases) +// ============================================================================ + +typedef struct PrRhiPushConstantRange { + PrRhiShaderStage stage_flags; + u32 offset; + u32 size; +} PrRhiPushConstantRange; + +typedef struct PrRhiVertexInputBinding { + u32 binding; + u32 stride; +} PrRhiVertexInputBinding; + +typedef struct PrRhiVertexAttribute { + u32 location; + u32 binding; + PrRhiFormat format; + u32 offset; +} PrRhiVertexAttribute; + +typedef struct PrRhiColorBlendAttachment { + u8 color_write_mask; +} PrRhiColorBlendAttachment; + +typedef struct PrRhiDescriptorSetLayoutBinding { + PrRhiDescriptorType type; + u32 descriptor_count; + PrRhiShaderStage stage_flags; + PrRhiDescriptorBindingFlag binding_flags; +} PrRhiDescriptorSetLayoutBinding; + +typedef struct PrRhiDescriptorPoolSize { + PrRhiDescriptorType type; + u32 descriptor_count; +} PrRhiDescriptorPoolSize; + +typedef struct PrRhiDescriptorImageInfo { + PrRhiTexture *texture; + PrRhiSampler *sampler; + PrRhiImageLayout layout; +} PrRhiDescriptorImageInfo; + +typedef struct PrRhiDescriptorBufferInfo { + PrRhiBuffer *buffer; + u64 offset; + u64 range; +} PrRhiDescriptorBufferInfo; + +typedef struct PrRhiImageMemoryBarrier { + PrRhiTexture *texture; + PrRhiImageLayout old_layout; + PrRhiImageLayout new_layout; +} PrRhiImageMemoryBarrier; + +typedef struct PrRhiBufferMemoryBarrier { + PrRhiBuffer *buffer; + u64 offset; + u64 size; +} PrRhiBufferMemoryBarrier; + +typedef struct PrRhiColorAttachment { + PrRhiTexture *texture; + PrRhiImageLayout layout; + b8 clear; + f32 clear_color[4]; +} PrRhiColorAttachment; + +// ============================================================================ +// Typed array aliases +// ============================================================================ + +// Opaque handle arrays (pointer-to-pointer) +typedef PrRhiPhysicalDevice **PrRhiPhysicalDeviceArray; +typedef PrRhiBuffer **PrRhiBufferArray; +typedef PrRhiTexture **PrRhiTextureArray; +typedef PrRhiFence **PrRhiFenceArray; +typedef PrRhiSemaphore **PrRhiSemaphoreArray; +typedef PrRhiCommandBuffer **PrRhiCommandBufferArray; +typedef PrRhiDescriptorSetLayout **PrRhiDescriptorSetLayoutArray; +typedef PrRhiDescriptorSet **PrRhiDescriptorSetArray; +typedef const char **PrRhiExtensionArray; + +// Value type arrays (contiguous structs/enums) +typedef PrRhiPushConstantRange *PrRhiPushConstantRangeArray; +typedef PrRhiVertexInputBinding *PrRhiVertexInputBindingArray; +typedef PrRhiVertexAttribute *PrRhiVertexAttributeArray; +typedef PrRhiFormat *PrRhiFormatArray; +typedef PrRhiColorBlendAttachment *PrRhiColorBlendAttachmentArray; +typedef PrRhiDescriptorSetLayoutBinding *PrRhiDescriptorSetLayoutBindingArray; +typedef PrRhiDescriptorPoolSize *PrRhiDescriptorPoolSizeArray; +typedef PrRhiDescriptorImageInfo *PrRhiDescriptorImageInfoArray; +typedef PrRhiDescriptorBufferInfo *PrRhiDescriptorBufferInfoArray; +typedef PrRhiImageMemoryBarrier *PrRhiImageMemoryBarrierArray; +typedef PrRhiBufferMemoryBarrier *PrRhiBufferMemoryBarrierArray; +typedef PrRhiColorAttachment *PrRhiColorAttachmentArray; +typedef struct PrRhiWriteDescriptorSet *PrRhiWriteDescriptorSetArray; + +// ============================================================================ +// Description structs +// ============================================================================ + +typedef struct PrRhiInstanceDesc { + const char *app_name; + u32 app_version; + PrRhiExtensionArray extra_extensions; +} PrRhiInstanceDesc; + +typedef struct PrRhiDeviceDesc { + PrRhiPresentMode present_mode; +} PrRhiDeviceDesc; + +typedef struct PrRhiBufferDesc { + u64 size; + PrRhiBufferUsage usage; + PrRhiMemoryUsage memory; +} PrRhiBufferDesc; + +typedef struct PrRhiTextureDesc { + PrRhiFormat format; + u32 width; + u32 height; + u32 mip_levels; + PrRhiTextureUsage usage; +} PrRhiTextureDesc; + +typedef struct PrRhiSamplerDesc { + PrRhiFilter mag_filter; + PrRhiFilter min_filter; + PrRhiMipmapMode mipmap_mode; + PrRhiAddressMode address_mode_u; + PrRhiAddressMode address_mode_v; + PrRhiAddressMode address_mode_w; + f32 max_anisotropy; + f32 min_lod; + f32 max_lod; +} PrRhiSamplerDesc; + +typedef struct PrRhiShaderDesc { + const void *spirv_code; + u64 spirv_size; +} PrRhiShaderDesc; + +typedef struct PrRhiPipelineLayoutDesc { + PrRhiDescriptorSetLayoutArray set_layouts; + PrRhiPushConstantRangeArray push_constant_ranges; +} PrRhiPipelineLayoutDesc; + +typedef struct PrRhiGraphicsPipelineDesc { + PrRhiShader *vertex_shader; + PrRhiShader *fragment_shader; + + PrRhiVertexInputBindingArray vertex_bindings; + PrRhiVertexAttributeArray vertex_attributes; + + PrRhiPrimitiveTopology topology; + + PrRhiFormatArray color_attachment_formats; + PrRhiFormat depth_attachment_format; + + b8 depth_test_enable; + b8 depth_write_enable; + PrRhiCompareOp depth_compare_op; + + PrRhiColorBlendAttachmentArray blend_attachments; + + b8 dynamic_viewport; + b8 dynamic_scissor; + + PrRhiPipelineLayout *layout; +} PrRhiGraphicsPipelineDesc; + +typedef struct PrRhiComputePipelineDesc { + PrRhiShader *shader; + PrRhiPipelineLayout *layout; +} PrRhiComputePipelineDesc; + +typedef struct PrRhiDescriptorSetLayoutDesc { + PrRhiDescriptorSetLayoutBindingArray bindings; +} PrRhiDescriptorSetLayoutDesc; + +typedef struct PrRhiDescriptorPoolDesc { + u32 max_sets; + PrRhiDescriptorPoolSizeArray pool_sizes; +} PrRhiDescriptorPoolDesc; + +typedef struct PrRhiWriteDescriptorSet { + PrRhiDescriptorSet *dst_set; + u32 dst_binding; + u32 dst_array_element; + PrRhiDescriptorType type; + PrRhiDescriptorImageInfoArray image_info; + PrRhiDescriptorBufferInfoArray buffer_info; +} PrRhiWriteDescriptorSet; + +typedef struct PrRhiFenceDesc { + b8 signaled; +} PrRhiFenceDesc; + +typedef struct PrRhiCommandPoolDesc { + u32 queue_family_index; +} PrRhiCommandPoolDesc; + +typedef struct PrRhiSwapchainDesc { + PrRhiSurface *surface; + u32 width; + u32 height; + b8 has_depth; +} PrRhiSwapchainDesc; + +typedef struct PrRhiSurfaceCapabilities { + u32 min_image_count; + u32 max_image_count; + u32 current_width; + u32 current_height; + u32 min_width; + u32 min_height; + u32 max_width; + u32 max_height; +} PrRhiSurfaceCapabilities; + +typedef u64 PrRhiDeviceAddress; + +// --- Command buffer types --- + +typedef struct PrRhiDepthAttachment { + PrRhiTexture *texture; + PrRhiImageLayout layout; + b8 clear; + f32 clear_depth; +} PrRhiDepthAttachment; + +#endif diff --git a/scratchpad/rhi/vulkan/pr_rhi_vk.h b/scratchpad/rhi/vulkan/pr_rhi_vk.h new file mode 100644 index 0000000..bebec69 --- /dev/null +++ b/scratchpad/rhi/vulkan/pr_rhi_vk.h @@ -0,0 +1,262 @@ +// vim:fileencoding=utf-8:foldmethod=marker +// +// Vulkan backend declarations — concrete implementations of the RHI. +// Backend .c files include this header directly (never the umbrella pr_rhi.h) +// to avoid the #define aliases. + +#ifndef PR_RHI_VK_H +#define PR_RHI_VK_H + +#include "../pr_rhi_types.h" + +// ============================================================================ +// Opaque struct definitions — visible only to the backend implementation. +// ============================================================================ + +struct PrRhiInstance { + void *handle; // VkInstance + void *debug_messenger; // VkDebugUtilsMessengerEXT +}; + +struct PrRhiPhysicalDevice { + void *handle; // VkPhysicalDevice + PrRhiInstance *instance; +}; + +struct PrRhiDevice { + void *handle; // VkDevice + void *queue; // VkQueue + u32 queue_family_index; + void *allocator; // VmaAllocator +}; + +struct PrRhiSurface { + void *handle; // VkSurfaceKHR +}; + +struct PrRhiSwapchain { + PrRhiDevice *device; + void *handle; // VkSwapchainKHR + u32 image_count; + PrRhiTexture **images; + PrRhiTexture *depth; + u32 format; // VkFormat + u32 width; + u32 height; +}; + +struct PrRhiBuffer { + void *handle; // VkBuffer + void *allocation; // VmaAllocation + u64 device_address; + u64 size; + void *mapped_data; +}; + +struct PrRhiTexture { + void *image; // VkImage + void *view; // VkImageView + void *allocation; // VmaAllocation +}; + +struct PrRhiSampler { + void *handle; // VkSampler +}; + +struct PrRhiShader { + void *handle; // VkShaderModule +}; + +struct PrRhiPipelineLayout { + void *handle; // VkPipelineLayout +}; + +struct PrRhiPipeline { + void *handle; // VkPipeline +}; + +struct PrRhiDescriptorSetLayout { + void *handle; // VkDescriptorSetLayout +}; + +struct PrRhiDescriptorPool { + void *handle; // VkDescriptorPool +}; + +struct PrRhiDescriptorSet { + void *handle; // VkDescriptorSet +}; + +struct PrRhiCommandPool { + void *handle; // VkCommandPool +}; + +struct PrRhiCommandBuffer { + void *handle; // VkCommandBuffer +}; + +struct PrRhiFence { + void *handle; // VkFence +}; + +struct PrRhiSemaphore { + void *handle; // VkSemaphore +}; + +// ============================================================================ +// Function declarations +// ============================================================================ + +PrRhiInstance *prRhiCreateInstanceVk(PrRhiInstanceDesc desc, WpAllocator *alloc); +void prRhiDestroyInstanceVk(PrRhiInstance *inst, WpAllocator *alloc); + +PrRhiPhysicalDeviceArray prRhiGetPhysicalDevicesVk(PrRhiInstance *inst, const WpAllocator *scratch); +void prRhiGetPhysicalDeviceNameVk(PrRhiPhysicalDevice *pdev, WpStr8 *out); +void prRhiGetPhysicalDeviceDriverInfoVk(PrRhiPhysicalDevice *pdev, WpStr8 *out); + +PrRhiSurface *prRhiCreateSurfaceVk(PrRhiInstance *inst, void *window_handle, WpAllocator *alloc); +void prRhiDestroySurfaceVk(PrRhiInstance *inst, PrRhiSurface *surface, WpAllocator *alloc); + +PrRhiSurfaceCapabilities prRhiGetSurfaceCapabilitiesVk(PrRhiPhysicalDevice *pdev, + PrRhiSurface *surface); + +PrRhiDevice *prRhiCreateDeviceVk(PrRhiPhysicalDevice *pdev, PrRhiSurface *surface, + PrRhiDeviceDesc desc, WpAllocator *alloc); +void prRhiDestroyDeviceVk(PrRhiDevice *device, WpAllocator *alloc); +void prRhiDeviceWaitIdleVk(PrRhiDevice *device); + +PrRhiSwapchain *prRhiCreateSwapchainVk(PrRhiDevice *device, PrRhiSwapchainDesc desc, + WpAllocator *alloc); +void prRhiDestroySwapchainVk(PrRhiDevice *device, PrRhiSwapchain *swapchain, + WpAllocator *alloc); +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 *alloc); +PrRhiTexture *prRhiGetSwapchainTextureVk(PrRhiSwapchain *swapchain, u32 image_index); +PrRhiTexture *prRhiGetSwapchainDepthTextureVk(PrRhiSwapchain *swapchain); + +PrRhiBuffer *prRhiCreateBufferVk(PrRhiDevice *device, PrRhiBufferDesc desc, + WpAllocator *alloc); +void prRhiDestroyBufferVk(PrRhiDevice *device, PrRhiBuffer *buffer, WpAllocator *alloc); +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 *alloc); +void prRhiDestroyTextureVk(PrRhiDevice *device, PrRhiTexture *texture, + WpAllocator *alloc); + +PrRhiSampler *prRhiCreateSamplerVk(PrRhiDevice *device, PrRhiSamplerDesc desc, + WpAllocator *alloc); +void prRhiDestroySamplerVk(PrRhiDevice *device, PrRhiSampler *sampler, + WpAllocator *alloc); + +PrRhiShader *prRhiCreateShaderVk(PrRhiDevice *device, PrRhiShaderDesc desc, + WpAllocator *alloc); +void prRhiDestroyShaderVk(PrRhiDevice *device, PrRhiShader *shader, WpAllocator *alloc); + +PrRhiPipelineLayout *prRhiCreatePipelineLayoutVk(PrRhiDevice *device, + PrRhiPipelineLayoutDesc desc, + WpAllocator *alloc); +void prRhiDestroyPipelineLayoutVk(PrRhiDevice *device, + PrRhiPipelineLayout *layout, + WpAllocator *alloc); + +PrRhiPipeline *prRhiCreateGraphicsPipelineVk(PrRhiDevice *device, + PrRhiGraphicsPipelineDesc desc, + WpAllocator *alloc); +PrRhiPipeline *prRhiCreateComputePipelineVk(PrRhiDevice *device, + PrRhiComputePipelineDesc desc, + WpAllocator *alloc); +void prRhiDestroyPipelineVk(PrRhiDevice *device, PrRhiPipeline *pipeline, + WpAllocator *alloc); + +PrRhiDescriptorSetLayout *prRhiCreateDescriptorSetLayoutVk(PrRhiDevice *device, + PrRhiDescriptorSetLayoutDesc desc, + WpAllocator *alloc); +void prRhiDestroyDescriptorSetLayoutVk(PrRhiDevice *device, + PrRhiDescriptorSetLayout *layout, + WpAllocator *alloc); + +PrRhiDescriptorPool *prRhiCreateDescriptorPoolVk(PrRhiDevice *device, + PrRhiDescriptorPoolDesc desc, + WpAllocator *alloc); +void prRhiDestroyDescriptorPoolVk(PrRhiDevice *device, + PrRhiDescriptorPool *pool, + WpAllocator *alloc); + +PrRhiDescriptorSet *prRhiAllocateDescriptorSetVk(PrRhiDevice *device, + PrRhiDescriptorPool *pool, + PrRhiDescriptorSetLayout *layout, + u32 variable_count, WpAllocator *alloc); +void prRhiFreeDescriptorSetVk(PrRhiDevice *device, PrRhiDescriptorPool *pool, + PrRhiDescriptorSet *set, WpAllocator *alloc); +void prRhiUpdateDescriptorSetVk(PrRhiDevice *device, PrRhiWriteDescriptorSetArray writes); + +PrRhiFence *prRhiCreateFenceVk(PrRhiDevice *device, PrRhiFenceDesc desc, + WpAllocator *alloc); +void prRhiDestroyFenceVk(PrRhiDevice *device, PrRhiFence *fence, WpAllocator *alloc); + +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 *alloc); +void prRhiDestroySemaphoreVk(PrRhiDevice *device, PrRhiSemaphore *semaphore, + WpAllocator *alloc); + +PrRhiCommandPool *prRhiCreateCommandPoolVk(PrRhiDevice *device, + PrRhiCommandPoolDesc desc, + WpAllocator *alloc); +void prRhiDestroyCommandPoolVk(PrRhiDevice *device, PrRhiCommandPool *pool, + WpAllocator *alloc); +PrRhiCommandBufferArray prRhiAllocateCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool, + u32 count, WpAllocator *alloc); +void prRhiFreeCommandBuffersVk(PrRhiDevice *device, PrRhiCommandPool *pool, + u32 count, PrRhiCommandBufferArray buffers); + +void prRhiBeginCommandBufferVk(PrRhiCommandBuffer *cb); +void prRhiEndCommandBufferVk(PrRhiCommandBuffer *cb); +void prRhiResetCommandBufferVk(PrRhiCommandBuffer *cb); + +void prRhiCmdPipelineBarrierVk(PrRhiCommandBuffer *cb, + PrRhiImageMemoryBarrierArray image_barriers, + PrRhiBufferMemoryBarrierArray buffer_barriers); + +void prRhiCmdBeginRenderingVk(PrRhiCommandBuffer *cb, + PrRhiColorAttachmentArray color_attachments, + const PrRhiDepthAttachment *depth_attachment); +void prRhiCmdEndRenderingVk(PrRhiCommandBuffer *cb); + +void prRhiCmdSetViewportVk(PrRhiCommandBuffer *cb, f32 x, f32 y, f32 width, f32 height); +void prRhiCmdSetScissorVk(PrRhiCommandBuffer *cb, i32 x, i32 y, u32 width, u32 height); + +void prRhiCmdBindPipelineVk(PrRhiCommandBuffer *cb, PrRhiPipelineBindPoint bind_point, + PrRhiPipeline *pipeline); +void prRhiCmdBindDescriptorSetsVk(PrRhiCommandBuffer *cb, PrRhiPipelineBindPoint bind_point, + PrRhiPipelineLayout *layout, u32 first_set, + PrRhiDescriptorSetArray sets); +void prRhiCmdPushConstantsVk(PrRhiCommandBuffer *cb, PrRhiPipelineLayout *layout, + PrRhiShaderStage stage_flags, u32 offset, u32 size, + const void *data); +void prRhiCmdBindVertexBuffersVk(PrRhiCommandBuffer *cb, u32 first_binding, + PrRhiBufferArray buffers, const u64 *offsets, u32 count); +void prRhiCmdBindIndexBufferVk(PrRhiCommandBuffer *cb, PrRhiBuffer *buffer, u64 offset, + PrRhiIndexType index_type); + +void prRhiCmdDrawVk(PrRhiCommandBuffer *cb, u32 vertex_count, u32 instance_count, + u32 first_vertex, u32 first_instance); +void prRhiCmdDrawIndexedVk(PrRhiCommandBuffer *cb, u32 index_count, u32 instance_count, + u32 first_index, i32 vertex_offset, u32 first_instance); + +void prRhiCmdCopyBufferToImageVk(PrRhiCommandBuffer *cb, PrRhiBuffer *src, PrRhiTexture *dst); + +void prRhiQueueSubmitVk(PrRhiDevice *device, PrRhiCommandBuffer *cb, + PrRhiSemaphore *wait_semaphore, + PrRhiSemaphore *signal_semaphore, PrRhiFence *fence); + +#endif diff --git a/scratchpad/rhi/vulkan/pr_rhi_vk_aliases.h b/scratchpad/rhi/vulkan/pr_rhi_vk_aliases.h new file mode 100644 index 0000000..55781a2 --- /dev/null +++ b/scratchpad/rhi/vulkan/pr_rhi_vk_aliases.h @@ -0,0 +1,76 @@ +// vim:fileencoding=utf-8:foldmethod=marker + +#ifndef PR_RHI_VK_ALIASES_H +#define PR_RHI_VK_ALIASES_H + +#include "pr_rhi_vk.h" + +#define prRhiCreateInstance prRhiCreateInstanceVk +#define prRhiDestroyInstance prRhiDestroyInstanceVk +#define prRhiGetPhysicalDevices prRhiGetPhysicalDevicesVk +#define prRhiGetPhysicalDeviceName prRhiGetPhysicalDeviceNameVk +#define prRhiGetPhysicalDeviceDriverInfo prRhiGetPhysicalDeviceDriverInfoVk +#define prRhiCreateSurface prRhiCreateSurfaceVk +#define prRhiDestroySurface prRhiDestroySurfaceVk +#define prRhiCreateDevice prRhiCreateDeviceVk +#define prRhiDestroyDevice prRhiDestroyDeviceVk +#define prRhiDeviceWaitIdle prRhiDeviceWaitIdleVk +#define prRhiCreateSwapchain prRhiCreateSwapchainVk +#define prRhiDestroySwapchain prRhiDestroySwapchainVk +#define prRhiAcquireNextImage prRhiAcquireNextImageVk +#define prRhiPresent prRhiPresentVk +#define prRhiRecreateSwapchain prRhiRecreateSwapchainVk +#define prRhiGetSwapchainTexture prRhiGetSwapchainTextureVk +#define prRhiGetSwapchainDepthTexture prRhiGetSwapchainDepthTextureVk +#define prRhiCreateBuffer prRhiCreateBufferVk +#define prRhiDestroyBuffer prRhiDestroyBufferVk +#define prRhiBufferMap prRhiBufferMapVk +#define prRhiBufferUnmap prRhiBufferUnmapVk +#define prRhiGetBufferDeviceAddress prRhiGetBufferDeviceAddressVk +#define prRhiCreateTexture prRhiCreateTextureVk +#define prRhiDestroyTexture prRhiDestroyTextureVk +#define prRhiCreateSampler prRhiCreateSamplerVk +#define prRhiDestroySampler prRhiDestroySamplerVk +#define prRhiCreateShader prRhiCreateShaderVk +#define prRhiDestroyShader prRhiDestroyShaderVk +#define prRhiCreatePipelineLayout prRhiCreatePipelineLayoutVk +#define prRhiDestroyPipelineLayout prRhiDestroyPipelineLayoutVk +#define prRhiCreateGraphicsPipeline prRhiCreateGraphicsPipelineVk +#define prRhiCreateComputePipeline prRhiCreateComputePipelineVk +#define prRhiDestroyPipeline prRhiDestroyPipelineVk +#define prRhiCreateDescriptorSetLayout prRhiCreateDescriptorSetLayoutVk +#define prRhiDestroyDescriptorSetLayout prRhiDestroyDescriptorSetLayoutVk +#define prRhiCreateDescriptorPool prRhiCreateDescriptorPoolVk +#define prRhiDestroyDescriptorPool prRhiDestroyDescriptorPoolVk +#define prRhiAllocateDescriptorSet prRhiAllocateDescriptorSetVk +#define prRhiFreeDescriptorSet prRhiFreeDescriptorSetVk +#define prRhiUpdateDescriptorSet prRhiUpdateDescriptorSetVk +#define prRhiCreateFence prRhiCreateFenceVk +#define prRhiDestroyFence prRhiDestroyFenceVk +#define prRhiWaitForFences prRhiWaitForFencesVk +#define prRhiResetFences prRhiResetFencesVk +#define prRhiCreateSemaphore prRhiCreateSemaphoreVk +#define prRhiDestroySemaphore prRhiDestroySemaphoreVk +#define prRhiCreateCommandPool prRhiCreateCommandPoolVk +#define prRhiDestroyCommandPool prRhiDestroyCommandPoolVk +#define prRhiAllocateCommandBuffers prRhiAllocateCommandBuffersVk +#define prRhiFreeCommandBuffers prRhiFreeCommandBuffersVk +#define prRhiBeginCommandBuffer prRhiBeginCommandBufferVk +#define prRhiEndCommandBuffer prRhiEndCommandBufferVk +#define prRhiResetCommandBuffer prRhiResetCommandBufferVk +#define prRhiCmdPipelineBarrier prRhiCmdPipelineBarrierVk +#define prRhiCmdBeginRendering prRhiCmdBeginRenderingVk +#define prRhiCmdEndRendering prRhiCmdEndRenderingVk +#define prRhiCmdSetViewport prRhiCmdSetViewportVk +#define prRhiCmdSetScissor prRhiCmdSetScissorVk +#define prRhiCmdBindPipeline prRhiCmdBindPipelineVk +#define prRhiCmdBindDescriptorSets prRhiCmdBindDescriptorSetsVk +#define prRhiCmdPushConstants prRhiCmdPushConstantsVk +#define prRhiCmdBindVertexBuffers prRhiCmdBindVertexBuffersVk +#define prRhiCmdBindIndexBuffer prRhiCmdBindIndexBufferVk +#define prRhiCmdDraw prRhiCmdDrawVk +#define prRhiCmdDrawIndexed prRhiCmdDrawIndexedVk +#define prRhiCmdCopyBufferToImage prRhiCmdCopyBufferToImageVk +#define prRhiQueueSubmit prRhiQueueSubmitVk + +#endif