From 32f49ebe974b1f14f9081196acceb95610949d5a Mon Sep 17 00:00:00 2001 From: Greg Wells Date: Thu, 29 May 2025 13:05:54 -0400 Subject: [PATCH] metal framebuffers --- .../src/core/framebuffers/metal_framebuffer.h | 8 ++ .../src/core/framebuffers/metal_framebuffer.m | 74 +++++++++++++++++++ src/utils/gryphn_error_code.h | 4 +- 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 rendering_api/metal/src/core/framebuffers/metal_framebuffer.h create mode 100644 rendering_api/metal/src/core/framebuffers/metal_framebuffer.m diff --git a/rendering_api/metal/src/core/framebuffers/metal_framebuffer.h b/rendering_api/metal/src/core/framebuffers/metal_framebuffer.h new file mode 100644 index 0000000..519a6ad --- /dev/null +++ b/rendering_api/metal/src/core/framebuffers/metal_framebuffer.h @@ -0,0 +1,8 @@ +#pragma once +#include "core/framebuffer/gryphn_framebuffer.h" +#import +#import + +typedef struct gnPlatformFramebuffer_t { + MTLRenderPassDescriptor* framebuffer; +} gnPlatformFramebuffer; diff --git a/rendering_api/metal/src/core/framebuffers/metal_framebuffer.m b/rendering_api/metal/src/core/framebuffers/metal_framebuffer.m new file mode 100644 index 0000000..ad45fb1 --- /dev/null +++ b/rendering_api/metal/src/core/framebuffers/metal_framebuffer.m @@ -0,0 +1,74 @@ +#include "metal_framebuffer.h" +#include "core/debugger/gryphn_debugger.h" +#include "core/texture/metal_texture.h" + +gnBool isDepthFormat(gnImageFormat format) { + return gnFalse; +} + +gnBool isStencilFormat(gnImageFormat format) { + return gnFalse; +} + +MTLLoadAction mtlGryphnLoadOperation(enum gnLoadOperation_e loadOperation) { + switch(loadOperation) { + case GN_LOAD_OPERATION_LOAD: return MTLLoadActionLoad; + case GN_LOAD_OPERATION_CLEAR: return MTLLoadActionClear; + case GN_LOAD_OPERATION_DONT_CARE: return MTLLoadActionDontCare; + } +} + +MTLStoreAction mtlGryphnStoreOperation(enum gnStoreOperation_e storeOperation) { + switch (storeOperation) { + case GN_STORE_OPERATION_STORE: return MTLStoreActionStore; + case GN_STORE_OPERATION_DONT_CARE: return MTLStoreActionDontCare; + } +} + +gnReturnCode gnCreateFramebufferFn(struct gnFramebuffer_t* framebuffer, struct gnOutputDevice_t* device, struct gnFramebufferInfo_t info) { + framebuffer->framebuffer = malloc(sizeof(struct gnPlatformFramebuffer_t)); + if (info.attachmentCount != info.renderPassDescriptor->info.attachmentCount) { + gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ + .message = gnCreateString("Attachment count on framebuffer does not equal attachment count on render pass descriptor") + }); + return GN_DIVERGENT_RENDERPASS; + } + + framebuffer->framebuffer->framebuffer = [[MTLRenderPassDescriptor alloc] init]; + [framebuffer->framebuffer->framebuffer setRenderTargetWidth:info.size.x]; + [framebuffer->framebuffer->framebuffer setRenderTargetHeight:info.size.y]; + + for (int i = 0; i < info.renderPassDescriptor->info.attachmentCount; i++) { + gnBool wasDepthStencil = gnFalse; + if (isDepthFormat(info.renderPassDescriptor->info.attachmentInfos[i].format)) { + gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ + .message = gnCreateString("Depth attachments are not currently supported in metal (get on this)") + }); + wasDepthStencil = gnTrue; + } + if (isStencilFormat(info.renderPassDescriptor->info.attachmentInfos[i].format)) { + gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ + .message = gnCreateString("Stencil attachments are not currently supported in metal (get on this)") + }); + wasDepthStencil = gnTrue; + } + + if(!wasDepthStencil) { + MTLRenderPassColorAttachmentDescriptor* color = framebuffer->framebuffer->framebuffer.colorAttachments[i]; + color.texture = info.attachments[i].texture->texture; + + color.loadAction = mtlGryphnLoadOperation(info.renderPassDescriptor->info.attachmentInfos[i].loadOperation); + color.storeAction = mtlGryphnStoreOperation(info.renderPassDescriptor->info.attachmentInfos[i].storeOperation); + + if (color.loadAction == MTLLoadActionClear) + color.clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0); + } + } + + return GN_SUCCESS; +} + +void gnDestroyFramebufferFn(struct gnFramebuffer_t* framebuffer) { + [framebuffer->framebuffer->framebuffer release]; + free(framebuffer->framebuffer); +} diff --git a/src/utils/gryphn_error_code.h b/src/utils/gryphn_error_code.h index aed17a4..faa96ee 100644 --- a/src/utils/gryphn_error_code.h +++ b/src/utils/gryphn_error_code.h @@ -25,7 +25,8 @@ typedef enum gnReturnCode_t { GN_FAILED_TO_CREATE_GRAPHICS_PIPELINE, GN_UNSUPPORTED_SHADER_MODULE, GN_UNKNOWN_SUBPASS, - GN_FAILED_TO_CREATE_FRAMEBUFFER + GN_FAILED_TO_CREATE_FRAMEBUFFER, + GN_DIVERGENT_RENDERPASS } gnReturnCode; typedef gnReturnCode gnErrorCode; @@ -56,5 +57,6 @@ static const char* gnErrorCodeToCString(enum gnReturnCode_t returnCode) { case GN_UNSUPPORTED_SHADER_MODULE: return "GN_UNSUPPORTED_SHADER_MODULE"; case GN_UNKNOWN_SUBPASS: return "GN_UNKNOWN_SUBPASS"; case GN_FAILED_TO_CREATE_FRAMEBUFFER: return "GN_FAILED_TO_CREATE_FRAMEBUFFER"; + case GN_DIVERGENT_RENDERPASS: return "GN_DIVERGENT_RENDERPASS"; } }