1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
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
|