diff --git a/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.h b/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.h new file mode 100644 index 0000000..5032b23 --- /dev/null +++ b/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.h @@ -0,0 +1,7 @@ +#pragma once +#include "core/pipelines/graphics_pipeline/gryphn_graphics_pipeline.h" +#import + +typedef struct gnPlatformGraphicsPipeline_t { + id graphicsPipeline; +} gnPlatformGraphicsPipeline; diff --git a/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.m b/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.m new file mode 100644 index 0000000..2b4479d --- /dev/null +++ b/rendering_api/metal/src/core/pipelines/graphics_pipeline/metal_graphics_pipeline.m @@ -0,0 +1,68 @@ +#include "metal_graphics_pipeline.h" +#include "core/devices/metal_output_devices.h" +#include "core/debugger/gryphn_debugger.h" +#include "core/shader_module/metal_shader_module.h" +#include "core/surface/metal_surface.h" + +MTLBlendFactor vkGryphnBlendFactor(enum gnBlendFactor_e factor) { + switch (factor) { + case GN_BLEND_FACTOR_ZERO: return MTLBlendFactorZero; + case GN_BLEND_FACTOR_ONE: return MTLBlendFactorOne; + case GN_BLEND_FACTOR_SRC_ALPHA: return MTLBlendFactorSourceAlpha; + case GN_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA: return MTLBlendFactorOneMinusSourceAlpha; + } +} + +MTLBlendOperation vkGryphnBlendOperation(enum gnBlendOperation_e operation) { + switch(operation) { + case GN_OPERATION_ADD: return MTLBlendOperationAdd; + } +} + +gnReturnCode gnCreateGraphicsPipelineFn(struct gnGraphicsPipeline_t* graphicsPipeline, struct gnOutputDevice_t* device, struct gnGraphicsPipelineInfo_t info) { + graphicsPipeline->graphicsPipeline = malloc(sizeof(struct gnPlatformGraphicsPipeline_t)); + MTLRenderPipelineDescriptor* descriptor = [[MTLRenderPipelineDescriptor alloc] init]; + + for (int i = 0; i < info.renderPassDescriptor->info.attachmentCount; i++) { + [descriptor.colorAttachments objectAtIndexedSubscript:i].pixelFormat = mtlGryphnFormatToVulkanFormat(info.renderPassDescriptor->info.attachmentInfos[i].format); + if (info.colorBlending.enable == gnTrue) { + [descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = YES; + [descriptor.colorAttachments objectAtIndexedSubscript:i].rgbBlendOperation = vkGryphnBlendOperation(info.colorBlending.colorBlendOperation); + [descriptor.colorAttachments objectAtIndexedSubscript:i].alphaBlendOperation = vkGryphnBlendOperation(info.colorBlending.alphaBlendOperation); + [descriptor.colorAttachments objectAtIndexedSubscript:i].sourceRGBBlendFactor = vkGryphnBlendFactor(info.colorBlending.sourceColorBlendFactor); + [descriptor.colorAttachments objectAtIndexedSubscript:i].sourceAlphaBlendFactor = vkGryphnBlendFactor(info.colorBlending.sourceAlphaBlendFactor); + [descriptor.colorAttachments objectAtIndexedSubscript:i].destinationRGBBlendFactor = vkGryphnBlendFactor(info.colorBlending.destinationColorBlendFactor); + [descriptor.colorAttachments objectAtIndexedSubscript:i].destinationAlphaBlendFactor = vkGryphnBlendFactor(info.colorBlending.destinationAlphaBlendFactor); + } else { + [descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = FALSE; + } + } + + for (int i = 0; i < info.shaderModuleCount; i++) { + if (info.shaderModules[i].info.stage == GN_VERTEX_SHADER_MODULE) { + [descriptor setVertexFunction:info.shaderModules[i].shaderModule->function]; + } else if (info.shaderModules[i].info.stage == GN_FRAGMENT_SHADER_MODULE) { + [descriptor setFragmentFunction:info.shaderModules[i].shaderModule->function]; + } else { + return GN_UNSUPPORTED_SHADER_MODULE; + } + } + + + NSError* error = nil; + graphicsPipeline->graphicsPipeline->graphicsPipeline = [device->outputDevice->device newRenderPipelineStateWithDescriptor:descriptor error:&error]; + if (graphicsPipeline->graphicsPipeline->graphicsPipeline == nil) { + gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ + .message = gnCombineStrings(gnCreateString("Failed to create metal render pipeline descriptor "), error.localizedDescription.UTF8String) + }); + return GN_FAILED_TO_CREATE_GRAPHICS_PIPELINE; + } + [descriptor release]; + [error release]; + return GN_SUCCESS; +} + +void gnDestroyGraphicsPipelineFn(struct gnGraphicsPipeline_t *graphicsPipeline) { + [graphicsPipeline->graphicsPipeline->graphicsPipeline release]; + free(graphicsPipeline->graphicsPipeline); +} diff --git a/src/core/renderpass/gryphn_render_pass_descriptor.c b/src/core/renderpass/gryphn_render_pass_descriptor.c index d282125..3a73d98 100644 --- a/src/core/renderpass/gryphn_render_pass_descriptor.c +++ b/src/core/renderpass/gryphn_render_pass_descriptor.c @@ -3,6 +3,7 @@ gnReturnCode gnCreateRenderPassDescriptor(struct gnRenderPassDescriptor_t* renderPass, struct gnOutputDevice_t* device, struct gnRenderPassDescriptorInfo_t info) { renderPass->device = device; + renderPass->info = info; return device->deviceFunctions->_gnCreateRenderPassDescriptor(renderPass, device, info); } diff --git a/src/core/renderpass/gryphn_render_pass_descriptor.h b/src/core/renderpass/gryphn_render_pass_descriptor.h index 5fb9d26..cb71b22 100644 --- a/src/core/renderpass/gryphn_render_pass_descriptor.h +++ b/src/core/renderpass/gryphn_render_pass_descriptor.h @@ -45,6 +45,7 @@ struct gnPlatformRenderPassDescriptor_t; typedef struct gnRenderPassDescriptor_t { struct gnPlatformRenderPassDescriptor_t* renderPassDescriptor; + struct gnRenderPassDescriptorInfo_t info; struct gnOutputDevice_t* device; } gnRenderPassDescriptor; diff --git a/src/core/shader_module/gryphn_shader_module.c b/src/core/shader_module/gryphn_shader_module.c index 3b7aa90..f8a7992 100644 --- a/src/core/shader_module/gryphn_shader_module.c +++ b/src/core/shader_module/gryphn_shader_module.c @@ -3,6 +3,7 @@ gnReturnCode gnCreateShaderModule(struct gnShaderModule_t* module, struct gnOutputDevice_t* device, struct gnShaderModuleInfo_t shaderModuleInfo) { module->device = device; + module->info = shaderModuleInfo; return device->deviceFunctions->_gnCreateShaderModule(module, device, shaderModuleInfo); } diff --git a/src/core/shader_module/gryphn_shader_module.h b/src/core/shader_module/gryphn_shader_module.h index 254b717..767638a 100644 --- a/src/core/shader_module/gryphn_shader_module.h +++ b/src/core/shader_module/gryphn_shader_module.h @@ -18,6 +18,7 @@ struct gnPlatformShaderModule_t; typedef struct gnShaderModule_t { struct gnPlatformShaderModule_t* shaderModule; + struct gnShaderModuleInfo_t info; struct gnOutputDevice_t* device; } gnShaderModule; diff --git a/src/utils/gryphn_error_code.h b/src/utils/gryphn_error_code.h index 4583afc..23d99e7 100644 --- a/src/utils/gryphn_error_code.h +++ b/src/utils/gryphn_error_code.h @@ -22,15 +22,8 @@ typedef enum gnReturnCode_t { GN_FAILED_TO_FIND_ENTRY_POINT, GN_FAILED_TO_CREATE_UNIFORM_LAYOUT, GN_FAILED_TO_CREATE_RENDER_PASS, - GN_FAILED_TO_CREATE_GRAPHICS_PIPELINE - - // GN_UNKNOWN_FRAMEBUFFER_ATTACHMENT, - // GN_UNKNOWN_FUNCTION, - // GN_UNKNOWN_COLOR_FORMAT, - // GN_FAILED_CREATE_GRAPHICS_PIPELINE, - // GN_FAILED_TO_CREATE_FRAMEBUFFER, - // GN_FAILED_CREATE_RENDERPASS, - // GN_FAILED_TO_CREATE_IMAGE + GN_FAILED_TO_CREATE_GRAPHICS_PIPELINE, + GN_UNSUPPORTED_SHADER_MODULE } gnReturnCode; typedef gnReturnCode gnErrorCode; @@ -58,5 +51,6 @@ static const char* gnErrorCodeToCString(enum gnReturnCode_t returnCode) { case GN_FAILED_TO_CREATE_UNIFORM_LAYOUT: return "GN_FAILED_TO_CREATE_UNIFORM_LAYOUT"; case GN_FAILED_TO_CREATE_RENDER_PASS: return "GN_FAILED_TO_CREATE_RENDER_PASS"; case GN_FAILED_TO_CREATE_GRAPHICS_PIPELINE: return "GN_FAILED_TO_CREATE_GRAPHICS_PIPELINE"; + case GN_UNSUPPORTED_SHADER_MODULE: return "GN_UNSUPPORTED_SHADER_MODULE"; } }