diff options
| author | Vasco <[email protected]> | 2026-08-12 17:47:50 +0100 |
|---|---|---|
| committer | Vasco <[email protected]> | 2026-08-12 17:47:50 +0100 |
| commit | 95e3e76fd9c789cbf2d4409ef49456addc71643f (patch) | |
| tree | 34161614f5f0ae909f58eb5e58a2ffd26c2f0e9f /rend.h | |
Diffstat (limited to 'rend.h')
| -rw-r--r-- | rend.h | 290 |
1 files changed, 290 insertions, 0 deletions
@@ -0,0 +1,290 @@ +/* =========================================================================== + * REND - Renderer Library - Copyright (c) 2026 Vasco Alves + * + * DESCRIPTION: + * - High level graphics rendering API around Vulkan 1.4 + * - Pushes data to the GPU in a highly configurable and STABLE fashion. + * - Is not responsible for initializing windows. + * - Is not responsible for compiling shaders. + * - Depends on PODIUM to be cross-platform. + * + * =========================================================================== */ + +#ifndef _REND_H_ +#define _REND_H_ + +#define REND_MAJOR 1 // breaking API changes +#define REND_MINOR 0 // non-breaking features +#define REND_PATCH 1 // non-breaking patches and bug fixes + +#define P_MODULE_VULKAN +#define P_MODULE_MATH +#include "podium.h" + +typedef struct rend_renderer_t* RendRenderer; // renderer target handle +typedef struct rend_pipeline_t* RendPipeline; // represents a baked shader + gpu pipeline state (blend mode, depth, vertex format) + +typedef struct RendMemory RendMemory; +typedef struct RendSpecs RendSpecs; +typedef struct RendBuffer RendBuffer; +typedef struct RendTexture RendTexture; + +/* Typedef enums as 16 bit unsigned integers */ +typedef uint16_t RendBackendType; +typedef uint16_t RendLifetime; +typedef uint16_t RendFormat; +typedef uint16_t RendTopology; +typedef uint16_t RendCullMode; +typedef uint16_t RendPolygonMode; +typedef uint16_t RendBufferType; + +typedef enum RendInputRate { REND_INPUT_RATE_INSTANCE, REND_INPUT_RATE_VERTEX } RendInputRate; +typedef enum RendIndexType { REND_INDEX_UINT16 = 16, REND_INDEX_UINT32 = 32 } RendIndexType; + +typedef struct { + uint64_t binding; + uint64_t stride; + uint8_t input_rate; +} RendVertexBinding; + +typedef struct { + uint64_t location; + uint64_t binding; + uint64_t offset; + RendFormat format; +} RendVertexAttributes; + +typedef struct { + uint32_t offset; + uint32_t size; +} RendPushConstantInfo; + +#define REND_MAX_BINDINGS 8 + +typedef struct { + uint32_t ubo_bindings[REND_MAX_BINDINGS]; + uint32_t ubo_array_sizes[REND_MAX_BINDINGS]; + uint32_t ubo_binding_count; + + uint32_t ssbo_bindings[REND_MAX_BINDINGS]; + uint32_t ssbo_array_sizes[REND_MAX_BINDINGS]; + uint32_t ssbo_binding_count; + + uint32_t texture_bindings[REND_MAX_BINDINGS]; + uint32_t texture_array_sizes[REND_MAX_BINDINGS]; + uint32_t texture_binding_count; +} RendBindingInfo; // the binding of rend: rebirth + +/* Clean up */ +extern void rend_quit(void); // Will free ALL resources created by the library such as RendRenderer, RendPipeline, RendBuffer and RendTexture. + +/* Renderer */ +extern RendRenderer rend_renderer_create(P_Window*, RendBackendType backend, void* device, bool vsync, RendBindingInfo *bind_info); // Create Renderer that renders to a target window with +extern void rend_renderer_destroy(RendRenderer renderer); // Destroy renderer. Unless you need to freely create and destroy renderers, you can rely on rend_quit to clean up. +extern bool rend_renderer_frame_begin(RendRenderer renderer); // May fail. Acquires backbuffer and starts recording commands! +extern void rend_renderer_frame_end(RendRenderer renderer, float *delta); // Stops recording commands and presents the contents to the screen. + +/* Write to Descriptor Sets */ +extern void rend_descriptor_write_ubo(RendRenderer, RendBuffer ubo, uint32_t binding, uint32_t slot); +extern void rend_descriptor_write_ssbo(RendRenderer, RendBuffer ssbo, uint32_t binding, uint32_t slot); +extern void rend_descriptor_write_texture(RendRenderer, RendTexture *texture, uint32_t binding, uint32_t slot); // Writes texture to a slot in the texture array. Does not need to be in the main render loop. + +/* Buffers */ +extern RendBuffer rend_buffer_create(RendRenderer renderer, size_t size, RendBufferType type, bool gpu); +extern void rend_buffer_destroy(RendBuffer *buffer); +extern void rend_buffer_write(RendRenderer renderer, RendBuffer *buffer, const void *data, size_t size, size_t offset); +extern void rend_buffer_copy(RendRenderer renderer, RendBuffer *dest, size_t dest_offset, RendBuffer *src, size_t src_offset, size_t bytes); +extern uint64_t rend_buffer_address(RendBuffer *buffer); + +/* Textures */ +extern RendTexture rend_texture_create(RendRenderer renderer, uint32_t width, uint32_t height, uint32_t depth, uint32_t mip_levels, uint32_t layers, RendFormat format); // Create a texture. +extern RendTexture rend_texture_create_from_data(RendRenderer renderer, const void *data, uint32_t width, uint32_t height, RendFormat format); // Create texture and copy data to it immediately. +extern void rend_texture_destroy(RendRenderer renderer, RendTexture *texture); // Destroy texture. Does not deallocate it's memory from the bump allocator. +extern void rend_texture_copy_data(RendRenderer renderer, RendTexture *texture, const void *data, size_t size); // Copy data to texture. MUST be the same size as the format expects (width x height x sizeof format). +extern void rend_texture_copy_buffer(RendRenderer renderer, RendTexture *texture, RendBuffer *buffer); // Copy buffer to texture. + +/* Create, Configure, and Destroy Rendering Pipelines */ +extern RendPipeline rend_pipeline_create_graphics_spirv(RendRenderer renderer, uint8_t *vertex_bytes, size_t vertex_size, uint8_t *frag_bytes, size_t frag_size, const RendVertexBinding *vertex_bindings, uint32_t vertex_binding_count, const RendVertexAttributes *vertex_attributes, uint32_t vertex_attribute_count, const RendPushConstantInfo *push_constants, uint32_t push_constant_count, RendPolygonMode polygon_mode, RendCullMode cull_mode, RendTopology topology, RendFormat color_format, bool depth_test_enable); // Create a pipeline for a renderer using a configuration handle. +extern RendPipeline rend_pipeline_create_graphics_bindless_spirv(RendRenderer renderer, uint8_t *vertex_bytes, size_t vertex_size, uint8_t *frag_bytes, size_t frag_size, const RendPushConstantInfo *push_constants, uint32_t push_constant_count, RendPolygonMode polygon_mode, RendCullMode cull_mode, RendTopology topology, RendFormat color_format, bool depth_test_enable); // Create a pipeline for a renderer using a configuration handle. +extern RendPipeline rend_pipeline_create_meshlet_spirv(RendRenderer renderer, uint8_t *meshlet_bytes, size_t meshlet_size, uint8_t *frag_bytes, size_t frag_size, const RendPushConstantInfo *push_constants, uint32_t push_constant_count, RendPolygonMode polygon_mode, RendCullMode cull_mode, bool depth_test_enable); // Creates a meshlet rendering pipeline. +extern RendPipeline rend_pipeline_create_compute_spirv(RendRenderer renderer, const uint8_t *compute_bytes, size_t compute_size, const RendPushConstantInfo *push_constants, uint32_t push_constant_count); // Create a compute pipeline. + +/* Commands */ +extern void rend_cmd_render_begin(RendRenderer renderer, float r, float g, float b, float a); // Begin render pass to default target the window. +extern void rend_cmd_render_begin_texture(RendRenderer renderer, RendTexture *texture); // Begin render pass with a texture as the target. +extern void rend_cmd_render_end(RendRenderer renderer); // End render pass. +extern void rend_cmd_render_end_texture(RendRenderer renderer, RendTexture *texture); // End render pass that targets texture. Transition texture to read optimal format. +extern void rend_cmd_bind_pipeline(RendPipeline pipeline); // Bind the pipeline to this frame. +extern void rend_cmd_bind_vertex_buffer(RendPipeline pipeline, uint32_t binding, RendBuffer buffer, size_t offset); // Bind vertex buffer to this graphics pipeline. +extern void rend_cmd_bind_index_buffer(RendPipeline pipeline, RendBuffer buffer, size_t offset, RendIndexType index_type); // Bind index buffer to this graphics pipeline. +extern void rend_cmd_push_constants(RendPipeline pipeline, void *push_data, size_t size); // Send push constants to this pipeline / command buffer. +extern void rend_cmd_dispatch(RendPipeline pipeline, uint32_t x, uint32_t y, uint32_t z); // Dispatch compute commands to group with dimensions x, y, z! +extern void rend_cmd_draw(RendPipeline pipeline, size_t count, uint32_t instance_count); // Calls draw command on the pipeline. +extern void rend_cmd_draw_indexed(RendPipeline pipeline, uint32_t index_count, uint32_t first_index, int32_t vertex_offset, uint32_t instance_count); // Draw the pipeline using indexed rendering. +extern void rend_cmd_blit(RendRenderer renderer, RendTexture *src, RendTexture *dst, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, uint32_t dst_x, uint32_t dst_y, uint32_t dst_w, uint32_t dst_h); // Blit a section of one texture onto another texture. + +enum RendBackendType_t { + REND_BACKEND_AUTO = 0, + REND_BACKEND_VULKAN_14, + REND_BACKEND_COUNT +}; + +enum RendLifetime_t { + REND_LIFETIME_FRAME = 0, + REND_LIFETIME_PERMANENT +}; + +enum RendTopology_t { + REND_TOPOLOGY_TRIANGLE_LIST = 0, + REND_TOPOLOGY_TRIANGLE_STRIP, + REND_TOPOLOGY_LINE_LIST, + REND_TOPOLOGY_LINE_STRIP, + REND_TOPOLOGY_POINT_LIST, +}; + +enum RendCullMode_t { + REND_CULL_MODE_NONE = 0, + REND_CULL_MODE_FRONT, + REND_CULL_MODE_BACK, + REND_CULL_MODE_FRONT_AND_BACK, +}; + +enum RendPolygonMode_t { + REND_POLYGON_MODE_FILL = 0, + REND_POLYGON_MODE_LINE, + REND_POLYGON_MODE_POINT, +}; + +enum RendFormat_t { + REND_FORMAT_UNDEFINED = 0, + REND_FORMAT_R8_UNORM, + REND_FORMAT_R8G8_UNORM, + REND_FORMAT_R8G8B8A8_UNORM, + REND_FORMAT_B8G8R8A8_UNORM, + + REND_FORMAT_R8G8B8A8_SRGB, + REND_FORMAT_B8G8R8A8_SRGB, + + REND_FORMAT_R32_SFLOAT, + REND_FORMAT_R32G32_SFLOAT, + REND_FORMAT_R32G32B32_SFLOAT, + REND_FORMAT_R32G32B32A32_SFLOAT, + + /* useful aliases */ + REND_FORMAT_1_SFLOAT32 = REND_FORMAT_R32_SFLOAT, + REND_FORMAT_2_SFLOAT32 = REND_FORMAT_R32G32_SFLOAT, + REND_FORMAT_3_SFLOAT32 = REND_FORMAT_R32G32B32_SFLOAT, + REND_FORMAT_4_SFLOAT32 = REND_FORMAT_R32G32B32A32_SFLOAT, + + REND_FORMAT_R16_SFLOAT, + REND_FORMAT_R16G16_SFLOAT, + REND_FORMAT_R16G16B16A16_SFLOAT, + + REND_FORMAT_R8G8B8A8_UINT, + REND_FORMAT_R16G16B16A16_UINT, + REND_FORMAT_R32_UINT, + REND_FORMAT_R32_SINT, + REND_FORMAT_R32G32B32A32_UINT, + + REND_FORMAT_D32_SFLOAT, + REND_FORMAT_D24_UNORM_S8_UINT, + REND_FORMAT_D32_SFLOAT_S8_UINT, + + REND_FORMAT_COUNT +}; + +static size_t rend_format_size[REND_FORMAT_COUNT] = { + [REND_FORMAT_UNDEFINED] = 0, + + [REND_FORMAT_R8_UNORM] = 1, + [REND_FORMAT_R8G8_UNORM] = 2, + [REND_FORMAT_R8G8B8A8_UNORM] = 4, + [REND_FORMAT_B8G8R8A8_UNORM] = 4, + + [REND_FORMAT_R8G8B8A8_SRGB] = 4, + [REND_FORMAT_B8G8R8A8_SRGB] = 4, + + [REND_FORMAT_R32_SFLOAT] = 4, + [REND_FORMAT_R32G32_SFLOAT] = 8, + [REND_FORMAT_R32G32B32_SFLOAT] = 12, + [REND_FORMAT_R32G32B32A32_SFLOAT] = 16, + + [REND_FORMAT_R16_SFLOAT] = 2, + [REND_FORMAT_R16G16_SFLOAT] = 4, + [REND_FORMAT_R16G16B16A16_SFLOAT] = 8, + + [REND_FORMAT_R8G8B8A8_UINT] = 4, + [REND_FORMAT_R16G16B16A16_UINT] = 8, + [REND_FORMAT_R32_UINT] = 4, + [REND_FORMAT_R32_SINT] = 4, + [REND_FORMAT_R32G32B32A32_UINT] = 16, + + [REND_FORMAT_D32_SFLOAT] = 4, + [REND_FORMAT_D24_UNORM_S8_UINT] = 4, + [REND_FORMAT_D32_SFLOAT_S8_UINT] = 8, // typically padded to 64-bit alignment by GPU drivers +}; + +enum RendBufferType_t { + REND_BUFFER_VERTEX , + REND_BUFFER_INDEX , + REND_BUFFER_UNIFORM , + REND_BUFFER_STORAGE , + REND_BUFFER_INDIRECT , + REND_BUFFER_TRANSFER , + REND_BUFFER_COUNT , +}; + + + +/* CHANGE LOG + * 0.1.0 - @vasco - vulkan instance + * 0.1.1 - @vasco - swapchain + * 0.1.2 - @vasco - command buffers + * 0.2.0 - @vasco - push basic vertex data to the gpu + * 0.3.1 - @vasco - Fixed rend_quit not freeing all objects. + * 0.4.0 - @vasco - Added resource sets. + * 0.4.1 - @vasco - Fixed binding descriptor sets. + * 0.4.2 - @vasco - Fixed capped framerate due to FIFO being always enabled and added vsync option. + * 0.4.3 - @vasco - Replaced bad fence based synchronization with a single timeline semaphore. + * 0.4.4 - @vasco - Deprecated pipeline destruction and clearing because it doesnt make any sense. + * 0.4.5 - @vasco - Exposed depth testing. + * 0.5.0 - @vasco - Host-visible buffers + * 0.5.1 - @vasco - Removed RendMemProperties from public API. + * 0.5.2 - @vasco - push_data is now push_vertices_and_draw and pipeline_draw not takes vertex count + * 0.6.0 - @vasco - indexed rendering + * 0.6.1 - @vasco - cool beans + * 0.6.2 - @vasco - Removed RendMemProperties is back. + * 0.6.3 - @vasco - push_data removed in favor of making the pipeline more low level. A prebuilt "gfx" pipeline can be added in the future. + * 0.6.4 - @vasco - Moved to push constants and bindless descriptors unde the hood. + * 0.7.0 - @vasco - Low level buffer creation API if you want device-local data. + * 0.7.1 - @vasco - typedefs for ease of use + * 0.8.0 - @vasco - bindless resources + * 0.8.1 - @vasco - remove old binding code from backend + * 0.8.2 - @vasco - nothing works!!! + * 0.8.3 - @vasco - pool allocator + * 0.8.4 - @vasco - buffers 2.0 + * 0.8.5 - @vasco - memory 2.0 + * 0.8.6 - @vasco - arena allocator + * 0.8.7 - @vasco - everything works!!! + * 0.8.8 - @vasco - fix device selection + * 0.8.9 - @vasco - images 2.0 + * 0.9.0 - @vasco - textures!!!!! + * 0.9.1 - @vasco - clear to color + * 0.10.0 - @vasco - instanced rendering + * 0.10.1 - @vasco - API clean up pt. 1 (remove RendShader in favor of pointers to data) + * 0.10.2 - @vasco - API clean up pt. 2 (remove RendPipelineConfig in favor of large functions) + * 0.11.0 - @vasco - compute shaders, dispatch command and render pass is now separate + * 0.11.1 - @vasco - better descriptor binding, multiple ubo, ssbo and texture arrays + * 0.11.2 - @vasco - cool beans + * 1.0.0 - @vasco - finished API release + * 1.0.1 - @vasco - render pass that targets textures + * + * 1.0.0 finished API release + * + * ------------------------------------------- + * + * 1.1.0 shader hot realoading plugin (need to add settings managament and dll loading to Podium) + */ + + +#endif |
