diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/defines.h | 4 | ||||
-rw-r--r-- | src/renderer/cleanroom/backend_vulkan.c | 65 | ||||
-rw-r--r-- | src/renderer/cleanroom/backend_vulkan.h | 27 | ||||
-rw-r--r-- | src/renderer/cleanroom/ral.h | 77 | ||||
-rw-r--r-- | src/renderer/cleanroom/renderer.c | 6 | ||||
-rw-r--r-- | src/renderer/cleanroom/renderer.h | 10 | ||||
-rw-r--r-- | src/renderer/cleanroom/simda.h | 18 | ||||
-rw-r--r-- | src/renderer/cleanroom/types.h | 116 | ||||
-rw-r--r-- | src/renderer/render_types.h | 7 |
9 files changed, 262 insertions, 68 deletions
diff --git a/src/defines.h b/src/defines.h index 4459e1a..811064d 100644 --- a/src/defines.h +++ b/src/defines.h @@ -71,6 +71,6 @@ Renderer backend defines: #endif #if defined(CEL_PLATFORM_MAC) -#define CEL_REND_BACKEND_METAL 1 -// #define CEL_REND_BACKEND_OPENGL 1 +// #define CEL_REND_BACKEND_METAL 1 +#define CEL_REND_BACKEND_OPENGL 1 #endif
\ No newline at end of file diff --git a/src/renderer/cleanroom/backend_vulkan.c b/src/renderer/cleanroom/backend_vulkan.c new file mode 100644 index 0000000..2838f20 --- /dev/null +++ b/src/renderer/cleanroom/backend_vulkan.c @@ -0,0 +1,65 @@ +#include <stdlib.h> +#include "ral.h" +#include "types.h" +#include "render_types.h" + +#define VULKAN_QUEUES_COUNT 2 +const char* queue_names[VULKAN_QUEUES_COUNT] = { + "GRAPHICS", "TRANSFER" +}; + +typedef struct vulkan_context { + gpu_device device; + + VkInstance instance; + +} vulkan_context; + +static vulkan_context context; + +static bool select_physical_device(gpu_device* out_device) {} + +bool gpu_device_create(gpu_device* out_device) { + // Physical device + if (!select_physical_device(out_device)) { + return false; + } + INFO("Physical device selected"); + + // Logical device + VkDeviceQueueCreateInfo queue_create_info[2]; + //.. + VkDeviceCreateInfo device_create_info = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO }; + + VkResult result = vkCreateDevice(); + if (result != VK_SUCCESS) { + FATAL("Error creating logical device with status %u\n", result); + exit(1); + } + INFO("Logical device created"); + + // Queues + + // Create the command pool + +} + +gpu_renderpass* gpu_renderpass_create() { + // Allocate it + // sets everything up + // return pointer to it +} + +void encode_set_pipeline(gpu_cmd_encoder* encoder, pipeline_type kind, gpu_pipeline* pipeline) { +// VK_PIPELINE_BIND_POINT_GRAPHICS, &shader->pipeline); + if (kind== PIPELINE_GRAPHICS) { + // ... + } else { + // ... + } +} + +// --- Drawing +inline void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count) { + vkCmdDrawIndexed(encoder->cmd_buffer, index_count, 1, 0, 0, 0); +}
\ No newline at end of file diff --git a/src/renderer/cleanroom/backend_vulkan.h b/src/renderer/cleanroom/backend_vulkan.h new file mode 100644 index 0000000..6798b13 --- /dev/null +++ b/src/renderer/cleanroom/backend_vulkan.h @@ -0,0 +1,27 @@ +#pragma once +#include "cleanroom/ral.h" + +#define GPU_SWAPCHAIN_IMG_COUNT 2 + +typedef struct gpu_swapchain {} gpu_swapchain; +typedef struct gpu_device { + // In Vulkan we store both physical and logical device here + VkPhysicalDevice physical_device; + VkDevice logical_device; + VkPhysicalDeviceProperties properties; + VkPhysicalDeviceFeatures features; + VkPhysicalDeviceMemoryProperties memory; + VkCommandPool pool; +} gpu_device; +typedef struct gpu_pipeline {} gpu_pipeline; + +typedef struct gpu_renderpass { + VkRenderPass vk_handle; + VkFramebuffer framebuffers[GPU_SWAPCHAIN_IMG_COUNT]; + u32 +} gpu_renderpass; + + +typedef struct gpu_cmd_encoder { + VkCommandBuffer cmd_buffer; +} gpu_cmd_encoder;
\ No newline at end of file diff --git a/src/renderer/cleanroom/ral.h b/src/renderer/cleanroom/ral.h new file mode 100644 index 0000000..8f7c8a4 --- /dev/null +++ b/src/renderer/cleanroom/ral.h @@ -0,0 +1,77 @@ +/** + * @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 "cleanroom/types.h" +#include "defines.h" + +// TODO: Replace with handle defines +typedef int buffer_handle; +typedef int texture_handle; +typedef int sampler_handle; +typedef int model_handle; + +// Forward declare structs +typedef struct gpu_swapchain gpu_swapchain; +typedef struct gpu_device gpu_device; +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 + + +// lifecycle functions +gpu_device* gpu_device_create(); +void gpu_device_destroy(); + +gpu_renderpass* gpu_renderpass_create(); +void gpu_renderpass_destroy(gpu_renderpass* pass); + +gpu_pipeline* gpu_pipeline_create(pipeline_kind kind); +void gpu_pipeline_destroy(gpu_pipeline* pipeline); + +void gpu_cmd_encoder_begin(); +void gpu_cmd_encoder_begin_render(); +void gpu_cmd_encoder_begin_compute(); + +/* Actual commands that we can encode */ +void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset, + buffer_handle dst, u64 dst_offset, u64 copy_size); +void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf); +void encode_set_pipeline(gpu_cmd_encoder* encoder, gpu_pipeline* pipeline); +// render pass +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(); +void encode_draw(gpu_cmd_encoder* encoder); +void encode_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count); + +// FUTURE: compute passes + +/** @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); + +// Buffers +void gpu_buffer_create(u64 size); +void gpu_buffer_destroy(buffer_handle buffer); +void gpu_buffer_upload(); +void gpu_buffer_bind(buffer_handle buffer); + +// Textures +void gpu_texture_create(); +void gpu_texture_destroy(); +void gpu_texture_upload(); + +// Samplers +void gpu_sampler_create();
\ No newline at end of file diff --git a/src/renderer/cleanroom/renderer.c b/src/renderer/cleanroom/renderer.c new file mode 100644 index 0000000..65c09de --- /dev/null +++ b/src/renderer/cleanroom/renderer.c @@ -0,0 +1,6 @@ +#include "render_types.h" +#include "defines.h" + +bool renderer_init() { + +}
\ No newline at end of file diff --git a/src/renderer/cleanroom/renderer.h b/src/renderer/cleanroom/renderer.h new file mode 100644 index 0000000..7d56fe2 --- /dev/null +++ b/src/renderer/cleanroom/renderer.h @@ -0,0 +1,10 @@ +#pragma once + +#include "cleanroom/ral.h" +#include "cleanroom/backend_vulkan.h" + +typedef struct renderer2 { + void* backend_state; + gpu_device* device; + gpu_pipeline* static_opaque_pipeline; +} renderer2;
\ No newline at end of file diff --git a/src/renderer/cleanroom/simda.h b/src/renderer/cleanroom/simda.h new file mode 100644 index 0000000..d0b4794 --- /dev/null +++ b/src/renderer/cleanroom/simda.h @@ -0,0 +1,18 @@ +#pragma once + +#include "maths_types.h" + +// 3. SIMA (simplified immediate mode api) / render.h +// - dont need to worry about uploading mesh data +// - very useful for debugging +void imm_draw_cuboid(); +void imm_draw_sphere(vec3 pos, f32 radius, vec4 colour); +void imm_draw_camera_frustum(); +static void imm_draw_model( + const char* model_filepath); // tracks internally whether the model is loaded + +static void imm_draw_model(const char* model_filepath) { + // check that model is loaded + // if not loaded, load model and upload to gpu - LRU cache for models + // else submit draw call +}
\ No newline at end of file diff --git a/src/renderer/cleanroom/types.h b/src/renderer/cleanroom/types.h index 3f62cab..a37e0e6 100644 --- a/src/renderer/cleanroom/types.h +++ b/src/renderer/cleanroom/types.h @@ -4,10 +4,14 @@ #include "maths_types.h" #include "str.h" -typedef int texture_handle; +// TODO: Replace with handle defines typedef int buffer_handle; +typedef int texture_handle; +typedef int sampler_handle; typedef int model_handle; +typedef struct transform_hierarchy {} transform_hierarchy; + /** @brief Texture Description - used by texture creation functions */ typedef struct texture_desc { // gpu_texture_type tex_type; @@ -47,8 +51,6 @@ typedef enum gpu_texture_format { } gpu_texture_format; /* render_types */ -typedef struct mesh mesh; -typedef struct model model; typedef struct model pbr_material; typedef struct model bp_material; // blinn-phong @@ -77,7 +79,7 @@ typedef union vertex { vec3 normal; vec4i bone_ids; // Integer vector for bone IDs vec4 bone_weights; // Weight of each bone's influence - } animated_3d; /** @brief vertex format for skeletal (animated) geometry in 3D */ + } skinned_3d; /** @brief vertex format for skeletal (animated) geometry in 3D */ } vertex; KITC_DECL_TYPED_ARRAY(vertex) @@ -122,79 +124,63 @@ typedef struct model { // 2 - you need to know how the overall renderer is designed // 1 - you need to understand graphics API specifics -/* render.h */ -// frontend -- these can be called from say a loop in an example, or via FFI -texture_handle texture_create(const char* debug_name, texture_desc description, const u8* data); +/* ral.h */ -void texture_data_upload(texture_handle texture); -buffer_handle buffer_create(const char* debug_name, u64 size); -bool buffer_destroy(buffer_handle buffer); +// enum pipeline_type { +// GRAPHICS, +// COMPUTE, +// } pipeline_type; -// models and meshes are implemented **in terms of the above** -mesh mesh_create(geometry_data* geometry); -model_handle model_load(const char* debug_name, const char* filepath); -/* ral.h */ -enum pipeline_type { - GRAPHICS, - COMPUTE, -} pipeline_type; +// command buffer gubbins -// backend -- these are not seen by the higher-level code -typedef struct gpu_swapchain gpu_swapchain; -typedef struct gpu_device gpu_device; -typedef struct gpu_pipeline gpu_pipeline; -typedef struct gpu_cmd_encoder gpu_cmd_encoder; -typedef struct gpu_cmd_buffer gpu_cmd_buffer; // Ready for submission +/* --- Backends */ -void gpu_cmd_encoder_begin(); -void gpu_cmd_encoder_begin_render(); -void gpu_cmd_encoder_begin_compute(); +// struct vulkan_backend { +// gpu_pipeline static_opaque_pipeline; +// gpu_pipeline skinned_opaque_pipeline; +// }; -/* Actual commands that we can encode */ -void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset, - buffer_handle dst, u64 dst_offset, u64 copy_size); -void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf); -// render pass -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_draw_indexed(gpu_cmd_encoder* encoder, u64 index_count, u64* indices); +/* --- Renderer layer */ +/* render.h */ -// FUTURE: compute passes +typedef struct renderer { + void* backend_context; +} renderer; -/** @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); +bool renderer_init(renderer* ren); +void renderer_shutdown(renderer* ren); -void gpu_queue_submit(gpu_cmd_buffer* buffer); +// frontend -- these can be called from say a loop in an example, or via FFI +texture_handle texture_create(const char* debug_name, texture_desc description, const u8* data); -// Buffers -void gpu_buffer_create(u64 size); -void gpu_buffer_destroy(buffer_handle buffer); -void gpu_buffer_upload(); -void gpu_buffer_bind(buffer_handle buffer); +// Frontend Resources +void texture_data_upload(texture_handle texture); +buffer_handle buffer_create(const char* debug_name, u64 size); +bool buffer_destroy(buffer_handle buffer); +sampler_handle sampler_create(); -// Textures -void gpu_texture_create(); -void gpu_texture_destroy(); -void gpu_texture_upload(); +void shader_hot_reload(const char* filepath); -// Samplers -void gpu_sampler_create(); +// models and meshes are implemented **in terms of the above** +mesh mesh_create(geometry_data* geometry); +model_handle model_load(const char* debug_name, const char* filepath); -// command buffer gubbins +// Drawing + +// void draw_mesh(gpu_cmd_encoder* encoder, mesh* mesh) { +// encode_set_vertex_buffer(encoder, mesh->vertex_buffer); +// encode_set_index_buffer(encoder, mesh->index_buffer); +// encode_draw_indexed(encoder, mesh->index_count) +// // vkCmdDrawIndexed +// } + +// void draw_scene(arena* frame, model_darray* models, renderer* ren, camera* camera, +// transform_hierarchy* tfh, scene* scene) { +// // set the pipeline first +// encode_set_pipeline() +// // in open this sets the shader +// // in vulkan it sets the whole pipeline -// 3. SIMA (simplified immediate mode api) / render.h -// - dont need to worry about uploading mesh data -// - very useful for debugging -void imm_draw_cuboid(); -void imm_draw_sphere(vec3 pos, f32 radius, vec4 colour); -void imm_draw_camera_frustum(); -static void imm_draw_model( - const char* model_filepath); // tracks internally whether the model is loaded - -static void imm_draw_model(const char* model_filepath) { - // check that model is loaded - // if not loaded, load model and upload to gpu - LRU cache for models - // else submit draw call -}
\ No newline at end of file +// }
\ No newline at end of file diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h index 2cc321c..d8425ef 100644 --- a/src/renderer/render_types.h +++ b/src/renderer/render_types.h @@ -179,4 +179,9 @@ typedef enum gpu_texture_format { TEXTURE_FORMAT_8_8_8_8_RGBA_UNORM, TEXTURE_FORMAT_DEPTH_DEFAULT, TEXTURE_FORMAT_COUNT -} gpu_texture_format;
\ No newline at end of file +} gpu_texture_format; + +typedef enum pipeline_kind { + GRAPHICS, + COMPUTE, +} pipeline_kind;
\ No newline at end of file |