summaryrefslogtreecommitdiff
path: root/src/renderer/cleanroom
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/cleanroom')
-rw-r--r--src/renderer/cleanroom/backend_vulkan.c65
-rw-r--r--src/renderer/cleanroom/backend_vulkan.h27
-rw-r--r--src/renderer/cleanroom/ral.h77
-rw-r--r--src/renderer/cleanroom/renderer.c6
-rw-r--r--src/renderer/cleanroom/renderer.h10
-rw-r--r--src/renderer/cleanroom/simda.h18
-rw-r--r--src/renderer/cleanroom/types.h116
7 files changed, 254 insertions, 65 deletions
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