summaryrefslogtreecommitdiff
path: root/src/render/ral.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/render/ral.h')
-rw-r--r--src/render/ral.h198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/render/ral.h b/src/render/ral.h
new file mode 100644
index 0000000..792bb4e
--- /dev/null
+++ b/src/render/ral.h
@@ -0,0 +1,198 @@
+/**
+ * @file ral.h
+ * @author your name (you@domain.com)
+ * @brief Render Abstraction Layer
+ * @details API that a graphics backend *must* implement
+ * @version 0.1
+ * @date 2024-03-31
+ *
+ * @copyright Copyright (c) 2024
+ *
+ */
+#pragma once
+
+#include "buf.h"
+#include "defines.h"
+#include "mem.h"
+#include "ral_types.h"
+#include "str.h"
+
+// Unrelated forward declares
+struct GLFWwindow;
+
+// Forward declare structs - these must be defined in the backend implementation
+typedef struct gpu_swapchain gpu_swapchain;
+typedef struct gpu_device gpu_device;
+typedef struct gpu_pipeline_layout gpu_pipeline_layout;
+typedef struct gpu_pipeline gpu_pipeline;
+typedef struct gpu_renderpass gpu_renderpass;
+typedef struct gpu_cmd_encoder gpu_cmd_encoder; // Recording
+typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission
+typedef struct gpu_buffer gpu_buffer;
+typedef struct gpu_texture gpu_texture;
+
+// #define MAX_SHADER_DATA_LAYOUTS 5
+// #define MAX_BUFFERS 256
+// #define MAX_TEXTURES 256
+// #define MAX_PIPELINES 128
+// #define MAX_RENDERPASSES 128
+
+// TYPED_POOL(gpu_buffer, buffer);
+// TYPED_POOL(gpu_texture, texture);
+
+// TYPED_POOL(gpu_pipeline_layout, pipeline_layout);
+// TYPED_POOL(gpu_pipeline, pipeline);
+// TYPED_POOL(gpu_renderpass, renderpass);
+
+// // --- Handy macros
+// #define BUFFER_GET(h) (buffer_pool_get(&context.resource_pools->buffers, h))
+// #define TEXTURE_GET(h) (texture_pool_get(&context.resource_pools->textures, h))
+
+// --- Pools
+// typedef struct gpu_backend_pools {
+// pipeline_pool pipelines;
+// pipeline_layout_pool pipeline_layouts;
+// renderpass_pool renderpasses;
+// } gpu_backend_pools;
+// void backend_pools_init(arena* a, gpu_backend_pools* backend_pools);
+
+// struct resource_pools {
+// buffer_pool buffers;
+// texture_pool textures;
+// };
+// void resource_pools_init(arena* a, struct resource_pools* res_pools);
+
+// --- Pipeline description
+typedef enum pipeline_kind {
+ PIPELINE_GRAPHICS,
+ PIPELINE_COMPUTE,
+} pipeline_kind;
+
+typedef struct shader_desc {
+ const char* debug_name;
+ str8 filepath; // Where it came from
+ str8 code; // Either GLSL or SPIRV bytecode
+ bool is_spirv;
+ bool is_combined_vert_frag; // Contains both vertex and fragment stages
+} shader_desc;
+
+shader_desc shader_quick_load(const char* filepath);
+/** @brief Hot reloads shaders for the given pipeline. Returns how long it took in milliseconds */
+u64 gpu_pipeline_reload_shaders(gpu_pipeline* pipeline); // TODO
+
+struct graphics_pipeline_desc {
+ const char* debug_name;
+ vertex_description vertex_desc;
+ shader_desc vs; /** @brief Vertex shader stage */
+ shader_desc fs; /** @brief Fragment shader stage */
+
+ // Roughly equivalent to a descriptor set layout each. each layout can have multiple bindings
+ // examples:
+ // - uniform buffer reprensenting view projection matrix
+ // - texture for shadow map
+ shader_data data_layouts[MAX_SHADER_DATA_LAYOUTS];
+ u32 data_layouts_count;
+
+ // gpu_pipeline_layout* layout;
+ gpu_renderpass* renderpass;
+
+ bool wireframe;
+ bool depth_test;
+};
+
+typedef struct gpu_renderpass_desc {
+ bool default_framebuffer;
+ bool has_color_target;
+ texture_handle color_target; // for now only support one
+ bool has_depth_stencil;
+ texture_handle depth_stencil;
+} gpu_renderpass_desc;
+
+// --- Lifecycle functions
+bool gpu_backend_init(const char* window_name, struct GLFWwindow* window);
+void gpu_backend_shutdown();
+void resource_pools_init(arena* a, struct resource_pools* res_pools);
+
+bool gpu_device_create(gpu_device* out_device);
+void gpu_device_destroy();
+
+// --- Render Pipeline
+gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description);
+void gpu_pipeline_destroy(gpu_pipeline* pipeline);
+
+// --- Renderpass
+gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description);
+void gpu_renderpass_destroy(gpu_renderpass* pass);
+
+// --- Swapchain
+bool gpu_swapchain_create(gpu_swapchain* out_swapchain);
+void gpu_swapchain_destroy(gpu_swapchain* swapchain);
+
+// --- Command buffer
+gpu_cmd_encoder gpu_cmd_encoder_create();
+void gpu_cmd_encoder_destroy(gpu_cmd_encoder* encoder);
+void gpu_cmd_encoder_begin(gpu_cmd_encoder encoder);
+void gpu_cmd_encoder_begin_render(gpu_cmd_encoder* encoder, gpu_renderpass* renderpass);
+void gpu_cmd_encoder_end_render(gpu_cmd_encoder* encoder);
+void gpu_cmd_encoder_begin_compute();
+gpu_cmd_encoder* gpu_get_default_cmd_encoder();
+
+/** @brief Finish recording and return a command buffer that can be submitted to a queue */
+gpu_cmd_buffer gpu_cmd_encoder_finish(gpu_cmd_encoder* encoder);
+
+void gpu_queue_submit(gpu_cmd_buffer* buffer);
+
+// --- Data copy commands
+/** @brief Copy data from one buffer to another */
+void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset,
+ buffer_handle dst, u64 dst_offset, u64 copy_size);
+/** @brief Upload CPU-side data as array of bytes to a GPU buffer */
+void buffer_upload_bytes(buffer_handle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size);
+
+/** @brief Copy data from buffer to buffer using a one time submit command buffer and a wait */
+void copy_buffer_to_buffer_oneshot(buffer_handle src, u64 src_offset, buffer_handle dst,
+ u64 dst_offset, u64 copy_size);
+/** @brief Copy data from buffer to an image using a one time submit command buffer */
+void copy_buffer_to_image_oneshot(buffer_handle src, texture_handle dst);
+
+// --- Render commands
+void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipeline* pipeline);
+void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data);
+void encode_set_default_settings(gpu_cmd_encoder* encoder);
+void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
+void encode_set_index_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
+void encode_set_bind_group(); // TODO
+void encode_draw(gpu_cmd_encoder* encoder, u64 count);
+void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count);
+void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf);
+
+// --- Buffers
+buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_flags flags,
+ const void* data);
+void gpu_buffer_destroy(buffer_handle buffer);
+void gpu_buffer_upload(const void* data);
+
+// Textures
+/** @brief Create a new GPU texture resource.
+ * @param create_view creates a texture view (with same dimensions) at the same time
+ * @param data if not NULL then the data stored at the pointer will be uploaded to the GPU texture
+ * @note automatically creates a sampler for you */
+texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data);
+void gpu_texture_destroy(texture_handle);
+void gpu_texture_upload(texture_handle texture, const void* data);
+
+// --- Vertex formats
+bytebuffer vertices_as_bytebuffer(arena* a, vertex_format format, vertex_darray* vertices);
+
+void vertex_desc_add(vertex_description* builder, const char* name, vertex_attrib_type type);
+
+// --- TEMP
+bool gpu_backend_begin_frame();
+void gpu_backend_end_frame();
+void gpu_temp_draw(size_t n_verts);
+
+// TODO: --- Compute
+
+// --- Helpers
+vertex_description static_3d_vertex_description();
+size_t vertex_attrib_size(vertex_attrib_type attr);