diff options
author | Omniscient <omniscient.oce@gmail.com> | 2024-10-27 00:56:55 +1100 |
---|---|---|
committer | Omniscient <omniscient.oce@gmail.com> | 2024-10-27 00:56:55 +1100 |
commit | e597fbb916848df1f6fbd4da04c1ab6f89a25b45 (patch) | |
tree | 4f7205d14cd78f2a489ab3098c8211549d638448 | |
parent | 3946ae807a2de00b3c810f986f60ba9cc32bc1a7 (diff) |
start on vulkan backend
-rw-r--r-- | Makefile | 13 | ||||
-rw-r--r-- | examples/cube.c | 3 | ||||
-rw-r--r-- | include/celeritas.h | 15 | ||||
-rw-r--r-- | src/backend_vk.c | 149 | ||||
-rw-r--r-- | src/camera.c | 2 | ||||
-rw-r--r-- | src/core.c | 4 | ||||
-rw-r--r-- | src/impl.c | 2 |
7 files changed, 173 insertions, 15 deletions
@@ -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 */ @@ -1,8 +1,8 @@ /** * @file core.c * @author Omniscient - * @brief - * + * @brief + * * @copyright Copyright (c) 2024 */ @@ -2,7 +2,7 @@ * @file impl.c * @author Omniscient * @brief Pulls in implementations of single-header libraries - * + * * @copyright Copyright (c) 2024 */ |