diff options
Diffstat (limited to 'src/ral')
-rw-r--r-- | src/ral/README.md | 5 | ||||
-rw-r--r-- | src/ral/backends/metal/backend_metal.h | 0 | ||||
-rw-r--r-- | src/ral/backends/opengl/backend_opengl.h | 76 | ||||
-rw-r--r-- | src/ral/backends/vulkan/backend_vulkan.h | 0 | ||||
-rw-r--r-- | src/ral/ral.h | 5 | ||||
-rw-r--r-- | src/ral/ral_common.c | 19 | ||||
-rw-r--r-- | src/ral/ral_common.h | 39 | ||||
-rw-r--r-- | src/ral/ral_impl.h | 38 | ||||
-rw-r--r-- | src/ral/ral_types.h | 223 |
9 files changed, 405 insertions, 0 deletions
diff --git a/src/ral/README.md b/src/ral/README.md new file mode 100644 index 0000000..f66b95a --- /dev/null +++ b/src/ral/README.md @@ -0,0 +1,5 @@ +# RAL + +**Render Abstraction Layer** is a thin abstraction over graphics APIs. Everything in `render` builds on top of the code in +this folder in order to be API-agnostic. It also makes writing graphics code easier as it smooths over some of the discrepancies +between APIs like texture/buffer creation and updating shader values.
\ No newline at end of file diff --git a/src/ral/backends/metal/backend_metal.h b/src/ral/backends/metal/backend_metal.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/ral/backends/metal/backend_metal.h diff --git a/src/ral/backends/opengl/backend_opengl.h b/src/ral/backends/opengl/backend_opengl.h new file mode 100644 index 0000000..22162f3 --- /dev/null +++ b/src/ral/backends/opengl/backend_opengl.h @@ -0,0 +1,76 @@ +#pragma once + +#include "ral_impl.h" +#ifdef CEL_REND_BACKEND_OPENGL + +#include "defines.h" +#include "maths_types.h" +#include "ral.h" +#include "ral_types.h" + +#define MAX_PIPELINE_UNIFORM_BUFFERS 32 + +#define OPENGL_DEFAULT_FRAMEBUFFER 0 + +typedef struct GPU_Swapchain{ + u32x2 dimensions; +}GPU_Swapchain; + +typedef struct GPU_Device { +} GPU_Device; + +typedef struct GPU_PipelineLayout{ + void *pad; +}GPU_PipelineLayout; + +typedef struct GPU_Pipeline { + u32 shader_id; + GPU_Renderpass* renderpass; + VertexDescription vertex_desc; + BufferHandle uniform_bindings[MAX_PIPELINE_UNIFORM_BUFFERS]; + u32 uniform_count; + bool wireframe; +} GPU_Pipeline; + +typedef struct GPU_Renderpass { + u32 fbo; + GPU_RenderpassDesc description; +} GPU_Renderpass; + +typedef struct GPU_CmdEncoder { + GPU_Pipeline *pipeline; +} GPU_CmdEncoder; // Recording + +typedef struct gpu_cmd_buffer { + void *pad; +} gpu_cmd_buffer; // Ready for submission + +typedef struct GPU_Buffer { + union { + u32 vbo; + u32 ibo; + u32 ubo; + } id; + union { + u32 vao; + u32 ubo_binding_point + }; // Optional + char* name; + u64 size; +} GPU_Buffer; + +typedef struct GPU_Texture { + u32 id; + void* pad; +} GPU_Texture; + +typedef struct opengl_support { +} opengl_support; + +u32 shader_create_separate(const char *vert_shader, const char *frag_shader); + +void uniform_vec3f(u32 program_id, const char *uniform_name, Vec3 *value); +void uniform_f32(u32 program_id, const char *uniform_name, f32 value); +void uniform_i32(u32 program_id, const char *uniform_name, i32 value); +void uniform_mat4f(u32 program_id, const char *uniform_name, Mat4 *value); +#endif diff --git a/src/ral/backends/vulkan/backend_vulkan.h b/src/ral/backends/vulkan/backend_vulkan.h new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/ral/backends/vulkan/backend_vulkan.h diff --git a/src/ral/ral.h b/src/ral/ral.h new file mode 100644 index 0000000..ce3b27d --- /dev/null +++ b/src/ral/ral.h @@ -0,0 +1,5 @@ +#pragma once + +#include "ral_types.h" +#include "ral_common.h" +#include "ral_impl.h"
\ No newline at end of file diff --git a/src/ral/ral_common.c b/src/ral/ral_common.c new file mode 100644 index 0000000..89d475b --- /dev/null +++ b/src/ral/ral_common.c @@ -0,0 +1,19 @@ +#include "ral_common.h" +#include "ral_impl.h" + +void backend_pools_init(arena* a, GPU_BackendPools* backend_pools) { + PipelineLayout_pool pipeline_layout_pool = + PipelineLayout_pool_create(a, MAX_PIPELINES, sizeof(GPU_PipelineLayout)); + backend_pools->pipeline_layouts = pipeline_layout_pool; + Pipeline_pool pipeline_pool = Pipeline_pool_create(a, MAX_PIPELINES, sizeof(GPU_Pipeline)); + backend_pools->pipelines = pipeline_pool; + Renderpass_pool rpass_pool = Renderpass_pool_create(a, MAX_RENDERPASSES, sizeof(GPU_Renderpass)); + backend_pools->renderpasses = rpass_pool; +} + +void resource_pools_init(arena* a, struct ResourcePools* res_pools) { + Buffer_pool buf_pool = Buffer_pool_create(a, MAX_BUFFERS, sizeof(GPU_Buffer)); + res_pools->buffers = buf_pool; + Texture_pool tex_pool = Texture_pool_create(a, MAX_TEXTURES, sizeof(GPU_Texture)); + res_pools->textures = tex_pool; +} diff --git a/src/ral/ral_common.h b/src/ral/ral_common.h new file mode 100644 index 0000000..1088404 --- /dev/null +++ b/src/ral/ral_common.h @@ -0,0 +1,39 @@ +#pragma once +#include "defines.h" +#include "buf.h" +#include "mem.h" +#include "ral_types.h" +#include "ral_impl.h" + + +TYPED_POOL(GPU_Buffer, Buffer); +TYPED_POOL(GPU_Texture, Texture); +TYPED_POOL(GPU_PipelineLayout, PipelineLayout); +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_BackendPools{ + Pipeline_pool pipelines; + PipelineLayout_pool pipeline_layouts; + Renderpass_pool renderpasses; +} GPU_BackendPools; +void backend_pools_init(arena* a, GPU_BackendPools* backend_pools); + +struct ResourcePools { + Buffer_pool buffers; + Texture_pool textures; +}; +void resource_pools_init(arena* a, struct ResourcePools* res_pools); + + +// --- Vertex formats +bytebuffer vertices_as_bytebuffer(arena* a, VertexFormat format, Vertex_darray* vertices); + +void vertex_desc_add(VertexDescription* builder, const char* name, VertexAttribType type); +VertexDescription static_3d_vertex_description(); +size_t vertex_attrib_size(VertexAttribType attr); diff --git a/src/ral/ral_impl.h b/src/ral/ral_impl.h new file mode 100644 index 0000000..4d1c17a --- /dev/null +++ b/src/ral/ral_impl.h @@ -0,0 +1,38 @@ +/** + * @brief +*/ +#pragma once +#include "defines.h" +#include "ral_types.h" + +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_PipelineLayout GPU_PipelineLayout; +typedef struct GPU_Pipeline GPU_Pipeline; +typedef struct GPU_Renderpass GPU_Renderpass; +typedef struct GPU_CmdEncoder GPU_CmdEncoder; // Recording +typedef struct GPU_CmdBuffer GPU_CmdBuffer; // Ready for submission +typedef struct GPU_Buffer GPU_Buffer; +typedef struct GPU_Texture GPU_Texture; + +bool GPU_Backend_Init(const char* window_name, struct GLFWwindow* window); +void GPU_Backend_Shutdown(); + +bool GPU_Device_Create(GPU_Device* out_device); +void GPU_Device_Destroy(GPU_Device* device); + +bool GPU_Swapchain_Create(GPU_Swapchain* out_swapchain); +void GPU_Swapchain_Destroy(GPU_Swapchain* swapchain); + +GPU_Renderpass* GPU_Renderpass_Create(GPU_RenderpassDesc description); +void GPU_Renderpass_Destroy(GPU_Renderpass* pass); + +GPU_Pipeline* GPU_GraphicsPipeline_Create(GraphicsPipelineDesc description, GPU_Renderpass* renderpass); +void GraphicsPipeline_Destroy(GPU_Pipeline* pipeline); + +#if defined(CEL_REND_BACKEND_OPENGL) +#include "backend_opengl.h" +#endif diff --git a/src/ral/ral_types.h b/src/ral/ral_types.h new file mode 100644 index 0000000..0ba7f87 --- /dev/null +++ b/src/ral/ral_types.h @@ -0,0 +1,223 @@ +#pragma once +#include "defines.h" +#include "darray.h" +#include "maths_types.h" + +// --- Max size constants +#define MAX_SHADER_DATA_LAYOUTS 8 +#define MAX_SHADER_BINDINGS 8 +#define MAX_BUFFERS 256 +#define MAX_TEXTURES 256 +#define MAX_PIPELINES 128 +#define MAX_RENDERPASSES 128 +#define MAX_VERTEX_ATTRIBUTES 16 + +// --- Handle types +CORE_DEFINE_HANDLE(BufferHandle); +CORE_DEFINE_HANDLE(TextureHandle); +CORE_DEFINE_HANDLE(SamplerHandle); +CORE_DEFINE_HANDLE(ShaderHandle); +CORE_DEFINE_HANDLE(PipelineLayoutHandle); +CORE_DEFINE_HANDLE(PipelineHandle); +CORE_DEFINE_HANDLE(RenderpassHandle); + +// --- Buffers +typedef enum GPU_BufferType{ + BUFFER_DEFAULT, // on Vulkan this would be a storage buffer? + BUFFER_VERTEX, + BUFFER_INDEX, + BUFFER_UNIFORM, + BUFFER_COUNT +} GPU_BufferType; + +static const char* buffer_type_names[] = { + "RAL Buffer Default", "RAL Buffer Vertex", "RAL Buffer Index", + "RAL Buffer Uniform", "RAL Buffer Count", +}; + +typedef enum GPU_BufferFlag { + BUFFER_FLAG_CPU = 1 << 0, + BUFFER_FLAG_GPU = 1 << 1, + BUFFER_FLAG_STORAGE = 1 << 2, + BUFFER_FLAG_COUNT +} GPU_BufferFlag; +typedef u32 GPU_BufferFlags; + +// --- Textures +typedef enum GPU_TextureType { + TEXTURE_TYPE_2D, + TEXTURE_TYPE_3D, + TEXTURE_TYPE_2D_ARRAY, + TEXTURE_TYPE_CUBE_MAP, + TEXTURE_TYPE_COUNT +} GPU_TextureType; + +typedef enum GPU_TextureFormat { + TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM, + TEXTURE_FORMAT_DEPTH_DEFAULT, + TEXTURE_FORMAT_COUNT +} GPU_TextureFormat; + +/** @brief Texture Description - used by texture creation functions */ +typedef struct TextureDesc { + GPU_TextureType tex_type; + GPU_TextureFormat format; + u32x2 extents; +} TextureDesc; + +// --- Vertices + +typedef enum VertexFormat { + VERTEX_STATIC_3D, + VERTEX_SPRITE, + VERTEX_SKINNED, + VERTEX_COLOURED_STATIC_3D, + VERTEX_RAW_POS_COLOUR, + VERTEX_COUNT +} VertexFormat; + +typedef union Vertex { + struct { + Vec3 position; + Vec3 normal; + Vec2 tex_coords; + } static_3d; /** @brief standard vertex format for static geometry in 3D */ + + struct { + Vec2 position; + Vec4 colour; + Vec2 tex_coords; + } sprite; /** @brief vertex format for 2D sprites or quads */ + + struct { + Vec3 position; + Vec4 colour; + Vec2 tex_coords; + Vec3 normal; + Vec4i bone_ids; // Integer vector for bone IDs + Vec4 bone_weights; // Weight of each bone's influence + } skinned_3d; /** @brief vertex format for skeletal (animated) geometry in 3D */ + + struct { + Vec3 position; + Vec2 tex_coords; + Vec3 normal; + Vec4 colour; + } coloured_static_3d; /** @brief vertex format used for debugging */ + + struct { + Vec2 position; + Vec3 colour; + } raw_pos_colour; +} Vertex; + +#ifndef TYPED_VERTEX_ARRAY +KITC_DECL_TYPED_ARRAY(Vertex); +KITC_DECL_TYPED_ARRAY(u32) +#define TYPED_VERTEX_ARRAY +#endif + +/// @strip_prefix(ATTR_) +typedef enum VertexAttribType { + ATTR_F32, + ATTR_F32x2, + ATTR_F32x3, + ATTR_F32x4, + ATTR_U32, + ATTR_U32x2, + ATTR_U32x3, + ATTR_U32x4, + ATTR_I32, + ATTR_I32x2, + ATTR_I32x3, + ATTR_I32x4, +} VertexAttribType; + +typedef struct VertexDescription { + char* debug_label; + const char* attr_names[MAX_VERTEX_ATTRIBUTES]; + VertexAttribType attributes[MAX_VERTEX_ATTRIBUTES]; + u32 attributes_count; + size_t stride; + bool use_full_vertex_size; +} VertexDescription; + +// --- Shaders +typedef enum ShaderVisibility { + VISIBILITY_VERTEX = 1 << 0, + VISIBILITY_FRAGMENT = 1 << 1, + VISIBILITY_COMPUTE = 1 << 2, +} ShaderVisibility ; + +typedef struct ShaderDesc {} ShaderDesc; + +typedef enum ShaderBindingKind { + BINDING_BUFFER, + BINDING_BUFFER_ARRAY, + BINDING_TEXTURE, + BINDING_TEXTURE_ARRAY, + // TODO: sampler + BINDING_COUNT +} ShaderBindingKind; + +typedef struct ShaderBinding { + const char* label; + ShaderBindingKind kind; + ShaderVisibility vis; + union { + struct { u32 size; } bytes; + struct { BufferHandle handle; } buffer; + struct { TextureHandle handle; } texture; + } data; +} ShaderBinding; + +typedef struct ShaderDataLayout { + ShaderBinding* bindings; + size_t binding_count; +} ShaderDataLayout; + +typedef ShaderDataLayout (*FN_GetBindingLayout)(void); + +typedef struct ShaderData { + FN_GetBindingLayout get_layout; + void* data; +} ShaderData; + +// --- Miscellaneous + +typedef enum PrimitiveTopology { + PRIMITIVE_TOPOLOGY_POINT, + PRIMITIVE_TOPOLOGY_LINE, + PRIMITIVE_TOPOLOGY_LINE_STRIP, + PRIMITIVE_TOPOLOGY_TRIANGLE, + PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + PRIMITIVE_TOPOLOGY_COUNT +} PrimitiveTopology; + +typedef enum CullMode { CULL_BACK_FACE, CULL_FRONT_FACE, CULL_COUNT } CullMode; + +typedef struct GraphicsPipelineDesc { + // GPU_Renderpass* renderpass -> takes a renderpass in the create function + const char* debug_name; + VertexDescription vertex_desc; + ShaderDesc vs; /** @brief Vertex shader stage */ + ShaderDesc 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 + ShaderData data_layouts[MAX_SHADER_DATA_LAYOUTS]; + u32 data_layouts_count; + + bool wireframe; + bool depth_test; +} GraphicsPipelineDesc; + +typedef struct GPU_RenderpassDesc { + bool default_framebuffer; + bool has_color_target; + TextureHandle color_target; // for now only support one + bool has_depth_stencil; + TextureHandle depth_stencil; +} GPU_RenderpassDesc; |