diff options
author | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-09 01:43:02 +1000 |
---|---|---|
committer | omniscient <17525998+omnisci3nce@users.noreply.github.com> | 2024-06-09 01:43:02 +1000 |
commit | 859ea7e23d2bbbc4b32b43727ae50aebe399e720 (patch) | |
tree | 868b5d938cec7846637cf403cde3723829822305 | |
parent | 19a5fae08d7f1f85cb5448a5f2b19f0f9d342a0e (diff) |
metal is back, baby
-rw-r--r-- | assets/shaders/blinn_phong.vert | 2 | ||||
-rw-r--r-- | assets/shaders/cube.frag | 2 | ||||
-rw-r--r-- | assets/shaders/cube.vert | 2 | ||||
-rw-r--r-- | assets/shaders/triangle.metal | 33 | ||||
-rw-r--r-- | assets/shaders/triangle.vert | 2 | ||||
-rw-r--r-- | deps/Unity/extras/fixture/src/unity_fixture.c | 6 | ||||
-rw-r--r-- | examples/cube/ex_cube.c | 4 | ||||
-rw-r--r-- | examples/triangle/ex_triangle.c | 42 | ||||
-rw-r--r-- | src/defines.h | 4 | ||||
-rw-r--r-- | src/renderer/backends/backend_vulkan.c | 1 | ||||
-rw-r--r-- | src/renderer/backends/metal/backend_metal.h | 74 | ||||
-rw-r--r-- | src/renderer/backends/metal/backend_metal.m | 285 | ||||
-rw-r--r-- | src/renderer/backends/opengl/backend_opengl.c | 2 | ||||
-rw-r--r-- | src/renderer/backends/opengl/opengl_helpers.h | 18 | ||||
-rw-r--r-- | src/renderer/ral.c | 6 | ||||
-rw-r--r-- | src/renderer/ral.h | 3 | ||||
-rw-r--r-- | src/renderer/render_types.h | 4 | ||||
-rw-r--r-- | xmake.lua | 13 |
18 files changed, 458 insertions, 45 deletions
diff --git a/assets/shaders/blinn_phong.vert b/assets/shaders/blinn_phong.vert index 1d2a53e..18609b7 100644 --- a/assets/shaders/blinn_phong.vert +++ b/assets/shaders/blinn_phong.vert @@ -1,4 +1,4 @@ -#version 430 core +#version 410 core struct Uniforms { mat4 model; diff --git a/assets/shaders/cube.frag b/assets/shaders/cube.frag index 292578f..88ba822 100644 --- a/assets/shaders/cube.frag +++ b/assets/shaders/cube.frag @@ -1,4 +1,4 @@ -#version 450 +#version 430 layout(location = 0) in vec3 fragColor; layout(location = 1) in vec2 fragTexCoord; diff --git a/assets/shaders/cube.vert b/assets/shaders/cube.vert index fa9f85b..2f1d76d 100644 --- a/assets/shaders/cube.vert +++ b/assets/shaders/cube.vert @@ -1,4 +1,4 @@ -#version 450 +#version 430 layout(binding = 0) uniform UniformBufferObject { mat4 model; diff --git a/assets/shaders/triangle.metal b/assets/shaders/triangle.metal new file mode 100644 index 0000000..6055705 --- /dev/null +++ b/assets/shaders/triangle.metal @@ -0,0 +1,33 @@ +#include <metal_stdlib> + +using namespace metal; + +struct VertexIn { + float2 position; + float3 color; +}; + +struct VertexOut { + float4 computedPosition [[position]]; + float3 fragColor; +}; + +// Vertex shader +vertex VertexOut basic_vertex( + const device VertexIn* vertex_array [[ buffer(0) ]], + unsigned int vid [[ vertex_id ]] + ) { + VertexIn v = vertex_array[vid]; + + VertexOut outVertex = VertexOut(); + outVertex.computedPosition = float4(v.position.xy, 0.0, 1.0); + outVertex.fragColor = v.color; + return outVertex; +} + +// Fragment shader +fragment float4 basic_fragment( + VertexOut interpolated [[stage_in]] +) { + return float4(interpolated.fragColor, 1.0); +}
\ No newline at end of file diff --git a/assets/shaders/triangle.vert b/assets/shaders/triangle.vert index 8030561..f98696c 100644 --- a/assets/shaders/triangle.vert +++ b/assets/shaders/triangle.vert @@ -1,4 +1,4 @@ -#version 450 +#version 430 layout(location = 0) in vec2 inPos; layout(location = 1) in vec3 inColor; diff --git a/deps/Unity/extras/fixture/src/unity_fixture.c b/deps/Unity/extras/fixture/src/unity_fixture.c index e69b5a3..8ffe1f8 100644 --- a/deps/Unity/extras/fixture/src/unity_fixture.c +++ b/deps/Unity/extras/fixture/src/unity_fixture.c @@ -15,10 +15,8 @@ struct UNITY_FIXTURE_T UnityFixture; * Build with -D UNITY_OUTPUT_CHAR=outputChar and include <stdio.h> * int (*outputChar)(int) = putchar; */ -void setUp(void) { /*does nothing*/ -} -void tearDown(void) { /*does nothing*/ -} +void setUp(void) { /*does nothing*/ } +void tearDown(void) { /*does nothing*/ } static void announceTestRun(unsigned int runNumber) { UnityPrint("Unity test run "); diff --git a/examples/cube/ex_cube.c b/examples/cube/ex_cube.c index 7b0ab48..a3d5a9f 100644 --- a/examples/cube/ex_cube.c +++ b/examples/cube/ex_cube.c @@ -70,8 +70,8 @@ int main() { str8 vert_path, frag_path; #ifdef CEL_REND_BACKEND_OPENGL - vert_path = str8lit("assets/shaders/blinn_phong.vert"); - frag_path = str8lit("assets/shaders/blinn_phong.frag"); + vert_path = str8lit("assets/shaders/cube.vert"); + frag_path = str8lit("assets/shaders/cube.frag"); #else vert_path = str8lit("build/linux/x86_64/debug/cube.vert.spv"); frag_path = str8lit("build/linux/x86_64/debug/cube.frag.spv"); diff --git a/examples/triangle/ex_triangle.c b/examples/triangle/ex_triangle.c index 0191c18..d9954e6 100644 --- a/examples/triangle/ex_triangle.c +++ b/examples/triangle/ex_triangle.c @@ -36,12 +36,12 @@ int main() { gpu_renderpass* renderpass = gpu_renderpass_create(&pass_description); str8 vert_path, frag_path; -#ifdef CEL_REND_BACKEND_OPENGL +#if defined(CEL_REND_BACKEND_OPENGL) vert_path = str8lit("assets/shaders/triangle.vert"); frag_path = str8lit("assets/shaders/triangle.frag"); -#else - vert_path = str8lit("build/linux/x86_64/debug/triangle.vert.spv"); - frag_path = str8lit("build/linux/x86_64/debug/triangle.frag.spv"); +#elif defined(CEL_REND_BACKEND_METAL) + vert_path = str8lit("build/gfx.metallib"); + frag_path = str8lit("build/gfx.metallib"); #endif str8_opt vertex_shader = str8_from_file(&scratch, vert_path); str8_opt fragment_shader = str8_from_file(&scratch, frag_path); @@ -57,7 +57,11 @@ int main() { .vs = { .debug_name = "Triangle Vertex Shader", .filepath = vert_path, .code = vertex_shader.contents, - .is_spirv = true }, +#ifdef CEL_REND_BACKEND_METAL + .is_combined_vert_frag = true, +#endif + .is_spirv = true, + }, .fs = { .debug_name = "Triangle Fragment Shader", .filepath = frag_path, .code = fragment_shader.contents, @@ -75,7 +79,7 @@ int main() { buffer_handle triangle_index_buf = gpu_buffer_create(sizeof(indices), CEL_BUFFER_INDEX, CEL_BUFFER_FLAG_GPU, indices); - // Main loop + // // Main loop while (!should_exit()) { input_update(&g_core.input); @@ -83,24 +87,24 @@ int main() { continue; } gpu_cmd_encoder* enc = gpu_get_default_cmd_encoder(); - // Begin recording + // // Begin recording gpu_cmd_encoder_begin(*enc); gpu_cmd_encoder_begin_render(enc, renderpass); - encode_bind_pipeline(enc, PIPELINE_GRAPHICS, gfx_pipeline); - encode_set_default_settings(enc); + // encode_bind_pipeline(enc, PIPELINE_GRAPHICS, gfx_pipeline); + // encode_set_default_settings(enc); - // Record draw calls - encode_set_vertex_buffer(enc, triangle_vert_buf); - encode_set_index_buffer(enc, triangle_index_buf); - encode_draw_indexed(enc, 6); + // // Record draw calls + // encode_set_vertex_buffer(enc, triangle_vert_buf); + // encode_set_index_buffer(enc, triangle_index_buf); + // encode_draw_indexed(enc, 6); - // End recording - gpu_cmd_encoder_end_render(enc); + // // End recording + // gpu_cmd_encoder_end_render(enc); - gpu_cmd_buffer buf = gpu_cmd_encoder_finish( - enc); // Command buffer is no longer recording and is ready to submit - // Submit - gpu_queue_submit(&buf); + // gpu_cmd_buffer buf = gpu_cmd_encoder_finish(enc); // Command buffer is no longer recording + // and is ready to submit + // // Submit + // gpu_queue_submit(&buf); gpu_backend_end_frame(); } diff --git a/src/defines.h b/src/defines.h index a35dbf4..9050f25 100644 --- a/src/defines.h +++ b/src/defines.h @@ -77,6 +77,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/backends/backend_vulkan.c b/src/renderer/backends/backend_vulkan.c index 06d8898..112e38b 100644 --- a/src/renderer/backends/backend_vulkan.c +++ b/src/renderer/backends/backend_vulkan.c @@ -403,6 +403,7 @@ VkFormat format_from_vertex_attr(vertex_attrib_type attr) { } gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description) { + TRACE("GPU Graphics Pipeline creation"); // Allocate gpu_pipeline_layout* layout = pipeline_layout_pool_alloc(&context.gpu_pools.pipeline_layouts, NULL); diff --git a/src/renderer/backends/metal/backend_metal.h b/src/renderer/backends/metal/backend_metal.h new file mode 100644 index 0000000..59b21d6 --- /dev/null +++ b/src/renderer/backends/metal/backend_metal.h @@ -0,0 +1,74 @@ +#pragma once +#define CEL_REND_BACKEND_METAL +#if defined(CEL_REND_BACKEND_METAL) + +#include "defines.h" +#include "maths_types.h" +#ifdef __OBJC__ +#import <Metal/Metal.h> +#import <MetalKit/MetalKit.h> +#import <QuartzCore/CAMetalLayer.h> +#import <Foundation/Foundation.h> +#else +typedef void* id; +#endif + +typedef struct gpu_swapchain { + u32x2 dimensions; + #ifdef __OBJC__ + CAMetalLayer* swapchain; + #else + void* swapchain; + #endif +} gpu_swapchain; +typedef struct gpu_device { + /** @brief `device` gives us access to our GPU */ + #ifdef __OBJC__ + id<MTLDevice> id; + #else + void* id; + #endif +} gpu_device; +typedef struct gpu_pipeline_layout { + void* pad; +} gpu_pipeline_layout; +typedef struct gpu_pipeline { + #ifdef __OBJC__ + id<MTLRenderPipelineState> pipeline_state; + #else + void* pipeline_state; + #endif +} gpu_pipeline; +typedef struct gpu_renderpass { + #ifdef __OBJC__ + MTLRenderPassDescriptor* rpass_descriptor; + #else + void* rpass_descriptor; + #endif +} gpu_renderpass; +typedef struct gpu_cmd_encoder { + #ifdef __OBJC__ + id<MTLCommandBuffer> cmd_buffer; + id<MTLRenderCommandEncoder> render_encoder; + #else + void* cmd_buffer; + void* render_encoder; + #endif +} gpu_cmd_encoder; +typedef struct gpu_cmd_buffer { + void* pad; +} gpu_cmd_buffer; + +typedef struct gpu_buffer { + #ifdef __OBJC__ + id<MTLBuffer> id; + #else + void* id; + #endif + u64 size; +} gpu_buffer; +typedef struct gpu_texture { + void* pad; +} gpu_texture; + +#endif
\ No newline at end of file diff --git a/src/renderer/backends/metal/backend_metal.m b/src/renderer/backends/metal/backend_metal.m new file mode 100644 index 0000000..0e9399e --- /dev/null +++ b/src/renderer/backends/metal/backend_metal.m @@ -0,0 +1,285 @@ +#include <assert.h> +#define CEL_REND_BACKEND_METAL +#if defined(CEL_REND_BACKEND_METAL) +#include <stddef.h> +#include "ral_types.h" +#include "colours.h" +#include <stdlib.h> +#include "camera.h" +#include "defines.h" +#include "file.h" +#include "log.h" +#include "maths_types.h" +#include "ral.h" + +#define GLFW_INCLUDE_NONE +#define GLFW_EXPOSE_NATIVE_COCOA + +#include <GLFW/glfw3.h> +#include <GLFW/glfw3native.h> + +#import <Foundation/Foundation.h> +#import <Metal/Metal.h> +#import <MetalKit/MetalKit.h> +#import <QuartzCore/CAMetalLayer.h> +#include "backend_metal.h" + +// --- 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)) + +typedef struct metal_context { + GLFWwindow* window; + NSWindow* metal_window; + arena pool_arena; + + gpu_device* device; + gpu_swapchain* swapchain; + id<CAMetalDrawable> surface; + + id<MTLCommandQueue> command_queue; + gpu_cmd_encoder main_command_buf; + gpu_backend_pools gpu_pools; + struct resource_pools* resource_pools; +} metal_context; + +static metal_context context; + +struct GLFWwindow; + +bool gpu_backend_init(const char *window_name, struct GLFWwindow *window) { + INFO("loading Metal backend"); + + memset(&context, 0, sizeof(metal_context)); + context.window = window; + + size_t pool_buffer_size = 1024 * 1024; + context.pool_arena = arena_create(malloc(pool_buffer_size), pool_buffer_size); + + backend_pools_init(&context.pool_arena, &context.gpu_pools); + context.resource_pools = malloc(sizeof(struct resource_pools)); + resource_pools_init(&context.pool_arena, context.resource_pools); + + glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); + + glfwMakeContextCurrent(window); + // FIXME: glfwSetFramebufferSizeCallback(ren->window, framebuffer_size_callback); + + // get a NSWindow pointer from GLFWwindow + NSWindow *nswindow = glfwGetCocoaWindow(window); + context.metal_window = nswindow; + + // const id<MTLCommandQueue> queue = [gpu newCommandQueue]; + // CAMetalLayer *swapchain = [CAMetalLayer layer]; + // swapchain.device = gpu; + // swapchain.opaque = YES; + + // // set swapchain for the window + // nswindow.contentView.layer = swapchain; + // nswindow.contentView.wantsLayer = YES; + + // MTLClearColor color = MTLClearColorMake(0.7, 0.1, 0.2, 1.0); + + // // set all our state properties + // state->device = gpu; + // state->cmd_queue = queue; + // state->swapchain = swapchain; + // state->clear_color = color; + + // NSError *err = 0x0; // TEMPORARY + + // WARN("About to try loading metallib"); + // id<MTLLibrary> defaultLibrary = [state->device newLibraryWithFile: @"build/gfx.metallib" error:&err]; + // CASSERT(defaultLibrary); + // state->default_lib = defaultLibrary; + // if (!state->default_lib) { + // NSLog(@"Failed to load library"); + // exit(0); + // } + + // create_render_pipeline(state); + + return true; +} + +void gpu_backend_shutdown() {} + +bool gpu_device_create(gpu_device* out_device) { + TRACE("GPU Device creation"); + const id<MTLDevice> gpu = MTLCreateSystemDefaultDevice(); + out_device->id = gpu; + context.device = out_device; + + const id<MTLCommandQueue> queue = [gpu newCommandQueue]; + context.command_queue = queue; + + return true; +} +void gpu_device_destroy() {} + +// --- Render Pipeline +gpu_pipeline* gpu_graphics_pipeline_create(struct graphics_pipeline_desc description) { + TRACE("GPU Graphics Pipeline creation"); + // Allocate + // gpu_pipeline_layout* layout = + // pipeline_layout_pool_alloc(&context.gpu_pools.pipeline_layouts, NULL); + gpu_pipeline* pipeline = pipeline_pool_alloc(&context.gpu_pools.pipelines, NULL); + + WARN("About to try loading metallib"); + assert(description.vs.is_combined_vert_frag); + // Ignore fragment shader data, as vert shader data contains both + NSError *err = 0x0; // TEMPORARY + NSString *myNSString = [NSString stringWithUTF8String:(char*)description.vs.filepath.buf]; + id<MTLLibrary> default_library = [context.device->id newLibraryWithFile:myNSString error:&err]; + assert(default_library); + + // setup vertex and fragment shaders + id<MTLFunction> ren_vert = [default_library newFunctionWithName:@"basic_vertex"]; + assert(ren_vert); + id<MTLFunction> ren_frag = [default_library newFunctionWithName:@"basic_fragment"]; + assert(ren_frag); + + // create pipeline descriptor + @autoreleasepool { + NSError *err = 0x0; + MTLRenderPipelineDescriptor *pld = [[MTLRenderPipelineDescriptor alloc] init]; + NSString *pipeline_name = [NSString stringWithUTF8String: description.debug_name]; + pld.label = pipeline_name; + pld.vertexFunction = ren_vert; + pld.fragmentFunction = ren_frag; + pld.colorAttachments[0].pixelFormat = MTLPixelFormatBGRA8Unorm; + pld.colorAttachments[0].blendingEnabled = YES; + + MTLDepthStencilDescriptor *depthStencilDescriptor = [MTLDepthStencilDescriptor new]; + depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionLess; + depthStencilDescriptor.depthWriteEnabled = YES; + pld.depthAttachmentPixelFormat = MTLPixelFormatDepth32Float_Stencil8; + + id<MTLDepthStencilState> depth_descriptor = [context.device->id newDepthStencilStateWithDescriptor:depthStencilDescriptor]; + // FIXME: state->depth_state = depth_descriptor; + + id<MTLRenderPipelineState> pipeline_state = [context.device->id newRenderPipelineStateWithDescriptor:pld error:&err]; + TRACE("created renderpipelinestate"); + pipeline->pipeline_state = pipeline_state; + + } + + return pipeline; +} +void gpu_pipeline_destroy(gpu_pipeline* pipeline) {} + +// --- Renderpass +gpu_renderpass* gpu_renderpass_create(const gpu_renderpass_desc* description) { + gpu_renderpass* renderpass = renderpass_pool_alloc(&context.gpu_pools.renderpasses, NULL); + + // TODO: Configure based on description + // set up render pass + context.surface = [context.swapchain->swapchain nextDrawable]; + MTLRenderPassDescriptor *renderPassDescriptor = [[MTLRenderPassDescriptor alloc] init]; + MTLRenderPassColorAttachmentDescriptor *cd = renderPassDescriptor.colorAttachments[0]; + [cd setTexture:context.surface.texture]; + [cd setLoadAction:MTLLoadActionClear]; + MTLClearColor clearColor = MTLClearColorMake(0.1, 0.1, 0.0, 1.0); + [cd setClearColor:clearColor]; + [cd setStoreAction:MTLStoreActionStore]; + + renderpass->rpass_descriptor = renderPassDescriptor; + + return renderpass; +} + +void gpu_renderpass_destroy(gpu_renderpass* pass) {} + +// --- Swapchain +bool gpu_swapchain_create(gpu_swapchain* out_swapchain) { + TRACE("GPU Swapchain creation"); + CAMetalLayer *swapchain = [CAMetalLayer layer]; + swapchain.device = context.device->id; + swapchain.opaque = YES; + out_swapchain->swapchain = swapchain; + + // set swapchain for the window + context.metal_window.contentView.layer = swapchain; + context.metal_window.contentView.wantsLayer = YES; + + context.swapchain = out_swapchain; + return true; +} +void gpu_swapchain_destroy(gpu_swapchain* swapchain) {} + +// --- Command buffer +gpu_cmd_encoder gpu_cmd_encoder_create() { + id <MTLCommandBuffer> cmd_buffer = [context.command_queue commandBuffer]; + + return (gpu_cmd_encoder) { + .cmd_buffer = cmd_buffer + }; +} +void gpu_cmd_encoder_destroy(gpu_cmd_encoder* encoder) {} +void gpu_cmd_encoder_begin(gpu_cmd_encoder encoder) { /* no-op */ } +void gpu_cmd_encoder_begin_render(gpu_cmd_encoder* encoder, gpu_renderpass* renderpass) { + DEBUG("Create Render Command Encoder"); + id<MTLRenderCommandEncoder> render_encoder = [encoder->cmd_buffer renderCommandEncoderWithDescriptor:renderpass->rpass_descriptor]; + encoder->render_encoder = render_encoder; + // [encoder setDepthStencilState:state->depth_state]; +} +void gpu_cmd_encoder_end_render(gpu_cmd_encoder* encoder) {} +void gpu_cmd_encoder_begin_compute() {} +gpu_cmd_encoder* gpu_get_default_cmd_encoder() { + return &context.main_command_buf; +} + +/** @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) {} + +void encode_buffer_copy(gpu_cmd_encoder* encoder, buffer_handle src, u64 src_offset, + buffer_handle dst, u64 dst_offset, u64 copy_size); +void buffer_upload_bytes(buffer_handle gpu_buf, bytebuffer cpu_buf, u64 offset, u64 size); + +void copy_buffer_to_buffer_oneshot(buffer_handle src, u64 src_offset, buffer_handle dst, + u64 dst_offset, u64 copy_size); +void copy_buffer_to_image_oneshot(buffer_handle src, texture_handle dst); + +void encode_bind_pipeline(gpu_cmd_encoder* encoder, pipeline_kind kind, gpu_pipeline* pipeline) {} +void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* data) {} +void encode_set_default_settings(gpu_cmd_encoder* encoder) { + [encoder->render_encoder setCullMode:MTLCullModeBack]; +} +void encode_set_vertex_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) { + gpu_buffer* vertex_buf = BUFFER_GET(buf); + [encoder->render_encoder setVertexBuffer:vertex_buf->id offset:0 atIndex:0]; +} +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) {} +void encode_clear_buffer(gpu_cmd_encoder* encoder, buffer_handle buf) {} + +buffer_handle gpu_buffer_create(u64 size, gpu_buffer_type buf_type, gpu_buffer_flags flags, + const void* data) { + buffer_handle handle; + gpu_buffer* buffer = buffer_pool_alloc(&context.resource_pools->buffers, &handle); + buffer->size = size; + + id<MTLBuffer> mtl_vert_buf = [context.device->id newBufferWithBytes:data + length: size + options:MTLResourceStorageModeShared]; + return handle; +} +void gpu_buffer_destroy(buffer_handle buffer) {} +void gpu_buffer_upload(const void* data) {} + +texture_handle gpu_texture_create(texture_desc desc, bool create_view, const void* data) {} +void gpu_texture_destroy(texture_handle) {} +void gpu_texture_upload(texture_handle texture, const void* data) {} + +bool gpu_backend_begin_frame() { + context.main_command_buf.cmd_buffer = [context.command_queue commandBuffer]; + return true; + } +void gpu_backend_end_frame() {} +void gpu_temp_draw(size_t n_verts) {} + +#endif
\ No newline at end of file diff --git a/src/renderer/backends/opengl/backend_opengl.c b/src/renderer/backends/opengl/backend_opengl.c index 8be1c2a..96415f1 100644 --- a/src/renderer/backends/opengl/backend_opengl.c +++ b/src/renderer/backends/opengl/backend_opengl.c @@ -2,7 +2,7 @@ #include "colours.h" #include "opengl_helpers.h" #include "ral_types.h" -#define CEL_REND_BACKEND_OPENGL +// #define CEL_REND_BACKEND_OPENGL #if defined(CEL_REND_BACKEND_OPENGL) #include <stdlib.h> #include "camera.h" diff --git a/src/renderer/backends/opengl/opengl_helpers.h b/src/renderer/backends/opengl/opengl_helpers.h index 2f6bef3..44d40cb 100644 --- a/src/renderer/backends/opengl/opengl_helpers.h +++ b/src/renderer/backends/opengl/opengl_helpers.h @@ -1,36 +1,36 @@ #pragma once -#include "ral_types.h" #include <glad/glad.h> #include <glfw3.h> +#include "ral_types.h" typedef struct opengl_vertex_attr { u32 count; GLenum data_type; -} opengl_vertex_attr ; +} opengl_vertex_attr; opengl_vertex_attr format_from_vertex_attr(vertex_attrib_type attr) { switch (attr) { case ATTR_F32: - return (opengl_vertex_attr){.count = 1, .data_type = GL_FLOAT }; + return (opengl_vertex_attr){ .count = 1, .data_type = GL_FLOAT }; case ATTR_U32: - return (opengl_vertex_attr){.count = 1, .data_type = GL_UNSIGNED_INT }; + return (opengl_vertex_attr){ .count = 1, .data_type = GL_UNSIGNED_INT }; case ATTR_I32: - return (opengl_vertex_attr){.count = 1, .data_type = GL_INT }; + return (opengl_vertex_attr){ .count = 1, .data_type = GL_INT }; case ATTR_F32x2: - return (opengl_vertex_attr){.count = 2, .data_type = GL_FLOAT }; + return (opengl_vertex_attr){ .count = 2, .data_type = GL_FLOAT }; case ATTR_U32x2: // return VK_FORMAT_R32G32_UINT; case ATTR_I32x2: // return VK_FORMAT_R32G32_UINT; case ATTR_F32x3: - return (opengl_vertex_attr){.count = 3, .data_type = GL_FLOAT }; + return (opengl_vertex_attr){ .count = 3, .data_type = GL_FLOAT }; case ATTR_U32x3: // return VK_FORMAT_R32G32B32_UINT; case ATTR_I32x3: // return VK_FORMAT_R32G32B32_SINT; case ATTR_F32x4: - return (opengl_vertex_attr){.count = 4, .data_type = GL_FLOAT }; + return (opengl_vertex_attr){ .count = 4, .data_type = GL_FLOAT }; case ATTR_U32x4: // return VK_FORMAT_R32G32B32A32_UINT; case ATTR_I32x4: - // return VK_FORMAT_R32G32B32A32_SINT; + return (opengl_vertex_attr){ .count = 4, .data_type = GL_INT }; } }
\ No newline at end of file diff --git a/src/renderer/ral.c b/src/renderer/ral.c index 4f2a999..fe12b4f 100644 --- a/src/renderer/ral.c +++ b/src/renderer/ral.c @@ -1,6 +1,12 @@ #include "ral.h" +#if defined(CEL_REND_BACKEND_VULKAN) +#include "backend_vulkan.h" +#elif defined(CEL_REND_BACKEND_METAL) +#include "backend_metal.h" +#elif defined(CEL_REND_BACKEND_OPENGL) #include "backend_opengl.h" +#endif size_t vertex_attrib_size(vertex_attrib_type attr) { switch (attr) { diff --git a/src/renderer/ral.h b/src/renderer/ral.h index a18ea87..3415b04 100644 --- a/src/renderer/ral.h +++ b/src/renderer/ral.h @@ -66,9 +66,10 @@ typedef enum pipeline_kind { typedef struct shader_desc { const char* debug_name; - str8 filepath; // where it came from + str8 filepath; // Where it came from str8 code; // Either GLSL or SPIRV bytecode bool is_spirv; + bool is_combined_vert_frag; // Contains both vertex and fragment stages } shader_desc; struct graphics_pipeline_desc { diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h index 63e5b29..a2c35fe 100644 --- a/src/renderer/render_types.h +++ b/src/renderer/render_types.h @@ -17,12 +17,12 @@ #endif #if defined(CEL_REND_BACKEND_VULKAN) #include "backend_vulkan.h" +#elif defined(CEL_REND_BACKEND_METAL) +#include "backend_metal.h" #elif defined(CEL_REND_BACKEND_OPENGL) #include "backend_opengl.h" #endif -#include "backend_opengl.h" - struct GLFWwindow; /** @brief configuration passed to the renderer at init time */ @@ -1,6 +1,6 @@ set_project("celeritas") set_version("0.1.0") -set_config("cc", "gcc") +set_config("cc", "clang") add_rules("mode.debug", "mode.release") -- we have two modes: debug & release @@ -30,6 +30,7 @@ elseif is_plat("windows") then elseif is_plat("macosx") then add_defines("CEL_PLATFORM_MAC") add_frameworks("Cocoa", "IOKit", "CoreVideo", "OpenGL") + add_frameworks( "Foundation", "Metal", "QuartzCore") set_runenv("MTL_DEBUG_LAYER", "1") -- add_syslinks("GL") end @@ -62,6 +63,7 @@ local core_sources = { "src/renderer/*.c", "src/renderer/backends/*.c", "src/renderer/backends/opengl/*.c", + "src/renderer/backends/metal/*.m", "src/resources/*.c", "src/std/*.c", "src/std/containers/*.c", @@ -113,6 +115,7 @@ target("core_config") add_includedirs("src/renderer/", {public = true}) add_includedirs("src/renderer/backends/", {public = true}) add_includedirs("src/renderer/backends/opengl", {public = true}) + add_includedirs("src/renderer/backends/metal", {public = true}) add_includedirs("src/resources/", {public = true}) add_includedirs("src/std/", {public = true}) add_includedirs("src/std/containers", {public = true}) @@ -166,6 +169,14 @@ target("tri") add_deps("core_static") add_files("examples/triangle/ex_triangle.c") set_rundir("$(projectdir)") + if is_plat("macosx") then + before_build(function (target) + print("build metal shaders lib") + os.exec("mkdir -p build/shaders") + os.exec("xcrun -sdk macosx metal -c assets/shaders/triangle.metal -o build/shaders/gfx.air") + os.exec("xcrun -sdk macosx metallib build/shaders/gfx.air -o build/gfx.metallib") + end) + end target("cube") set_kind("binary") |