diff --git a/projects/apis/metal/src/commands/commands/metal_commands.m b/projects/apis/metal/src/commands/commands/metal_commands.m index 3fce495..9d92af0 100644 --- a/projects/apis/metal/src/commands/commands/metal_commands.m +++ b/projects/apis/metal/src/commands/commands/metal_commands.m @@ -33,6 +33,7 @@ void endMetalRenderPass(gnCommandBuffer buffer) { void bindMetalGraphicsPipeline(gnCommandBuffer buffer, struct gnGraphicsPipeline_t* graphicsPipeline) { id encoder = (id)buffer->commandBuffer->encoder; [encoder setRenderPipelineState:graphicsPipeline->graphicsPipeline->graphicsPipeline]; + [encoder setDepthStencilState:graphicsPipeline->graphicsPipeline->depthState]; if (graphicsPipeline->info.cullMode.face == GN_CULL_FACE_BACK) [encoder setCullMode:MTLCullModeBack]; diff --git a/projects/apis/metal/src/framebuffers/metal_framebuffer.m b/projects/apis/metal/src/framebuffers/metal_framebuffer.m index ee90bf0..2d465ee 100644 --- a/projects/apis/metal/src/framebuffers/metal_framebuffer.m +++ b/projects/apis/metal/src/framebuffers/metal_framebuffer.m @@ -6,11 +6,11 @@ #include "output_device/gryphn_output_device.h" gnBool isDepthFormat(gnImageFormat format) { - return gnFalse; + return (format == GN_FORMAT_D24S8_UINT) || (format == GN_FORMAT_D32S8_UINT); } gnBool isStencilFormat(gnImageFormat format) { - return gnFalse; + return (format == GN_FORMAT_D24S8_UINT) || (format == GN_FORMAT_D32S8_UINT); } MTLLoadAction mtlGryphnLoadOperation(gnLoadOperation loadOperation) { @@ -45,9 +45,11 @@ gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice de 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)") - }); + MTLRenderPassDepthAttachmentDescriptor* depthAttachment = framebuffer->framebuffer->framebuffer.depthAttachment; + depthAttachment.texture = info.attachments[i]->texture->texture; + depthAttachment.loadAction = mtlGryphnLoadOperation(info.renderPassDescriptor->info.attachmentInfos[i].loadOperation); + depthAttachment.storeAction = mtlGryphnStoreOperation(info.renderPassDescriptor->info.attachmentInfos[i].storeOperation); + depthAttachment.clearDepth = 1.0f; wasDepthStencil = gnTrue; } if (isStencilFormat(info.renderPassDescriptor->info.attachmentInfos[i].format)) { diff --git a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h index b0aad98..06d1db2 100644 --- a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h +++ b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h @@ -5,6 +5,7 @@ typedef struct gnPlatformGraphicsPipeline_t { id graphicsPipeline; + id depthState; metalBindingMaps vertexShaderMaps, fragmentShaderMaps; } gnPlatformGraphicsPipeline; diff --git a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m index e6d8f35..5c56c50 100644 --- a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m +++ b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m @@ -28,6 +28,19 @@ MTLVertexFormat mtlGryphnVertexFormat(gnVertexFormat format) { } } +MTLCompareFunction mtlGrypnCompareOperation(gnCompareOperation operation) { + switch(operation) { + case GN_COMPARE_NEVER: return MTLCompareFunctionNever; + case GN_COMPARE_LESS: return MTLCompareFunctionLess; + case GN_COMPARE_EQUAL: return MTLCompareFunctionEqual; + case GN_COMPARE_LESS_OR_EQUAL: return MTLCompareFunctionLessEqual; + case GN_COMPARE_GREATER: return MTLCompareFunctionGreater; + case GN_COMPARE_NOT_EQUAL: return MTLCompareFunctionNotEqual; + case GN_COMPARE_GREATER_OR_EQUAL: return MTLCompareFunctionGreaterEqual; + case GN_COMPARE_ALWAYS: return MTLCompareFunctionAlways; + } +} + gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info) { graphicsPipeline->graphicsPipeline = malloc(sizeof(struct gnPlatformGraphicsPipeline_t)); MTLRenderPipelineDescriptor* descriptor = [[MTLRenderPipelineDescriptor alloc] init]; @@ -75,10 +88,6 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn MTLVertexAttributeDescriptorArray* attributes = vertexDescriptor.attributes; MTLVertexBufferLayoutDescriptorArray* buffers = vertexDescriptor.layouts; - // layout(location = 0) in vec3 inPosition; - // layout(location = 1) in vec2 inUV; - // layout(location = 2) in vec3 inColor; - int k = 0; for (int i = 0; i < info.shaderInputLayout.bufferCount; i++) { [[buffers objectAtIndexedSubscript:info.shaderInputLayout.bufferAttributes[i].binding] setStride:info.shaderInputLayout.bufferAttributes[i].size]; @@ -90,6 +99,13 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn } } + MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init]; + depthStencilDesc.depthWriteEnabled = info.depthStencil.depthWriteEnable, + depthStencilDesc.depthCompareFunction = info.depthStencil.depthWriteEnable, + depthStencilDesc.depthCompareFunction = mtlGrypnCompareOperation(info.depthStencil.operation), + + graphicsPipeline->graphicsPipeline->depthState = [device->outputDevice->device newDepthStencilStateWithDescriptor:depthStencilDesc]; + [descriptor setVertexDescriptor:vertexDescriptor]; NSError* error = nil; graphicsPipeline->graphicsPipeline->graphicsPipeline = [device->outputDevice->device newRenderPipelineStateWithDescriptor:descriptor error:&error];