summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmniscient <omniscient.oce@gmail.com>2024-10-27 00:56:55 +1100
committerOmniscient <omniscient.oce@gmail.com>2024-10-27 00:56:55 +1100
commite597fbb916848df1f6fbd4da04c1ab6f89a25b45 (patch)
tree4f7205d14cd78f2a489ab3098c8211549d638448
parent3946ae807a2de00b3c810f986f60ba9cc32bc1a7 (diff)
start on vulkan backend
-rw-r--r--Makefile13
-rw-r--r--examples/cube.c3
-rw-r--r--include/celeritas.h15
-rw-r--r--src/backend_vk.c149
-rw-r--r--src/camera.c2
-rw-r--r--src/core.c4
-rw-r--r--src/impl.c2
7 files changed, 173 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index 597ecdc..92afab1 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ CC := clang
INCLUDES := -I./include -Ideps/glfw-3.3.8/include/GLFW -Ideps/stb_image
CFLAGS := -Wall -Wextra -O2 -fPIC $(INCLUDES)
# TODO(low prio): split static object files and shared object files so we can remove -fPIC from static lib builds
-LDFLAGS := -lglfw
+LDFLAGS := -lglfw -lvulkan
# Detect OS
UNAME_S := $(shell uname -s)
@@ -67,22 +67,27 @@ shared: $(SHARED_LIB)
static: $(STATIC_LIB)
-# Shaders
+# Metal shader compilation
+ifeq ($(UNAME_S),Darwin)
$(SHADER_OUT_DIR)/%.air: $(SHADER_DIR)/%.metal
@mkdir -p $(SHADER_OUT_DIR)
xcrun -sdk macosx metal -c $< -o $@
$(METAL_LIB): $(METAL_AIR_FILES)
xcrun -sdk macosx metallib $^ -o $(SHADER_OUT_DIR)/default.metallib
+endif
.PHONY: all
all: shared static
.PHONY: triangle
-triangle: $(EXAMPLES_DIR)/triangle.c $(SHARED_LIB) $(SHADER_OUT_DIR)/triangle.air $(METAL_LIB)
+triangle: $(EXAMPLES_DIR)/triangle.c $(SHARED_LIB) # $(SHADER_OUT_DIR)/triangle.air $(METAL_LIB)
@mkdir -p $(BUILD_DIR)
+ifeq ($(UNAME_S),Darwin)
+ $(MAKE) $(SHADER_OUT_DIR)/triangle.air $(METAL_LIB)
+endif
$(CC) $(CFLAGS) $(EXAMPLES_DIR)/triangle.c -L$(BUILD_DIR) -lceleritas $(LDFLAGS) -o $(BUILD_DIR)/triangle.bin
- MTL_DEBUG_LAYER=1 build/triangle.bin
+ MTL_DEBUG_LAYER=1 LD_LIBRARY_PATH=$(BUILD_DIR) build/triangle.bin
.PHONY: cube
cube: $(EXAMPLES_DIR)/cube.c $(SHARED_LIB) $(SHADER_OUT_DIR)/cube.air $(METAL_LIB)
diff --git a/examples/cube.c b/examples/cube.c
index f107e75..5dcd504 100644
--- a/examples/cube.c
+++ b/examples/cube.c
@@ -32,7 +32,8 @@ void draw() {
// if (!printed) {
// printf("\nTo Center:\n");
// for (int i = 0; i < 16; i += 4) {
- // printf("%f %f %f %f\n", to_center.data[i], to_center.data[i + 1], to_center.data[i + 2], to_center.data[i + 3]);
+ // printf("%f %f %f %f\n", to_center.data[i], to_center.data[i + 1], to_center.data[i + 2], to_center.data[i +
+ // 3]);
// }
// printed = true;
// }
diff --git a/include/celeritas.h b/include/celeritas.h
index 62b3fc3..ef85a66 100644
--- a/include/celeritas.h
+++ b/include/celeritas.h
@@ -69,6 +69,9 @@ _Static_assert(sizeof(ptrdiff_t) == 8, "type ptrdiff_t should be 8 bytes");
#define MB(x) ((size_t)x * 1000 * 1000)
#define GB(x) ((size_t)x * 1000 * 1000 * 1000)
+// TEMP
+#define CEL_PLATFORM_LINUX
+
// Platform informs renderer backend (unless user overrides)
#if defined(CEL_PLATFORM_LINUX) || defined(CEL_PLATFORM_WINDOWS)
#define GPU_VULKAN 1
@@ -76,7 +79,7 @@ _Static_assert(sizeof(ptrdiff_t) == 8, "type ptrdiff_t should be 8 bytes");
#define GPU_METAL 1
#endif
-#define TODO(msg) \
+#define TODO(msg) \
printf("TODO: %s\n", msg); \
exit(1);
@@ -130,10 +133,10 @@ fixed_arena fixed_arena_new(void* backing_buffer, size_t size, size_t alignment)
/**
* @brief Allocates memory on the arena.
- *
+ *
* @param arena
* @param size Number of bytes to reserve
- * @return Pointer to the allocated memory or NULL if there's not enough space
+ * @return Pointer to the allocated memory or NULL if there's not enough space
*/
void* fixed_arena_alloc(fixed_arena* arena, size_t size);
@@ -300,7 +303,7 @@ inlined vec3 vec3_normalise(vec3 a);
inlined f32 vec3_dot(vec3 a, vec3 b);
inlined vec3 vec3_cross(vec3 a, vec3 b);
-inlined vec4 vec4_create(f32 x, f32 y, f32 z, f32 w);
+vec4 vec4_create(f32 x, f32 y, f32 z, f32 w);
// quaternion functions
inlined quat quat_ident();
@@ -353,8 +356,8 @@ DEFINE_HANDLE(compute_pipeline_handle);
typedef struct gpu_swapchain gpu_swapchain;
typedef struct gpu_encoder gpu_encoder; // Render command encoder
typedef struct gpu_compute_encoder gpu_compute_encoder;
-typedef struct gpu_buffer gpu_buffer;
-typedef struct gpu_texture gpu_texture;
+// typedef struct gpu_buffer gpu_buffer;
+// typedef struct gpu_texture gpu_texture;
// NOTE: Can we just use Storage buffer for everything?
// typedef enum gpu_buf_type {} gpu_buf_type;
diff --git a/src/backend_vk.c b/src/backend_vk.c
index b6585d9..585eae8 100644
--- a/src/backend_vk.c
+++ b/src/backend_vk.c
@@ -1 +1,150 @@
+/**
+ * @file backend_vk.c
+ * @author Omniscient
+ * @brief Implements the RAL interface using Vulkan.
+ *
+ * @copyright Copyright (c) 2024
+ */
+
#include <celeritas.h>
+
+#ifdef GPU_VULKAN
+
+#include <vulkan/vk_platform.h>
+#include <vulkan/vulkan.h>
+#include <vulkan/vulkan_core.h>
+
+NAMESPACED_LOGGER(vulkan);
+
+#define MIN_API_VERSION VK_MAKE_API_VERSION(0, 1, 3, 0)
+
+struct gpu_swapchain {
+ VkSwapchainKHR handle;
+ VkExtent2D extents;
+};
+
+struct gpu_encoder {};
+
+struct gpu_compute_encoder {};
+
+typedef struct vk_pipeline {
+} vk_pipeline;
+
+typedef struct vk_buffer {
+ VkBuffer handle;
+ VkDeviceMemory memory;
+ u64 size;
+} vk_buffer;
+
+typedef struct vk_texture {
+} vk_texture;
+
+TYPED_POOL(vk_buffer, buf);
+TYPED_POOL(vk_texture, tex);
+TYPED_POOL(vk_pipeline, pipeline);
+
+typedef struct vulkan_context {
+ GLFWwindow* window;
+ VkInstance instance;
+ VkSurfaceKHR surface;
+ VkDebugUtilsMessengerEXT vk_debugger;
+ VkPhysicalDevice gpu;
+ VkDevice device;
+
+ /* pools */
+ buf_pool bufpool;
+ tex_pool texpool;
+ pipeline_pool psopool;
+} vulkan_context;
+
+/** globally available vulkan data */
+static vulkan_context ctx;
+
+// Forward declares
+
+void _init_device();
+void _init_swapchain();
+void _init_commands();
+void _init_sync_objects();
+
+void ral_backend_init(const char* window_name, struct GLFWwindow* window) {
+ TRACE("loading vulkan backend");
+
+ // Application info
+ VkApplicationInfo app_info = { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO };
+ app_info.apiVersion = VK_API_VERSION_1_2;
+ app_info.pApplicationName = window_name;
+ app_info.applicationVersion = MIN_API_VERSION;
+ app_info.pEngineName = "Celeritas Engine";
+ app_info.engineVersion = MIN_API_VERSION;
+
+ // Instance setup
+ VkInstanceCreateInfo create_info = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO };
+ create_info.pApplicationInfo = &app_info;
+
+ // TODO: Extensions
+
+ // Finally, create the Instance
+ VkResult res = vkCreateInstance(&create_info, NULL, &ctx.instance);
+ if (res != VK_SUCCESS) {
+ ERROR("vkCreateInstance failed with result: %u", res);
+ // TODO: change function sig to return bool
+ exit(1);
+ }
+
+ INFO("successfully initialised Vulkan RAL backend");
+}
+
+void ral_backend_shutdown() {}
+void ral_backend_resize_framebuffer(int width, int height) {}
+
+buf_handle ral_buffer_create(u64 size, const void* data) {
+ buf_handle handle;
+ vk_buffer* buffer = buf_pool_alloc(&ctx.bufpool, &handle);
+
+ VkBufferCreateInfo buffer_info = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO };
+ buffer_info.size = size;
+ // Add all the flags and leave optimisation up to the driver and the GPU
+ buffer_info.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
+ VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
+ VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
+ buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+ vkCreateBuffer(ctx.device, &buffer_info, NULL, &buffer->handle);
+
+ VkMemoryRequirements mem_reqs;
+ vkGetBufferMemoryRequirements(ctx.device, buffer->handle, &mem_reqs);
+
+ return handle;
+}
+
+void ral_buffer_destroy(buf_handle handle);
+void ral_buffer_upload_data(buf_handle, u64 size, const void* data);
+
+tex_handle ral_texture_create(texture_desc desc, bool create_view, const void* data);
+tex_handle ral_texture_load_from_file(const char* filepath) {}
+void ral_texture_destroy(tex_handle handle);
+
+gpu_encoder* ral_render_encoder(render_pass_desc rpass_desc) { return NULL; }
+
+void ral_encoder_finish(gpu_encoder* enc) {}
+void ral_encoder_submit(gpu_encoder* enc) {}
+void ral_encoder_finish_and_submit(gpu_encoder* enc) {}
+
+pipeline_handle ral_gfx_pipeline_create(gfx_pipeline_desc desc) {}
+void ral_gfx_pipeline_destroy(pipeline_handle handle) {}
+
+void ral_encode_bind_pipeline(gpu_encoder* enc, pipeline_handle pipeline) {}
+void ral_set_default_settings(gpu_encoder* enc) {}
+void ral_encode_set_vertex_buf(gpu_encoder* enc, buf_handle vbuf) {}
+void ral_encode_set_index_buf(gpu_encoder* enc, buf_handle ibuf) {}
+void ral_encode_set_texture(gpu_encoder* enc, tex_handle texture, u32 slot) {}
+void ral_bind_buffer(gpu_encoder* enc, buf_handle, u32 index) {}
+void ral_encode_draw_tris(gpu_encoder* enc, size_t start, size_t count) {}
+
+void ral_frame_start() {}
+
+void ral_frame_draw(scoped_draw_commands draw_fn) {}
+void ral_frame_end() {}
+
+#endif
diff --git a/src/camera.c b/src/camera.c
index 2f5506e..8fe727f 100644
--- a/src/camera.c
+++ b/src/camera.c
@@ -2,7 +2,7 @@
* @file camera.c
* @author Omniscient
* @brief Camera movement
- *
+ *
* @copyright Copyright (c) 2024
*/
diff --git a/src/core.c b/src/core.c
index addae75..df066c0 100644
--- a/src/core.c
+++ b/src/core.c
@@ -1,8 +1,8 @@
/**
* @file core.c
* @author Omniscient
- * @brief
- *
+ * @brief
+ *
* @copyright Copyright (c) 2024
*/
diff --git a/src/impl.c b/src/impl.c
index 3af8ed2..8010b30 100644
--- a/src/impl.c
+++ b/src/impl.c
@@ -2,7 +2,7 @@
* @file impl.c
* @author Omniscient
* @brief Pulls in implementations of single-header libraries
- *
+ *
* @copyright Copyright (c) 2024
*/