From 8211876837d7000419a5deb56102d34795764ed8 Mon Sep 17 00:00:00 2001 From: Greg Wells Date: Sun, 29 Jun 2025 14:40:09 -0400 Subject: [PATCH] get all the commands to work --- .../apis/metal/loader/metal_command_loader.m | 30 +++---- .../apis/metal/loader/metal_device_loader.m | 82 +++++++++++-------- projects/apis/metal/src/buffer/metal_buffer.h | 8 ++ projects/apis/metal/src/buffer/metal_buffer.m | 11 +-- .../command_buffer/metal_command_buffer.h | 5 ++ .../command_buffer/metal_command_buffer.m | 17 ++-- .../command_pool/metal_command_pool.h | 3 + .../command_pool/metal_command_pool.m | 4 +- .../src/commands/commands/metal_commands.h | 19 +++++ .../src/commands/commands/metal_commands.m | 34 ++++---- .../src/framebuffers/metal_framebuffer.h | 3 + .../src/framebuffers/metal_framebuffer.m | 4 +- .../metal_graphics_pipeline.h | 3 + .../metal_graphics_pipeline.m | 22 ++--- .../apis/metal/src/present/metal_present.h | 11 +++ .../apis/metal/src/present/metal_present.m | 12 +-- .../metal_presentation_queue.h | 4 + .../metal_presentation_queue.m | 10 +-- .../metal/src/renderpass/metal_render_pass.h | 3 + .../metal/src/renderpass/metal_render_pass.m | 4 +- .../src/shader_module/metal_shader_module.h | 4 + .../src/shader_module/metal_shader_module.m | 10 ++- projects/apis/metal/src/submit/metal_submit.h | 8 ++ projects/apis/metal/src/submit/metal_submit.m | 10 +-- .../apis/metal/src/surface/metal_surface.h | 4 +- .../apis/metal/src/surface/metal_surface.m | 13 ++- .../apis/metal/src/sync/fence/metal_fence.h | 8 +- .../apis/metal/src/sync/fence/metal_fence.m | 10 +-- .../src/sync/semaphore/metal_semaphore.h | 3 + .../src/sync/semaphore/metal_semaphore.m | 4 +- .../apis/metal/src/texture/metal_texture.h | 4 + .../apis/metal/src/texture/metal_texture.m | 33 ++++++++ .../apis/metal/src/uniforms/metal_uniform.c | 12 --- .../apis/metal/src/uniforms/metal_uniform.h | 3 + .../apis/metal/src/uniforms/metal_uniform.m | 23 ++++++ .../metal/src/uniforms/metal_uniform_pool.h | 5 +- ...al_uniform_pool.c => metal_uniform_pool.m} | 6 +- 37 files changed, 295 insertions(+), 154 deletions(-) create mode 100644 projects/apis/metal/src/commands/commands/metal_commands.h create mode 100644 projects/apis/metal/src/present/metal_present.h create mode 100644 projects/apis/metal/src/submit/metal_submit.h create mode 100644 projects/apis/metal/src/texture/metal_texture.m delete mode 100644 projects/apis/metal/src/uniforms/metal_uniform.c create mode 100644 projects/apis/metal/src/uniforms/metal_uniform.m rename projects/apis/metal/src/uniforms/{metal_uniform_pool.c => metal_uniform_pool.m} (76%) diff --git a/projects/apis/metal/loader/metal_command_loader.m b/projects/apis/metal/loader/metal_command_loader.m index c6548e0..2ab3df4 100644 --- a/projects/apis/metal/loader/metal_command_loader.m +++ b/projects/apis/metal/loader/metal_command_loader.m @@ -1,22 +1,24 @@ #include "metal_loader.h" +#include "commands/command_buffer/metal_command_buffer.h" +#include "commands/commands/metal_commands.h" gnCommandFunctions loadMetalCommandFunctions() { return (gnCommandFunctions){ - ._gnCommandPoolAllocateCommandBuffers = NULL, - ._gnBeginCommandBuffer = NULL, - ._gnResetCommandBuffer = NULL, - ._gnEndCommandBuffer = NULL, + ._gnCommandPoolAllocateCommandBuffers = allocateMetalCommandBuffers, + ._gnBeginCommandBuffer = beginMetalCommandBuffer, + ._gnResetCommandBuffer = resetMetalCommandBuffer, + ._gnEndCommandBuffer = endMetalCommandBuffer, - ._gnCommandBeginRenderPass = NULL, - ._gnCommandEndRenderPass = NULL, - ._gnCommandBindGraphicsPipeline = NULL, - ._gnCommandSetViewport = NULL, - ._gnCommandSetScissor = NULL, - ._gnCommandBindUniform = NULL, - ._gnCommandPushConstant = NULL, + ._gnCommandBeginRenderPass = metelBeginRenderPass, + ._gnCommandEndRenderPass = endMetalRenderPass, + ._gnCommandBindGraphicsPipeline = bindMetalGraphicsPipeline, + ._gnCommandSetViewport = setMetalViewport, + ._gnCommandSetScissor = setMetalScissor, + ._gnCommandBindUniform = metalBindUniform, + ._gnCommandPushConstant = metalBindVertexBytes, - ._gnCommandBindBuffer = NULL, - ._gnCommandDraw = NULL, - ._gnCommandDrawIndexed = NULL, + ._gnCommandBindBuffer = bindMetalBuffer, + ._gnCommandDraw = metalDraw, + ._gnCommandDrawIndexed = metalDrawIndexed, }; } diff --git a/projects/apis/metal/loader/metal_device_loader.m b/projects/apis/metal/loader/metal_device_loader.m index 5ca513d..bea199f 100644 --- a/projects/apis/metal/loader/metal_device_loader.m +++ b/projects/apis/metal/loader/metal_device_loader.m @@ -1,53 +1,67 @@ #include "metal_loader.h" +#include "presentation_queue/metal_presentation_queue.h" +#include "shader_module/metal_shader_module.h" +#include "renderpass/metal_render_pass.h" +#include "framebuffers/metal_framebuffer.h" +#include "uniforms/metal_uniform_pool.h" +#include "pipelines/graphics_pipeline/metal_graphics_pipeline.h" +#include "texture/metal_texture.h" +#include "commands/command_pool/metal_command_pool.h" +#include "buffer/metal_buffer.h" +#include "uniforms/metal_uniform.h" +#include "sync/semaphore/metal_semaphore.h" +#include "sync/fence/metal_fence.h" +#include "submit/metal_submit.h" +#include "present/metal_present.h" gnDeviceFunctions loadMetalDeviceFunctions() { return (gnDeviceFunctions){ - ._gnCreatePresentationQueue = NULL, - ._gnPresentationQueueGetImage = NULL, - ._gnDestroyPresentationQueue = NULL, + ._gnCreatePresentationQueue = createMetalPresentationQueue, + ._gnPresentationQueueGetImage = getMetalPresentQueueImage, + ._gnDestroyPresentationQueue = destroyMetalPresentationQueue, - ._gnCreateShaderModule = NULL, - ._gnDestroyShaderModule = NULL, + ._gnCreateShaderModule = createMetalShaderModule, + ._gnDestroyShaderModule = destroyMetalShaderModule, - ._gnCreateRenderPassDescriptor = NULL, - ._gnDestroyRenderPassDescriptor = NULL, + ._gnCreateRenderPassDescriptor = createMetalRenderPass, + ._gnDestroyRenderPassDescriptor = destroyMetalRenderPass, - ._gnCreateGraphicsPipeline = NULL, - ._gnDestroyGraphicsPipeline = NULL, + ._gnCreateGraphicsPipeline = createMetalGraphicsPipeline, + ._gnDestroyGraphicsPipeline = destroyMetalGraphicsPipeline, - ._gnCreateFramebuffer = NULL, - ._gnDestroyFramebuffer = NULL, + ._gnCreateFramebuffer = createMetalFramebuffer, + ._gnDestroyFramebuffer = destroyMetalFramebuffer, - ._gnCreateCommandPool = NULL, - ._gnDestroyCommandPool = NULL, + ._gnCreateCommandPool = createMetalCommandPool, + ._gnDestroyCommandPool = destroyMetalCommandPool, - ._gnCreateSemaphore = NULL, - ._gnDestroySemaphore = NULL, + ._gnCreateSemaphore = createMetalSemaphore, + ._gnDestroySemaphore = destroyMetalSemaphore, - ._gnCreateBuffer = NULL, - ._gnBufferData = NULL, - ._gnMapBuffer = NULL, - ._gnDestroyBuffer = NULL, + ._gnCreateBuffer = createMetalBuffer, + ._gnBufferData = metalBufferData, + ._gnMapBuffer = mapMetalBuffer, + ._gnDestroyBuffer = destroyMetalBuffer, - ._gnCreateUniformPool = NULL, - ._gnUniformPoolAllocateUniforms = NULL, - ._gnDestroyUniformPool = NULL, + ._gnCreateUniformPool = createMetalUniformPool, + ._gnUniformPoolAllocateUniforms = allocateMetalUniforms, + ._gnDestroyUniformPool = destroyMetalUniformPool, - ._gnUpdateBufferUniform = NULL, - ._gnUpdateImageUniform = NULL, + ._gnUpdateBufferUniform = updateMetalBufferUniform, + ._gnUpdateImageUniform = updateMetalImageUniform, - ._gnCreateTexture = NULL, - ._gnTextureData = NULL, - ._gnDestroyTexture = NULL, + ._gnCreateTexture = createMetalTexture, + ._gnTextureData = metalTextureData, + ._gnDestroyTexture = metalDestroyTexture, - ._gnCreateFence = NULL, - ._gnWaitForFence = NULL, - ._gnResetFence = NULL, - ._gnDestroyFence = NULL, + ._gnCreateFence = createMetalFence, + ._gnWaitForFence = waitForMetalFence, + ._gnResetFence = resetMetalFence, + ._gnDestroyFence = destroyMetalFence, - ._gnSubmit = NULL, - ._gnPresent = NULL, + ._gnSubmit = metalSubmit, + ._gnPresent = metalPresent, - ._gnWaitForDevice = NULL + ._gnWaitForDevice = waitForMetalDevice }; } diff --git a/projects/apis/metal/src/buffer/metal_buffer.h b/projects/apis/metal/src/buffer/metal_buffer.h index a90953b..285d5fc 100644 --- a/projects/apis/metal/src/buffer/metal_buffer.h +++ b/projects/apis/metal/src/buffer/metal_buffer.h @@ -1,7 +1,15 @@ #pragma once #import +#include "buffers/gryphn_buffer.h" +#include "output_device/gryphn_output_device.h" +#include "devices/metal_output_devices.h" struct gnPlatformBuffer_t { id buffer, stagingBuffer; bool useStagingBuffer; }; + +gnReturnCode createMetalBuffer(gnBufferHandle buffer, gnDevice device, gnBufferInfo info); +void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data); +void* mapMetalBuffer(gnBufferHandle buffer); +void destroyMetalBuffer(gnBufferHandle buffer); diff --git a/projects/apis/metal/src/buffer/metal_buffer.m b/projects/apis/metal/src/buffer/metal_buffer.m index e9f7802..2d92140 100644 --- a/projects/apis/metal/src/buffer/metal_buffer.m +++ b/projects/apis/metal/src/buffer/metal_buffer.m @@ -1,9 +1,6 @@ #include "metal_buffer.h" -#include "buffers/gryphn_buffer.h" -#include "output_device/gryphn_output_device.h" -#include "devices/metal_output_devices.h" -gnReturnCode gnCreateBufferFn(gnBufferHandle buffer, gnOutputDeviceHandle device, gnBufferInfo info) { +gnReturnCode createMetalBuffer(gnBufferHandle buffer, gnDevice device, gnBufferInfo info) { buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t)); MTLResourceOptions option; buffer->buffer->useStagingBuffer = (info.usage == GN_DYNAMIC_DRAW) ? NO : YES; @@ -16,7 +13,7 @@ gnReturnCode gnCreateBufferFn(gnBufferHandle buffer, gnOutputDeviceHandle device buffer->buffer->buffer = [device->outputDevice->device newBufferWithLength:info.size options:option]; return GN_SUCCESS; } -void gnBufferDataFn(gnBufferHandle buffer, size_t dataSize, void* data) { +void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data) { void* bufferData; if (buffer->buffer->useStagingBuffer) { memcpy(buffer->buffer->stagingBuffer.contents, data, dataSize); @@ -29,10 +26,10 @@ void gnBufferDataFn(gnBufferHandle buffer, size_t dataSize, void* data) { } else memcpy(buffer->buffer->buffer.contents, data, dataSize); } -void* gnMapBufferFn(gnBufferHandle buffer) { +void* mapMetalBuffer(gnBufferHandle buffer) { return buffer->buffer->buffer.contents; } -void gnDestroyBufferFn(gnBufferHandle buffer) { +void destroyMetalBuffer(gnBufferHandle buffer) { if (buffer->buffer->useStagingBuffer) [buffer->buffer->stagingBuffer release]; [buffer->buffer->buffer release]; diff --git a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h index 30aaaec..187c173 100644 --- a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h +++ b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h @@ -10,3 +10,8 @@ typedef struct gnPlatformCommandBuffer_t { struct gnGraphicsPipeline_t* boundGraphcisPipeline; gnBufferHandle indexBuffer; } gnPlatformCommandBuffer; + +gnReturnCode allocateMetalCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPool pool); +void resetMetalCommandBuffer(gnCommandBuffer commandBuffer); +gnReturnCode beginMetalCommandBuffer(gnCommandBuffer commandBuffer); +gnReturnCode endMetalCommandBuffer(gnCommandBuffer commandBuffer); diff --git a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m index 1a12c73..eaf0d03 100644 --- a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m +++ b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m @@ -2,23 +2,22 @@ #include "commands/command_pool/metal_command_pool.h" #import -gnReturnCode gnCommandPoolAllocateCommandBuffersFn(gnCommandBufferHandle* commandBuffers, uint32_t count, struct gnCommandPool_t* pool) { +gnReturnCode allocateMetalCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPool pool) { for (int i = 0; i < count; i++) { - commandBuffers[i]->commandBuffer = malloc(sizeof(gnPlatformCommandBuffer)); - } + commandBuffers[i]->commandBuffer = malloc(sizeof(gnPlatformCommandBuffer)); } return GN_SUCCESS; } -void gnResetCommandBufferFn(struct gnCommandBuffer_t *commandBuffer) { - // do nothing -} -gnReturnCode gnBeginCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) { - commandBuffer->commandBuffer->boundGraphcisPipeline = NULL; +void resetMetalCommandBuffer(gnCommandBuffer commandBuffer) { commandBuffer->commandBuffer->commandBuffer = [commandBuffer->commandPool->commandPool->commandQueue commandBuffer]; +} +gnReturnCode beginMetalCommandBuffer(gnCommandBuffer commandBuffer) { + commandBuffer->commandBuffer->boundGraphcisPipeline = NULL; + commandBuffer->commandBuffer->encoder = nil; return GN_SUCCESS; } -gnReturnCode gnEndCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) { +gnReturnCode endMetalCommandBuffer(gnCommandBuffer commandBuffer) { // [commandBuffer->commandBuffer->commandBuffer commit]; return GN_SUCCESS; } diff --git a/projects/apis/metal/src/commands/command_pool/metal_command_pool.h b/projects/apis/metal/src/commands/command_pool/metal_command_pool.h index f0f2e40..71fe0da 100644 --- a/projects/apis/metal/src/commands/command_pool/metal_command_pool.h +++ b/projects/apis/metal/src/commands/command_pool/metal_command_pool.h @@ -5,3 +5,6 @@ typedef struct gnPlatformCommandPool_t { id commandQueue; } gnPlatformCommandPool; + +gnReturnCode createMetalCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info); +void destroyMetalCommandPool(gnCommandPool commandPool); diff --git a/projects/apis/metal/src/commands/command_pool/metal_command_pool.m b/projects/apis/metal/src/commands/command_pool/metal_command_pool.m index 75879c2..95c3bd4 100644 --- a/projects/apis/metal/src/commands/command_pool/metal_command_pool.m +++ b/projects/apis/metal/src/commands/command_pool/metal_command_pool.m @@ -1,14 +1,14 @@ #include "metal_command_pool.h" #include "devices/metal_output_devices.h" -gnReturnCode gnCreateCommandPoolFn(struct gnCommandPool_t* commandPool, struct gnOutputDevice_t* device, gnCommandPoolInfo info) { +gnReturnCode createMetalCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info) { commandPool->commandPool = malloc(sizeof(struct gnPlatformCommandPool_t)); commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue]; return GN_SUCCESS; } -void gnDestroyCommandPoolFn(struct gnCommandPool_t* commandPool) { +void destroyMetalCommandPool(gnCommandPool commandPool) { [commandPool->commandPool->commandQueue release]; free(commandPool->commandPool); } diff --git a/projects/apis/metal/src/commands/commands/metal_commands.h b/projects/apis/metal/src/commands/commands/metal_commands.h new file mode 100644 index 0000000..9978e51 --- /dev/null +++ b/projects/apis/metal/src/commands/commands/metal_commands.h @@ -0,0 +1,19 @@ +#include "command/commands/gryphn_command.h" +#include "framebuffers/metal_framebuffer.h" +#include "commands/command_buffer/metal_command_buffer.h" +#include "pipelines/graphics_pipeline/metal_graphics_pipeline.h" +#include "buffer/metal_buffer.h" +#include "uniforms/metal_uniform.h" +#include "texture/metal_texture.h" +#import + +void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo); +void endMetalRenderPass(gnCommandBuffer buffer); +void bindMetalGraphicsPipeline(gnCommandBuffer buffer, struct gnGraphicsPipeline_t* graphicsPipeline); +void setMetalViewport(gnCommandBuffer buffer, gnViewport viewport); +void setMetalScissor(gnCommandBuffer buffer, gnScissor scissor); +void bindMetalBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type); +void metalDraw(gnCommandBuffer buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance); +void metalDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance); +void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set); +void metalBindVertexBytes(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data); diff --git a/projects/apis/metal/src/commands/commands/metal_commands.m b/projects/apis/metal/src/commands/commands/metal_commands.m index c293ffe..ea3bf32 100644 --- a/projects/apis/metal/src/commands/commands/metal_commands.m +++ b/projects/apis/metal/src/commands/commands/metal_commands.m @@ -1,12 +1,6 @@ -#include "command/commands/gryphn_command.h" -#include "framebuffers/metal_framebuffer.h" -#include "commands/command_buffer/metal_command_buffer.h" -#include "pipelines/graphics_pipeline/metal_graphics_pipeline.h" -#include "buffer/metal_buffer.h" -#include "uniforms/metal_uniform.h" -#import +#include "metal_commands.h" -void gnCommandBeginRenderPassFn(struct gnCommandBuffer_t* buffer, gnRenderPassInfo passInfo) { +void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) { int currentColorAttachment = 0; for (int i = 0; i < passInfo.clearValueCount; i++) { gnBool wasDepthStencil = gnFalse; @@ -32,10 +26,10 @@ void gnCommandBeginRenderPassFn(struct gnCommandBuffer_t* buffer, gnRenderPassIn id encoder = (id)buffer->commandBuffer->encoder; [encoder setViewport:vp]; } -void gnCommandEndRenderPassFn(struct gnCommandBuffer_t* buffer) { +void endMetalRenderPass(gnCommandBuffer buffer) { [buffer->commandBuffer->encoder endEncoding]; } -void gnCommandBindGraphicsPipelineFn(struct gnCommandBuffer_t* buffer, struct gnGraphicsPipeline_t* graphicsPipeline) { +void bindMetalGraphicsPipeline(gnCommandBuffer buffer, struct gnGraphicsPipeline_t* graphicsPipeline) { id encoder = (id)buffer->commandBuffer->encoder; [encoder setRenderPipelineState:graphicsPipeline->graphicsPipeline->graphicsPipeline]; @@ -60,24 +54,24 @@ void gnCommandBindGraphicsPipelineFn(struct gnCommandBuffer_t* buffer, struct gn buffer->commandBuffer->boundGraphcisPipeline = graphicsPipeline; } -void gnCommandSetViewportFn(struct gnCommandBuffer_t* buffer, gnViewport viewport) { +void setMetalViewport(gnCommandBuffer buffer, gnViewport viewport) { MTLViewport vp = {(double)viewport.position.x, (double)viewport.position.y, (double)viewport.size.x, (double)viewport.size.y, viewport.minDepth, viewport.maxDepth}; id encoder = (id)buffer->commandBuffer->encoder; [encoder setViewport:vp]; } -void gnCommandSetScissorFn(struct gnCommandBuffer_t* buffer, gnScissor scissor) { +void setMetalScissor(gnCommandBuffer buffer, gnScissor scissor) { MTLScissorRect scissorRect = { scissor.position.x, scissor.position.y, scissor.size.x, scissor.size.y }; id encoder = (id)buffer->commandBuffer->encoder; [encoder setScissorRect:scissorRect]; } -void gnCommandBindBufferFn(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) { +void bindMetalBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) { id encoder = (id)buffer->commandBuffer->encoder; if (type == GN_VERTEX_BUFFER) [encoder setVertexBuffer:bufferToBind->buffer->buffer offset:0 atIndex:0]; else if (type == GN_INDEX_BUFFER) buffer->commandBuffer->indexBuffer = bufferToBind; } -void gnCommandDrawFn(struct gnCommandBuffer_t* buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance) { +void metalDraw(gnCommandBuffer buffer, int vertexCount, int firstVertex, int instanceCount, int firstInstance) { if (buffer->commandBuffer->boundGraphcisPipeline != NULL) { id encoder = (id)buffer->commandBuffer->encoder; if (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType == GN_PRIMITIVE_POINTS) @@ -92,7 +86,7 @@ void gnCommandDrawFn(struct gnCommandBuffer_t* buffer, int vertexCount, int firs [encoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:firstVertex vertexCount:vertexCount instanceCount:instanceCount baseInstance:firstInstance]; } } -void gnCommandDrawIndexedFn(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance) { +void metalDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexCount, int firstIndex, int vertexOffset, int instanceCount, int firstInstance) { id encoder = (id)buffer->commandBuffer->encoder; MTLPrimitiveType primative; switch (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType) { @@ -114,7 +108,7 @@ void gnCommandDrawIndexedFn(gnCommandBufferHandle buffer, gnIndexType type, int ]; } -void gnCommandBindUniformFn(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) { +void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) { id encoder = (id)buffer->commandBuffer->encoder; for (int i = 0; i < uniform->uniform->bindingCount; i++) { if (uniform->uniform->bindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) { @@ -124,6 +118,14 @@ void gnCommandBindUniformFn(gnCommandBufferHandle buffer, gnUniform uniform, uin offset:info.offset atIndex:(info.binding + 1) ]; + } else if (uniform->uniform->bindings[i].type == GN_IMAGE_DESCRIPTOR) { + gnImageUniformInfo info = *(gnImageUniformInfo*)uniform->uniform->bindings[i].data; + [encoder setFragmentTexture:info.texture->texture->texture atIndex:(info.binding + 1)]; } } } + +void metalBindVertexBytes(gnCommandBufferHandle buffer, gnPushConstantLayout layout, void* data) { + id encoder = (id)buffer->commandBuffer->encoder; + [encoder setVertexBytes:data length:layout.size atIndex:0]; // TODO: fix this +} diff --git a/projects/apis/metal/src/framebuffers/metal_framebuffer.h b/projects/apis/metal/src/framebuffers/metal_framebuffer.h index 725b03d..6fbbd7d 100644 --- a/projects/apis/metal/src/framebuffers/metal_framebuffer.h +++ b/projects/apis/metal/src/framebuffers/metal_framebuffer.h @@ -11,3 +11,6 @@ typedef struct gnPlatformFramebuffer_t { gnBool isDepthFormat(gnImageFormat format); gnBool isStencilFormat(gnImageFormat format); + +gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info); +void destroyMetalFramebuffer(gnFramebuffer framebuffer); diff --git a/projects/apis/metal/src/framebuffers/metal_framebuffer.m b/projects/apis/metal/src/framebuffers/metal_framebuffer.m index 2586c80..ee90bf0 100644 --- a/projects/apis/metal/src/framebuffers/metal_framebuffer.m +++ b/projects/apis/metal/src/framebuffers/metal_framebuffer.m @@ -28,7 +28,7 @@ MTLStoreAction mtlGryphnStoreOperation(gnStoreOperation storeOperation) { } } -gnReturnCode gnCreateFramebufferFn(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info) { +gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info) { framebuffer->framebuffer = malloc(sizeof(struct gnPlatformFramebuffer_t)); if (info.attachmentCount != info.renderPassDescriptor->info.attachmentCount) { gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ @@ -74,7 +74,7 @@ gnReturnCode gnCreateFramebufferFn(gnFramebuffer framebuffer, gnOutputDevice dev return GN_SUCCESS; } -void gnDestroyFramebufferFn(struct gnFramebuffer_t* framebuffer) { +void destroyMetalFramebuffer(gnFramebuffer framebuffer) { [framebuffer->framebuffer->framebuffer release]; free(framebuffer->framebuffer); } 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 4593839..4799811 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,3 +5,6 @@ typedef struct gnPlatformGraphicsPipeline_t { id graphicsPipeline; } gnPlatformGraphicsPipeline; + +gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info); +void destroyMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline); 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 97f6d43..edd3dae 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 @@ -4,7 +4,7 @@ #include "shader_module/metal_shader_module.h" #include "surface/metal_surface.h" -MTLBlendFactor vkGryphnBlendFactor(gnBlendFactor factor) { +MTLBlendFactor mtlGryphnBlendFactor(gnBlendFactor factor) { switch (factor) { case GN_BLEND_FACTOR_ZERO: return MTLBlendFactorZero; case GN_BLEND_FACTOR_ONE: return MTLBlendFactorOne; @@ -13,7 +13,7 @@ MTLBlendFactor vkGryphnBlendFactor(gnBlendFactor factor) { } } -MTLBlendOperation vkGryphnBlendOperation(gnBlendOperation operation) { +MTLBlendOperation mtlGryphnBlendOperation(gnBlendOperation operation) { switch(operation) { case GN_OPERATION_ADD: return MTLBlendOperationAdd; } @@ -26,7 +26,7 @@ MTLVertexFormat mtlGryphnVertexFormat(gnVertexFormat format) { } } -gnReturnCode gnCreateGraphicsPipelineFn(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info) { +gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info) { graphicsPipeline->graphicsPipeline = malloc(sizeof(struct gnPlatformGraphicsPipeline_t)); MTLRenderPipelineDescriptor* descriptor = [[MTLRenderPipelineDescriptor alloc] init]; @@ -43,15 +43,15 @@ gnReturnCode gnCreateGraphicsPipelineFn(gnGraphicsPipeline graphicsPipeline, gnO gnSubpassAttachmentInfo subpassAtt = subpass.colorAttachments[i]; gnRenderPassAttachmentInfo attInfo = info.renderPassDescriptor->info.attachmentInfos[subpassAtt.index]; - descriptor.colorAttachments[i].pixelFormat = mtlGryphnFormatToVulkanFormat(attInfo.format); + descriptor.colorAttachments[i].pixelFormat = mtlGryphnFormatToMetalFormat(attInfo.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); + [descriptor.colorAttachments objectAtIndexedSubscript:i].rgbBlendOperation = mtlGryphnBlendOperation(info.colorBlending.colorBlendOperation); + [descriptor.colorAttachments objectAtIndexedSubscript:i].alphaBlendOperation = mtlGryphnBlendOperation(info.colorBlending.alphaBlendOperation); + [descriptor.colorAttachments objectAtIndexedSubscript:i].sourceRGBBlendFactor = mtlGryphnBlendFactor(info.colorBlending.sourceColorBlendFactor); + [descriptor.colorAttachments objectAtIndexedSubscript:i].sourceAlphaBlendFactor = mtlGryphnBlendFactor(info.colorBlending.sourceAlphaBlendFactor); + [descriptor.colorAttachments objectAtIndexedSubscript:i].destinationRGBBlendFactor = mtlGryphnBlendFactor(info.colorBlending.destinationColorBlendFactor); + [descriptor.colorAttachments objectAtIndexedSubscript:i].destinationAlphaBlendFactor = mtlGryphnBlendFactor(info.colorBlending.destinationAlphaBlendFactor); } else { [descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = FALSE; } @@ -97,7 +97,7 @@ gnReturnCode gnCreateGraphicsPipelineFn(gnGraphicsPipeline graphicsPipeline, gnO return GN_SUCCESS; } -void gnDestroyGraphicsPipelineFn(struct gnGraphicsPipeline_t *graphicsPipeline) { +void destroyMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline) { [graphicsPipeline->graphicsPipeline->graphicsPipeline release]; free(graphicsPipeline->graphicsPipeline); } diff --git a/projects/apis/metal/src/present/metal_present.h b/projects/apis/metal/src/present/metal_present.h new file mode 100644 index 0000000..82b9912 --- /dev/null +++ b/projects/apis/metal/src/present/metal_present.h @@ -0,0 +1,11 @@ +#include "present/gryphn_present.h" +#include "instance/metal_instance.h" +#include "surface/metal_surface.h" +#include "devices/metal_output_devices.h" +#include "sync/semaphore/metal_semaphore.h" +#include "presentation_queue/metal_presentation_queue.h" +#include "debugger/gryphn_debugger.h" +#include "texture/metal_texture.h" +#import + +gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info); diff --git a/projects/apis/metal/src/present/metal_present.m b/projects/apis/metal/src/present/metal_present.m index 845ebda..e765999 100644 --- a/projects/apis/metal/src/present/metal_present.m +++ b/projects/apis/metal/src/present/metal_present.m @@ -1,14 +1,6 @@ -#include "present/gryphn_present.h" -#include "instance/metal_instance.h" -#include "surface/metal_surface.h" -#include "devices/metal_output_devices.h" -#include "sync/semaphore/metal_semaphore.h" -#include "presentation_queue/metal_presentation_queue.h" -#include "debugger/gryphn_debugger.h" -#include "texture/metal_texture.h" -#import +#include "metal_present.h" -gnReturnCode gnPresentFn(gnOutputDeviceHandle device, gnPresentInfo info) { +gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { for (int i = 0; i < info.waitCount; i++) { while (!info.waitSemaphores[i]->semaphore->eventTriggered) {} } diff --git a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h index ca1e084..4fe8525 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h @@ -8,3 +8,7 @@ typedef struct gnPlatformPresentationQueue_t { uint32_t currentImage; } gnPlatformPresentationQueue; + +gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo); +gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex); +void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue); diff --git a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m index 14fc7b9..1fb2727 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m @@ -5,7 +5,7 @@ #include "texture/metal_texture.h" #include "sync/semaphore/metal_semaphore.h" -gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueueHandle presentationQueue, const gnOutputDeviceHandle device, gnPresentationQueueInfo presentationInfo) { +gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo) { if (presentationInfo.minImageCount > 3) { gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ .message = gnCreateString("On Metal you cannot have more than 3 images in a presentation queue") @@ -22,8 +22,8 @@ gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueueHandle presentationQ presentationQueue->presentationQueue = malloc(sizeof(struct gnPlatformPresentationQueue_t)); - MTLPixelFormat convertedFormat = mtlGryphnFormatToVulkanFormat(presentationInfo.format.format); - CGColorSpaceRef convertedColorSpace = mtlGryphnColorSpaceToVulkanColorSpace(presentationInfo.format.colorSpace); + MTLPixelFormat convertedFormat = mtlGryphnFormatToMetalFormat(presentationInfo.format.format); + CGColorSpaceRef convertedColorSpace = mtlGryphnColorSpaceToMetalColorSpace(presentationInfo.format.colorSpace); presentationQueue->presentationQueue->textureCount = presentationInfo.minImageCount; presentationQueue->presentationQueue->textures = malloc(sizeof(id) * presentationInfo.minImageCount); @@ -47,7 +47,7 @@ gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueueHandle presentationQ return GN_SUCCESS; } -gnReturnCode gnPresentationQueueGetImageFn(gnPresentationQueueHandle presentationQueue, uint64_t timeout, struct gnSemaphore_t* semaphore, uint32_t* imageIndex) { +gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex) { semaphore->semaphore->eventTriggered = gnFalse; *imageIndex = presentationQueue->presentationQueue->currentImage; presentationQueue->presentationQueue->currentImage++; @@ -56,7 +56,7 @@ gnReturnCode gnPresentationQueueGetImageFn(gnPresentationQueueHandle presentatio return GN_SUCCESS; } -void gnDestroyPresentationQueueFn(gnPresentationQueueHandle presentationQueue) { +void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) { for (int i = 0; i < presentationQueue->imageCount; i++) { [presentationQueue->presentationQueue->textures[i] release]; } diff --git a/projects/apis/metal/src/renderpass/metal_render_pass.h b/projects/apis/metal/src/renderpass/metal_render_pass.h index 82619d4..70be445 100644 --- a/projects/apis/metal/src/renderpass/metal_render_pass.h +++ b/projects/apis/metal/src/renderpass/metal_render_pass.h @@ -5,3 +5,6 @@ typedef struct gnPlatformRenderPassDescriptor_t { MTLRenderPassDescriptor* passDescriptor; } gnPlatformRenderPassDescriptor; + +gnReturnCode createMetalRenderPass(gnRenderPassDescriptor renderPass, gnDevice device, gnRenderPassDescriptorInfo info); +void destroyMetalRenderPass(gnRenderPassDescriptor renderPass); diff --git a/projects/apis/metal/src/renderpass/metal_render_pass.m b/projects/apis/metal/src/renderpass/metal_render_pass.m index dc5e265..99c0d34 100644 --- a/projects/apis/metal/src/renderpass/metal_render_pass.m +++ b/projects/apis/metal/src/renderpass/metal_render_pass.m @@ -1,13 +1,13 @@ #include "metal_render_pass.h" -gnReturnCode gnCreateRenderPassDescriptorFn(gnRenderPassDescriptor renderPass, gnOutputDevice device, gnRenderPassDescriptorInfo info) { +gnReturnCode createMetalRenderPass(gnRenderPassDescriptor renderPass, gnDevice device, gnRenderPassDescriptorInfo info) { renderPass->renderPassDescriptor = malloc(sizeof(gnPlatformRenderPassDescriptor)); renderPass->renderPassDescriptor->passDescriptor = [[MTLRenderPassDescriptor alloc] init]; return GN_SUCCESS; } -void gnDestroyRenderPassDescriptorFn(struct gnRenderPassDescriptor_t* renderPass) { +void destroyMetalRenderPass(gnRenderPassDescriptor renderPass) { [renderPass->renderPassDescriptor->passDescriptor release]; free(renderPass->renderPassDescriptor); } diff --git a/projects/apis/metal/src/shader_module/metal_shader_module.h b/projects/apis/metal/src/shader_module/metal_shader_module.h index 127781f..98d265d 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.h +++ b/projects/apis/metal/src/shader_module/metal_shader_module.h @@ -4,4 +4,8 @@ typedef struct gnPlatformShaderModule_t { id function; + uint32_t pushConstantIndex; } gnPlatformShaderModule; + +gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo); +void destroyMetalShaderModule(gnShaderModule module); diff --git a/projects/apis/metal/src/shader_module/metal_shader_module.m b/projects/apis/metal/src/shader_module/metal_shader_module.m index b6329c8..4ce2ca3 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.m +++ b/projects/apis/metal/src/shader_module/metal_shader_module.m @@ -6,13 +6,13 @@ #import void mtlSpirVErrorCallback(void *userdata, const char *error) { - struct gnDebugger_t* debugger = (struct gnDebugger_t*)userdata; + gnDebugger debugger = (gnDebugger)userdata; gnDebuggerSetErrorMessage(debugger, (gnMessageData){ .message = gnCreateString(error) }); } -gnReturnCode gnCreateShaderModuleFn(gnShaderModule module, gnOutputDevice device, gnShaderModuleInfo shaderModuleInfo) { +gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo) { module->shaderModule = malloc(sizeof(struct gnPlatformShaderModule_t)); spvc_context context = NULL; @@ -42,6 +42,10 @@ gnReturnCode gnCreateShaderModuleFn(gnShaderModule module, gnOutputDevice device spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, binding); } + spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &list, &count); + for (int i = 0; i < count; i++) { + // TODO: get the buffer index + } spvc_compiler_create_compiler_options(compiler, &options); spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_VERSION, 200); @@ -96,6 +100,6 @@ gnReturnCode gnCreateShaderModuleFn(gnShaderModule module, gnOutputDevice device return GN_SUCCESS; } -void gnDestroyShaderModuleFn(struct gnShaderModule_t* module) { +void destroyMetalShaderModule(gnShaderModule module) { free(module->shaderModule); } diff --git a/projects/apis/metal/src/submit/metal_submit.h b/projects/apis/metal/src/submit/metal_submit.h new file mode 100644 index 0000000..ac9e4fe --- /dev/null +++ b/projects/apis/metal/src/submit/metal_submit.h @@ -0,0 +1,8 @@ +#include "submit/gryphn_submit.h" +#include "sync/semaphore/metal_semaphore.h" +#include "commands/command_buffer/metal_command_buffer.h" +#include "debugger/gryphn_debugger.h" +#include "commands/command_pool/metal_command_pool.h" +#include "sync/fence/gryphn_fence.h" + +gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info); diff --git a/projects/apis/metal/src/submit/metal_submit.m b/projects/apis/metal/src/submit/metal_submit.m index 926558e..d5e7a04 100644 --- a/projects/apis/metal/src/submit/metal_submit.m +++ b/projects/apis/metal/src/submit/metal_submit.m @@ -1,16 +1,10 @@ -#include "submit/gryphn_submit.h" -#include "sync/semaphore/metal_semaphore.h" -#include "commands/command_buffer/metal_command_buffer.h" -#include "debugger/gryphn_debugger.h" -#include "commands/command_pool/metal_command_pool.h" -#include "sync/fence/gryphn_fence.h" +#include "metal_submit.h" -gnReturnCode gnSubmitFn(gnDevice* device, gnSubmitInfo info) { +gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) { for (int i = 0; i < info.waitCount; i++) { while (!info.waitSemaphores[i]->semaphore->eventTriggered) {} } - __block gnSemaphore* semsToSignal = info.signalSemaphores; __block int semsToSignalCount = info.signalCount; __block gnFence fenceToSignal = info.fence; diff --git a/projects/apis/metal/src/surface/metal_surface.h b/projects/apis/metal/src/surface/metal_surface.h index 1157113..8124627 100644 --- a/projects/apis/metal/src/surface/metal_surface.h +++ b/projects/apis/metal/src/surface/metal_surface.h @@ -7,8 +7,8 @@ typedef struct gnPlatformWindowSurface_t { } gnPlatformWindowSurface; -MTLPixelFormat mtlGryphnFormatToVulkanFormat(gnImageFormat format); -CGColorSpaceRef mtlGryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace); +MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format); +CGColorSpaceRef mtlGryphnColorSpaceToMetalColorSpace(gnColorSpace colorSpace); gnReturnCode createMetalSurface(gnWindowSurface windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo); gnSurfaceDetails getMetalSurfaceDetails(gnWindowSurface windowSurface, gnPhysicalDevice device); diff --git a/projects/apis/metal/src/surface/metal_surface.m b/projects/apis/metal/src/surface/metal_surface.m index 4238334..b286e46 100644 --- a/projects/apis/metal/src/surface/metal_surface.m +++ b/projects/apis/metal/src/surface/metal_surface.m @@ -26,17 +26,22 @@ gnSurfaceDetails getMetalSurfaceDetails( surfaceDetails.formats = (gnSurfaceFormat[]){ { GN_FORMAT_BGRA8_SRGB, GN_COLOR_SPACE_SRGB_NONLINEAR } }; surfaceDetails.minImageCount = 2; surfaceDetails.maxImageCount = 3; + CGSize size = windowSurface->windowSurface->layer.visibleRect.size; + surfaceDetails.minImageSize = surfaceDetails.maxImageSize = surfaceDetails.currentSize = (gnUInt2){size.width, size.height}; return surfaceDetails; } -MTLPixelFormat mtlGryphnFormatToVulkanFormat(gnImageFormat format) { +MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format) { switch (format) { - case GN_FORMAT_BGRA8_SRGB: { return MTLPixelFormatBGRA8Unorm_sRGB; } - default: return MTLPixelFormatInvalid; + case GN_FORMAT_NONE: return MTLPixelFormatInvalid; + case GN_FORMAT_BGRA8_SRGB: return MTLPixelFormatBGRA8Unorm_sRGB; + case GN_FORMAT_RGBA8_SRGB: return MTLPixelFormatRG8Unorm_sRGB; + case GN_FORMAT_D24S8_UINT: return MTLPixelFormatDepth24Unorm_Stencil8; + case GN_FORMAT_D32S8_UINT: return MTLPixelFormatDepth32Float_Stencil8; } } -CGColorSpaceRef mtlGryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace) { +CGColorSpaceRef mtlGryphnColorSpaceToMetalColorSpace(gnColorSpace colorSpace) { switch (colorSpace) { case GN_COLOR_SPACE_SRGB_NONLINEAR: { return CGColorSpaceCreateWithName(kCGColorSpaceSRGB); } } diff --git a/projects/apis/metal/src/sync/fence/metal_fence.h b/projects/apis/metal/src/sync/fence/metal_fence.h index e695a28..13c5a27 100644 --- a/projects/apis/metal/src/sync/fence/metal_fence.h +++ b/projects/apis/metal/src/sync/fence/metal_fence.h @@ -3,6 +3,10 @@ #import #import -typedef struct gnPlatformFence_t { +typedef struct gnPlatformFence_t {} gnPlatformFence; -} gnPlatformFence; +gnReturnCode createMetalFence(gnFence fence, gnDevice device); +void singalMetalFence(gnFence fence); +void waitForMetalFence(gnFence fence, uint64_t timeout); +void resetMetalFence(gnFence fence); +void destroyMetalFence(gnFence fence); diff --git a/projects/apis/metal/src/sync/fence/metal_fence.m b/projects/apis/metal/src/sync/fence/metal_fence.m index 1c7a0ba..1ed16d4 100644 --- a/projects/apis/metal/src/sync/fence/metal_fence.m +++ b/projects/apis/metal/src/sync/fence/metal_fence.m @@ -1,7 +1,7 @@ #include "metal_fence.h" #include "devices/metal_output_devices.h" -gnReturnCode gnCreateFenceFn(struct gnFence_t* fence, struct gnOutputDevice_t* device) { +gnReturnCode createMetalFence(gnFence fence, struct gnOutputDevice_t* device) { // fence->fence = malloc(sizeof(gnPlatformFence)); // fence->fence->fence = [device->outputDevice->device newSharedEvent]; @@ -10,14 +10,14 @@ gnReturnCode gnCreateFenceFn(struct gnFence_t* fence, struct gnOutputDevice_t* d return GN_SUCCESS; } -void gnSignalFenceFn(struct gnFence_t* fence) { +void singalMetalFence(gnFence fence) { // dispatch_semaphore_signal(fence->fence->semaphore); } -void gnWaitForFenceFn(struct gnFence_t* fence, uint64_t timeout) { +void waitForMetalFence(gnFence fence, uint64_t timeout) { // dispatch_semaphore_wait(fence->fence->semaphore, timeout); while (fence->signaled == gnFalse) {} } -void gnResetFenceFn(struct gnFence_t* fence) { +void resetMetalFence(gnFence fence) { // dispatch_semaphore_signal(fence->fence->semaphore); // [fence->fence->fence setSignaledValue:0]; // [fence->fence->fence notifyListener:fence->fence->listener @@ -26,7 +26,7 @@ void gnResetFenceFn(struct gnFence_t* fence) { // dispatch_semaphore_signal(fence->fence->semaphore); // }]; } -void gnDestroyFenceFn(struct gnFence_t* fence) { +void destroyMetalFence(gnFence fence) { // [fence->fence->fence release]; // [fence->fence->listener release]; // free(fence->fence); diff --git a/projects/apis/metal/src/sync/semaphore/metal_semaphore.h b/projects/apis/metal/src/sync/semaphore/metal_semaphore.h index 7f7dc59..b5ffaf0 100644 --- a/projects/apis/metal/src/sync/semaphore/metal_semaphore.h +++ b/projects/apis/metal/src/sync/semaphore/metal_semaphore.h @@ -6,3 +6,6 @@ typedef struct gnPlatformSemaphore_t { id event; bool eventTriggered; } gnPlatformSemaphore; + +gnReturnCode createMetalSemaphore(gnSemaphore semaphore, gnOutputDevice device); +void destroyMetalSemaphore(gnSemaphore semaphore); diff --git a/projects/apis/metal/src/sync/semaphore/metal_semaphore.m b/projects/apis/metal/src/sync/semaphore/metal_semaphore.m index a032827..bfa815e 100644 --- a/projects/apis/metal/src/sync/semaphore/metal_semaphore.m +++ b/projects/apis/metal/src/sync/semaphore/metal_semaphore.m @@ -1,13 +1,13 @@ #include "metal_semaphore.h" #include "devices/metal_output_devices.h" -gnReturnCode gnCreateSemaphoreFn(gnSemaphore semaphore, gnOutputDevice device) { +gnReturnCode createMetalSemaphore(gnSemaphore semaphore, gnOutputDevice device) { semaphore->semaphore = malloc(sizeof(gnPlatformSemaphore)); semaphore->semaphore->event = [device->outputDevice->device newEvent]; return GN_SUCCESS; } -void gnDestroySemaphoreFn(gnSemaphore semaphore) { +void destroyMetalSemaphore(gnSemaphore semaphore) { [semaphore->semaphore->event release]; free(semaphore->semaphore); } diff --git a/projects/apis/metal/src/texture/metal_texture.h b/projects/apis/metal/src/texture/metal_texture.h index d4b392f..4b202a1 100644 --- a/projects/apis/metal/src/texture/metal_texture.h +++ b/projects/apis/metal/src/texture/metal_texture.h @@ -5,3 +5,7 @@ typedef struct gnPlatformTexture_t { id texture; } gnPlatformTexture; + +gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnTextureInfo info); +void metalTextureData(gnTextureHandle texture, void* pixelData); +void metalDestroyTexture(gnTexture texture); diff --git a/projects/apis/metal/src/texture/metal_texture.m b/projects/apis/metal/src/texture/metal_texture.m new file mode 100644 index 0000000..553079a --- /dev/null +++ b/projects/apis/metal/src/texture/metal_texture.m @@ -0,0 +1,33 @@ +#include "metal_texture.h" +#include "surface/metal_surface.h" +#include "devices/metal_output_devices.h" + +gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnTextureInfo info) { + texture->texture = malloc(sizeof(struct gnPlatformTexture_t)); + MTLTextureDescriptor *textureDescriptor = [[MTLTextureDescriptor alloc] init]; + textureDescriptor.pixelFormat = mtlGryphnFormatToMetalFormat(info.format); + textureDescriptor.width = info.width; + textureDescriptor.height = info.height; + texture->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor]; + [textureDescriptor release]; + return GN_SUCCESS; +} + +void metalTextureData(gnTextureHandle texture, void* pixelData) { + MTLRegion region = { + { 0, 0, 0 }, + {texture->info.width, texture->info.height, 1} + }; + + NSUInteger bytesPerRow = 4 * texture->info.width; // TODO: fix this should not be set to 4 + [texture->texture->texture replaceRegion:region + mipmapLevel:0 + withBytes:pixelData + bytesPerRow:bytesPerRow]; + +} + +void metalDestroyTexture(gnTexture texture) { + [texture->texture->texture release]; + free(texture->texture); +} diff --git a/projects/apis/metal/src/uniforms/metal_uniform.c b/projects/apis/metal/src/uniforms/metal_uniform.c deleted file mode 100644 index 8609dd3..0000000 --- a/projects/apis/metal/src/uniforms/metal_uniform.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include "metal_uniform.h" - -void gnUpdateBufferUniformFn(gnUniform uniform, gnBufferUniformInfo* info) { - for (int i = 0; i < uniform->uniform->bindingCount; i++) { - if (uniform->uniform->bindings[i].binding == info->binding) { - uniform->uniform->bindings[i].data = malloc(sizeof(gnBufferUniformInfo)); - memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnBufferUniformInfo)); - break; - } - } -} diff --git a/projects/apis/metal/src/uniforms/metal_uniform.h b/projects/apis/metal/src/uniforms/metal_uniform.h index fd44d4a..7288025 100644 --- a/projects/apis/metal/src/uniforms/metal_uniform.h +++ b/projects/apis/metal/src/uniforms/metal_uniform.h @@ -12,3 +12,6 @@ typedef struct gnPlatformUniform_t { uint32_t bindingCount; metalUniformBinding* bindings; } gnPlatformUniform; + +void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info); +void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info); diff --git a/projects/apis/metal/src/uniforms/metal_uniform.m b/projects/apis/metal/src/uniforms/metal_uniform.m new file mode 100644 index 0000000..8a28e83 --- /dev/null +++ b/projects/apis/metal/src/uniforms/metal_uniform.m @@ -0,0 +1,23 @@ +#include +#include "metal_uniform.h" + +void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) { + for (int i = 0; i < uniform->uniform->bindingCount; i++) { + if (uniform->uniform->bindings[i].binding == info->binding) { + uniform->uniform->bindings[i].data = malloc(sizeof(gnBufferUniformInfo)); + memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnBufferUniformInfo)); + break; + } + } +} + + +void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) { + for (int i = 0; i < uniform->uniform->bindingCount; i++) { + if (uniform->uniform->bindings[i].binding == info->binding) { + uniform->uniform->bindings[i].data = malloc(sizeof(gnImageUniformInfo)); + memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnImageUniformInfo)); + break; + } + } +} diff --git a/projects/apis/metal/src/uniforms/metal_uniform_pool.h b/projects/apis/metal/src/uniforms/metal_uniform_pool.h index a514b90..16340f6 100644 --- a/projects/apis/metal/src/uniforms/metal_uniform_pool.h +++ b/projects/apis/metal/src/uniforms/metal_uniform_pool.h @@ -1,5 +1,8 @@ #pragma once -#include #include typedef struct gnPlatformUniformPool_t {} gnPlatformUniformPool; + +gnReturnCode createMetalUniformPool(gnUniformPool pool, gnDeviceHandle device); +gnUniform* allocateMetalUniforms(gnUniformPool pool, const gnUniformAllocationInfo allocInfo); +void destroyMetalUniformPool(gnUniformPool pool); diff --git a/projects/apis/metal/src/uniforms/metal_uniform_pool.c b/projects/apis/metal/src/uniforms/metal_uniform_pool.m similarity index 76% rename from projects/apis/metal/src/uniforms/metal_uniform_pool.c rename to projects/apis/metal/src/uniforms/metal_uniform_pool.m index db93ad8..a49e8e0 100644 --- a/projects/apis/metal/src/uniforms/metal_uniform_pool.c +++ b/projects/apis/metal/src/uniforms/metal_uniform_pool.m @@ -2,11 +2,11 @@ #include #include "metal_uniform.h" -gnReturnCode gnCreateUniformPoolFn(gnUniformPool pool, gnDeviceHandle device) { +gnReturnCode createMetalUniformPool(gnUniformPool pool, gnDeviceHandle device) { return GN_SUCCESS; } -gnUniform* gnUniformPoolAllocateUniformsFn(gnUniformPool pool, const gnUniformAllocationInfo allocInfo) { +gnUniform* allocateMetalUniforms(gnUniformPool pool, const gnUniformAllocationInfo allocInfo) { gnUniform* uniforms = malloc(sizeof(gnUniform) * allocInfo.setCount); for (int i = 0; i < allocInfo.setCount; i++) { uniforms[i] = malloc(sizeof(struct gnUniform_t)); @@ -20,4 +20,4 @@ gnUniform* gnUniformPoolAllocateUniformsFn(gnUniformPool pool, const gnUniformAl return uniforms; } -void gnDestroyUniformPoolFn(gnUniformPool pool) { } +void destroyMetalUniformPool(gnUniformPool pool) { free(pool->uniformPool); }