get all the commands to work

This commit is contained in:
Greg Wells
2025-06-29 14:40:09 -04:00
parent 67e5e6e36a
commit 8211876837
37 changed files with 295 additions and 154 deletions

View File

@@ -1,22 +1,24 @@
#include "metal_loader.h" #include "metal_loader.h"
#include "commands/command_buffer/metal_command_buffer.h"
#include "commands/commands/metal_commands.h"
gnCommandFunctions loadMetalCommandFunctions() { gnCommandFunctions loadMetalCommandFunctions() {
return (gnCommandFunctions){ return (gnCommandFunctions){
._gnCommandPoolAllocateCommandBuffers = NULL, ._gnCommandPoolAllocateCommandBuffers = allocateMetalCommandBuffers,
._gnBeginCommandBuffer = NULL, ._gnBeginCommandBuffer = beginMetalCommandBuffer,
._gnResetCommandBuffer = NULL, ._gnResetCommandBuffer = resetMetalCommandBuffer,
._gnEndCommandBuffer = NULL, ._gnEndCommandBuffer = endMetalCommandBuffer,
._gnCommandBeginRenderPass = NULL, ._gnCommandBeginRenderPass = metelBeginRenderPass,
._gnCommandEndRenderPass = NULL, ._gnCommandEndRenderPass = endMetalRenderPass,
._gnCommandBindGraphicsPipeline = NULL, ._gnCommandBindGraphicsPipeline = bindMetalGraphicsPipeline,
._gnCommandSetViewport = NULL, ._gnCommandSetViewport = setMetalViewport,
._gnCommandSetScissor = NULL, ._gnCommandSetScissor = setMetalScissor,
._gnCommandBindUniform = NULL, ._gnCommandBindUniform = metalBindUniform,
._gnCommandPushConstant = NULL, ._gnCommandPushConstant = metalBindVertexBytes,
._gnCommandBindBuffer = NULL, ._gnCommandBindBuffer = bindMetalBuffer,
._gnCommandDraw = NULL, ._gnCommandDraw = metalDraw,
._gnCommandDrawIndexed = NULL, ._gnCommandDrawIndexed = metalDrawIndexed,
}; };
} }

View File

@@ -1,53 +1,67 @@
#include "metal_loader.h" #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() { gnDeviceFunctions loadMetalDeviceFunctions() {
return (gnDeviceFunctions){ return (gnDeviceFunctions){
._gnCreatePresentationQueue = NULL, ._gnCreatePresentationQueue = createMetalPresentationQueue,
._gnPresentationQueueGetImage = NULL, ._gnPresentationQueueGetImage = getMetalPresentQueueImage,
._gnDestroyPresentationQueue = NULL, ._gnDestroyPresentationQueue = destroyMetalPresentationQueue,
._gnCreateShaderModule = NULL, ._gnCreateShaderModule = createMetalShaderModule,
._gnDestroyShaderModule = NULL, ._gnDestroyShaderModule = destroyMetalShaderModule,
._gnCreateRenderPassDescriptor = NULL, ._gnCreateRenderPassDescriptor = createMetalRenderPass,
._gnDestroyRenderPassDescriptor = NULL, ._gnDestroyRenderPassDescriptor = destroyMetalRenderPass,
._gnCreateGraphicsPipeline = NULL, ._gnCreateGraphicsPipeline = createMetalGraphicsPipeline,
._gnDestroyGraphicsPipeline = NULL, ._gnDestroyGraphicsPipeline = destroyMetalGraphicsPipeline,
._gnCreateFramebuffer = NULL, ._gnCreateFramebuffer = createMetalFramebuffer,
._gnDestroyFramebuffer = NULL, ._gnDestroyFramebuffer = destroyMetalFramebuffer,
._gnCreateCommandPool = NULL, ._gnCreateCommandPool = createMetalCommandPool,
._gnDestroyCommandPool = NULL, ._gnDestroyCommandPool = destroyMetalCommandPool,
._gnCreateSemaphore = NULL, ._gnCreateSemaphore = createMetalSemaphore,
._gnDestroySemaphore = NULL, ._gnDestroySemaphore = destroyMetalSemaphore,
._gnCreateBuffer = NULL, ._gnCreateBuffer = createMetalBuffer,
._gnBufferData = NULL, ._gnBufferData = metalBufferData,
._gnMapBuffer = NULL, ._gnMapBuffer = mapMetalBuffer,
._gnDestroyBuffer = NULL, ._gnDestroyBuffer = destroyMetalBuffer,
._gnCreateUniformPool = NULL, ._gnCreateUniformPool = createMetalUniformPool,
._gnUniformPoolAllocateUniforms = NULL, ._gnUniformPoolAllocateUniforms = allocateMetalUniforms,
._gnDestroyUniformPool = NULL, ._gnDestroyUniformPool = destroyMetalUniformPool,
._gnUpdateBufferUniform = NULL, ._gnUpdateBufferUniform = updateMetalBufferUniform,
._gnUpdateImageUniform = NULL, ._gnUpdateImageUniform = updateMetalImageUniform,
._gnCreateTexture = NULL, ._gnCreateTexture = createMetalTexture,
._gnTextureData = NULL, ._gnTextureData = metalTextureData,
._gnDestroyTexture = NULL, ._gnDestroyTexture = metalDestroyTexture,
._gnCreateFence = NULL, ._gnCreateFence = createMetalFence,
._gnWaitForFence = NULL, ._gnWaitForFence = waitForMetalFence,
._gnResetFence = NULL, ._gnResetFence = resetMetalFence,
._gnDestroyFence = NULL, ._gnDestroyFence = destroyMetalFence,
._gnSubmit = NULL, ._gnSubmit = metalSubmit,
._gnPresent = NULL, ._gnPresent = metalPresent,
._gnWaitForDevice = NULL ._gnWaitForDevice = waitForMetalDevice
}; };
} }

View File

@@ -1,7 +1,15 @@
#pragma once #pragma once
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include "buffers/gryphn_buffer.h"
#include "output_device/gryphn_output_device.h"
#include "devices/metal_output_devices.h"
struct gnPlatformBuffer_t { struct gnPlatformBuffer_t {
id<MTLBuffer> buffer, stagingBuffer; id<MTLBuffer> buffer, stagingBuffer;
bool useStagingBuffer; 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);

View File

@@ -1,9 +1,6 @@
#include "metal_buffer.h" #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)); buffer->buffer = malloc(sizeof(struct gnPlatformBuffer_t));
MTLResourceOptions option; MTLResourceOptions option;
buffer->buffer->useStagingBuffer = (info.usage == GN_DYNAMIC_DRAW) ? NO : YES; 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]; buffer->buffer->buffer = [device->outputDevice->device newBufferWithLength:info.size options:option];
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnBufferDataFn(gnBufferHandle buffer, size_t dataSize, void* data) { void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data) {
void* bufferData; void* bufferData;
if (buffer->buffer->useStagingBuffer) { if (buffer->buffer->useStagingBuffer) {
memcpy(buffer->buffer->stagingBuffer.contents, data, dataSize); memcpy(buffer->buffer->stagingBuffer.contents, data, dataSize);
@@ -29,10 +26,10 @@ void gnBufferDataFn(gnBufferHandle buffer, size_t dataSize, void* data) {
} else } else
memcpy(buffer->buffer->buffer.contents, data, dataSize); memcpy(buffer->buffer->buffer.contents, data, dataSize);
} }
void* gnMapBufferFn(gnBufferHandle buffer) { void* mapMetalBuffer(gnBufferHandle buffer) {
return buffer->buffer->buffer.contents; return buffer->buffer->buffer.contents;
} }
void gnDestroyBufferFn(gnBufferHandle buffer) { void destroyMetalBuffer(gnBufferHandle buffer) {
if (buffer->buffer->useStagingBuffer) if (buffer->buffer->useStagingBuffer)
[buffer->buffer->stagingBuffer release]; [buffer->buffer->stagingBuffer release];
[buffer->buffer->buffer release]; [buffer->buffer->buffer release];

View File

@@ -10,3 +10,8 @@ typedef struct gnPlatformCommandBuffer_t {
struct gnGraphicsPipeline_t* boundGraphcisPipeline; struct gnGraphicsPipeline_t* boundGraphcisPipeline;
gnBufferHandle indexBuffer; gnBufferHandle indexBuffer;
} gnPlatformCommandBuffer; } gnPlatformCommandBuffer;
gnReturnCode allocateMetalCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPool pool);
void resetMetalCommandBuffer(gnCommandBuffer commandBuffer);
gnReturnCode beginMetalCommandBuffer(gnCommandBuffer commandBuffer);
gnReturnCode endMetalCommandBuffer(gnCommandBuffer commandBuffer);

View File

@@ -2,23 +2,22 @@
#include "commands/command_pool/metal_command_pool.h" #include "commands/command_pool/metal_command_pool.h"
#import <Metal/Metal.h> #import <Metal/Metal.h>
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++) { for (int i = 0; i < count; i++) {
commandBuffers[i]->commandBuffer = malloc(sizeof(gnPlatformCommandBuffer)); commandBuffers[i]->commandBuffer = malloc(sizeof(gnPlatformCommandBuffer)); }
}
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnResetCommandBufferFn(struct gnCommandBuffer_t *commandBuffer) { void resetMetalCommandBuffer(gnCommandBuffer commandBuffer) {
// do nothing
}
gnReturnCode gnBeginCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) {
commandBuffer->commandBuffer->boundGraphcisPipeline = NULL;
commandBuffer->commandBuffer->commandBuffer = [commandBuffer->commandPool->commandPool->commandQueue commandBuffer]; commandBuffer->commandBuffer->commandBuffer = [commandBuffer->commandPool->commandPool->commandQueue commandBuffer];
}
gnReturnCode beginMetalCommandBuffer(gnCommandBuffer commandBuffer) {
commandBuffer->commandBuffer->boundGraphcisPipeline = NULL;
commandBuffer->commandBuffer->encoder = nil;
return GN_SUCCESS; return GN_SUCCESS;
} }
gnReturnCode gnEndCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) { gnReturnCode endMetalCommandBuffer(gnCommandBuffer commandBuffer) {
// [commandBuffer->commandBuffer->commandBuffer commit]; // [commandBuffer->commandBuffer->commandBuffer commit];
return GN_SUCCESS; return GN_SUCCESS;
} }

View File

@@ -5,3 +5,6 @@
typedef struct gnPlatformCommandPool_t { typedef struct gnPlatformCommandPool_t {
id<MTLCommandQueue> commandQueue; id<MTLCommandQueue> commandQueue;
} gnPlatformCommandPool; } gnPlatformCommandPool;
gnReturnCode createMetalCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info);
void destroyMetalCommandPool(gnCommandPool commandPool);

View File

@@ -1,14 +1,14 @@
#include "metal_command_pool.h" #include "metal_command_pool.h"
#include "devices/metal_output_devices.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 = malloc(sizeof(struct gnPlatformCommandPool_t));
commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue]; commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue];
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnDestroyCommandPoolFn(struct gnCommandPool_t* commandPool) { void destroyMetalCommandPool(gnCommandPool commandPool) {
[commandPool->commandPool->commandQueue release]; [commandPool->commandPool->commandQueue release];
free(commandPool->commandPool); free(commandPool->commandPool);
} }

View File

@@ -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 <Metal/MTLRenderCommandEncoder.h>
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);

View File

@@ -1,12 +1,6 @@
#include "command/commands/gryphn_command.h" #include "metal_commands.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 <Metal/MTLRenderCommandEncoder.h>
void gnCommandBeginRenderPassFn(struct gnCommandBuffer_t* buffer, gnRenderPassInfo passInfo) { void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) {
int currentColorAttachment = 0; int currentColorAttachment = 0;
for (int i = 0; i < passInfo.clearValueCount; i++) { for (int i = 0; i < passInfo.clearValueCount; i++) {
gnBool wasDepthStencil = gnFalse; gnBool wasDepthStencil = gnFalse;
@@ -32,10 +26,10 @@ void gnCommandBeginRenderPassFn(struct gnCommandBuffer_t* buffer, gnRenderPassIn
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
[encoder setViewport:vp]; [encoder setViewport:vp];
} }
void gnCommandEndRenderPassFn(struct gnCommandBuffer_t* buffer) { void endMetalRenderPass(gnCommandBuffer buffer) {
[buffer->commandBuffer->encoder endEncoding]; [buffer->commandBuffer->encoder endEncoding];
} }
void gnCommandBindGraphicsPipelineFn(struct gnCommandBuffer_t* buffer, struct gnGraphicsPipeline_t* graphicsPipeline) { void bindMetalGraphicsPipeline(gnCommandBuffer buffer, struct gnGraphicsPipeline_t* graphicsPipeline) {
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
[encoder setRenderPipelineState:graphicsPipeline->graphicsPipeline->graphicsPipeline]; [encoder setRenderPipelineState:graphicsPipeline->graphicsPipeline->graphicsPipeline];
@@ -60,24 +54,24 @@ void gnCommandBindGraphicsPipelineFn(struct gnCommandBuffer_t* buffer, struct gn
buffer->commandBuffer->boundGraphcisPipeline = graphicsPipeline; 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}; MTLViewport vp = {(double)viewport.position.x, (double)viewport.position.y, (double)viewport.size.x, (double)viewport.size.y, viewport.minDepth, viewport.maxDepth};
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
[encoder setViewport:vp]; [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 }; MTLScissorRect scissorRect = { scissor.position.x, scissor.position.y, scissor.size.x, scissor.size.y };
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
[encoder setScissorRect:scissorRect]; [encoder setScissorRect:scissorRect];
} }
void gnCommandBindBufferFn(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) { void bindMetalBuffer(gnCommandBufferHandle buffer, gnBufferHandle bufferToBind, gnBufferType type) {
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
if (type == GN_VERTEX_BUFFER) if (type == GN_VERTEX_BUFFER)
[encoder setVertexBuffer:bufferToBind->buffer->buffer offset:0 atIndex:0]; [encoder setVertexBuffer:bufferToBind->buffer->buffer offset:0 atIndex:0];
else if (type == GN_INDEX_BUFFER) else if (type == GN_INDEX_BUFFER)
buffer->commandBuffer->indexBuffer = bufferToBind; 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) { if (buffer->commandBuffer->boundGraphcisPipeline != NULL) {
id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
if (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType == GN_PRIMITIVE_POINTS) 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]; [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<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
MTLPrimitiveType primative; MTLPrimitiveType primative;
switch (buffer->commandBuffer->boundGraphcisPipeline->info.primitiveType) { 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<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder; id<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
for (int i = 0; i < uniform->uniform->bindingCount; i++) { for (int i = 0; i < uniform->uniform->bindingCount; i++) {
if (uniform->uniform->bindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) { if (uniform->uniform->bindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) {
@@ -124,6 +118,14 @@ void gnCommandBindUniformFn(gnCommandBufferHandle buffer, gnUniform uniform, uin
offset:info.offset offset:info.offset
atIndex:(info.binding + 1) 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<MTLRenderCommandEncoder> encoder = (id<MTLRenderCommandEncoder>)buffer->commandBuffer->encoder;
[encoder setVertexBytes:data length:layout.size atIndex:0]; // TODO: fix this
}

View File

@@ -11,3 +11,6 @@ typedef struct gnPlatformFramebuffer_t {
gnBool isDepthFormat(gnImageFormat format); gnBool isDepthFormat(gnImageFormat format);
gnBool isStencilFormat(gnImageFormat format); gnBool isStencilFormat(gnImageFormat format);
gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info);
void destroyMetalFramebuffer(gnFramebuffer framebuffer);

View File

@@ -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)); framebuffer->framebuffer = malloc(sizeof(struct gnPlatformFramebuffer_t));
if (info.attachmentCount != info.renderPassDescriptor->info.attachmentCount) { if (info.attachmentCount != info.renderPassDescriptor->info.attachmentCount) {
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
@@ -74,7 +74,7 @@ gnReturnCode gnCreateFramebufferFn(gnFramebuffer framebuffer, gnOutputDevice dev
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnDestroyFramebufferFn(struct gnFramebuffer_t* framebuffer) { void destroyMetalFramebuffer(gnFramebuffer framebuffer) {
[framebuffer->framebuffer->framebuffer release]; [framebuffer->framebuffer->framebuffer release];
free(framebuffer->framebuffer); free(framebuffer->framebuffer);
} }

View File

@@ -5,3 +5,6 @@
typedef struct gnPlatformGraphicsPipeline_t { typedef struct gnPlatformGraphicsPipeline_t {
id<MTLRenderPipelineState> graphicsPipeline; id<MTLRenderPipelineState> graphicsPipeline;
} gnPlatformGraphicsPipeline; } gnPlatformGraphicsPipeline;
gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info);
void destroyMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline);

View File

@@ -4,7 +4,7 @@
#include "shader_module/metal_shader_module.h" #include "shader_module/metal_shader_module.h"
#include "surface/metal_surface.h" #include "surface/metal_surface.h"
MTLBlendFactor vkGryphnBlendFactor(gnBlendFactor factor) { MTLBlendFactor mtlGryphnBlendFactor(gnBlendFactor factor) {
switch (factor) { switch (factor) {
case GN_BLEND_FACTOR_ZERO: return MTLBlendFactorZero; case GN_BLEND_FACTOR_ZERO: return MTLBlendFactorZero;
case GN_BLEND_FACTOR_ONE: return MTLBlendFactorOne; 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) { switch(operation) {
case GN_OPERATION_ADD: return MTLBlendOperationAdd; 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)); graphicsPipeline->graphicsPipeline = malloc(sizeof(struct gnPlatformGraphicsPipeline_t));
MTLRenderPipelineDescriptor* descriptor = [[MTLRenderPipelineDescriptor alloc] init]; MTLRenderPipelineDescriptor* descriptor = [[MTLRenderPipelineDescriptor alloc] init];
@@ -43,15 +43,15 @@ gnReturnCode gnCreateGraphicsPipelineFn(gnGraphicsPipeline graphicsPipeline, gnO
gnSubpassAttachmentInfo subpassAtt = subpass.colorAttachments[i]; gnSubpassAttachmentInfo subpassAtt = subpass.colorAttachments[i];
gnRenderPassAttachmentInfo attInfo = info.renderPassDescriptor->info.attachmentInfos[subpassAtt.index]; 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) { if (info.colorBlending.enable == gnTrue) {
[descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = YES; [descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = YES;
[descriptor.colorAttachments objectAtIndexedSubscript:i].rgbBlendOperation = vkGryphnBlendOperation(info.colorBlending.colorBlendOperation); [descriptor.colorAttachments objectAtIndexedSubscript:i].rgbBlendOperation = mtlGryphnBlendOperation(info.colorBlending.colorBlendOperation);
[descriptor.colorAttachments objectAtIndexedSubscript:i].alphaBlendOperation = vkGryphnBlendOperation(info.colorBlending.alphaBlendOperation); [descriptor.colorAttachments objectAtIndexedSubscript:i].alphaBlendOperation = mtlGryphnBlendOperation(info.colorBlending.alphaBlendOperation);
[descriptor.colorAttachments objectAtIndexedSubscript:i].sourceRGBBlendFactor = vkGryphnBlendFactor(info.colorBlending.sourceColorBlendFactor); [descriptor.colorAttachments objectAtIndexedSubscript:i].sourceRGBBlendFactor = mtlGryphnBlendFactor(info.colorBlending.sourceColorBlendFactor);
[descriptor.colorAttachments objectAtIndexedSubscript:i].sourceAlphaBlendFactor = vkGryphnBlendFactor(info.colorBlending.sourceAlphaBlendFactor); [descriptor.colorAttachments objectAtIndexedSubscript:i].sourceAlphaBlendFactor = mtlGryphnBlendFactor(info.colorBlending.sourceAlphaBlendFactor);
[descriptor.colorAttachments objectAtIndexedSubscript:i].destinationRGBBlendFactor = vkGryphnBlendFactor(info.colorBlending.destinationColorBlendFactor); [descriptor.colorAttachments objectAtIndexedSubscript:i].destinationRGBBlendFactor = mtlGryphnBlendFactor(info.colorBlending.destinationColorBlendFactor);
[descriptor.colorAttachments objectAtIndexedSubscript:i].destinationAlphaBlendFactor = vkGryphnBlendFactor(info.colorBlending.destinationAlphaBlendFactor); [descriptor.colorAttachments objectAtIndexedSubscript:i].destinationAlphaBlendFactor = mtlGryphnBlendFactor(info.colorBlending.destinationAlphaBlendFactor);
} else { } else {
[descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = FALSE; [descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = FALSE;
} }
@@ -97,7 +97,7 @@ gnReturnCode gnCreateGraphicsPipelineFn(gnGraphicsPipeline graphicsPipeline, gnO
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnDestroyGraphicsPipelineFn(struct gnGraphicsPipeline_t *graphicsPipeline) { void destroyMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline) {
[graphicsPipeline->graphicsPipeline->graphicsPipeline release]; [graphicsPipeline->graphicsPipeline->graphicsPipeline release];
free(graphicsPipeline->graphicsPipeline); free(graphicsPipeline->graphicsPipeline);
} }

View File

@@ -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 <QuartzCore/CAMetalLayer.h>
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info);

View File

@@ -1,14 +1,6 @@
#include "present/gryphn_present.h" #include "metal_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 <QuartzCore/CAMetalLayer.h>
gnReturnCode gnPresentFn(gnOutputDeviceHandle device, gnPresentInfo info) { gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
for (int i = 0; i < info.waitCount; i++) { for (int i = 0; i < info.waitCount; i++) {
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {} while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
} }

View File

@@ -8,3 +8,7 @@ typedef struct gnPlatformPresentationQueue_t {
uint32_t currentImage; uint32_t currentImage;
} gnPlatformPresentationQueue; } 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);

View File

@@ -5,7 +5,7 @@
#include "texture/metal_texture.h" #include "texture/metal_texture.h"
#include "sync/semaphore/metal_semaphore.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) { if (presentationInfo.minImageCount > 3) {
gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){
.message = gnCreateString("On Metal you cannot have more than 3 images in a presentation queue") .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)); presentationQueue->presentationQueue = malloc(sizeof(struct gnPlatformPresentationQueue_t));
MTLPixelFormat convertedFormat = mtlGryphnFormatToVulkanFormat(presentationInfo.format.format); MTLPixelFormat convertedFormat = mtlGryphnFormatToMetalFormat(presentationInfo.format.format);
CGColorSpaceRef convertedColorSpace = mtlGryphnColorSpaceToVulkanColorSpace(presentationInfo.format.colorSpace); CGColorSpaceRef convertedColorSpace = mtlGryphnColorSpaceToMetalColorSpace(presentationInfo.format.colorSpace);
presentationQueue->presentationQueue->textureCount = presentationInfo.minImageCount; presentationQueue->presentationQueue->textureCount = presentationInfo.minImageCount;
presentationQueue->presentationQueue->textures = malloc(sizeof(id<MTLTexture>) * presentationInfo.minImageCount); presentationQueue->presentationQueue->textures = malloc(sizeof(id<MTLTexture>) * presentationInfo.minImageCount);
@@ -47,7 +47,7 @@ gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueueHandle presentationQ
return GN_SUCCESS; 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; semaphore->semaphore->eventTriggered = gnFalse;
*imageIndex = presentationQueue->presentationQueue->currentImage; *imageIndex = presentationQueue->presentationQueue->currentImage;
presentationQueue->presentationQueue->currentImage++; presentationQueue->presentationQueue->currentImage++;
@@ -56,7 +56,7 @@ gnReturnCode gnPresentationQueueGetImageFn(gnPresentationQueueHandle presentatio
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnDestroyPresentationQueueFn(gnPresentationQueueHandle presentationQueue) { void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) {
for (int i = 0; i < presentationQueue->imageCount; i++) { for (int i = 0; i < presentationQueue->imageCount; i++) {
[presentationQueue->presentationQueue->textures[i] release]; [presentationQueue->presentationQueue->textures[i] release];
} }

View File

@@ -5,3 +5,6 @@
typedef struct gnPlatformRenderPassDescriptor_t { typedef struct gnPlatformRenderPassDescriptor_t {
MTLRenderPassDescriptor* passDescriptor; MTLRenderPassDescriptor* passDescriptor;
} gnPlatformRenderPassDescriptor; } gnPlatformRenderPassDescriptor;
gnReturnCode createMetalRenderPass(gnRenderPassDescriptor renderPass, gnDevice device, gnRenderPassDescriptorInfo info);
void destroyMetalRenderPass(gnRenderPassDescriptor renderPass);

View File

@@ -1,13 +1,13 @@
#include "metal_render_pass.h" #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 = malloc(sizeof(gnPlatformRenderPassDescriptor));
renderPass->renderPassDescriptor->passDescriptor = [[MTLRenderPassDescriptor alloc] init]; renderPass->renderPassDescriptor->passDescriptor = [[MTLRenderPassDescriptor alloc] init];
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnDestroyRenderPassDescriptorFn(struct gnRenderPassDescriptor_t* renderPass) { void destroyMetalRenderPass(gnRenderPassDescriptor renderPass) {
[renderPass->renderPassDescriptor->passDescriptor release]; [renderPass->renderPassDescriptor->passDescriptor release];
free(renderPass->renderPassDescriptor); free(renderPass->renderPassDescriptor);
} }

View File

@@ -4,4 +4,8 @@
typedef struct gnPlatformShaderModule_t { typedef struct gnPlatformShaderModule_t {
id<MTLFunction> function; id<MTLFunction> function;
uint32_t pushConstantIndex;
} gnPlatformShaderModule; } gnPlatformShaderModule;
gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo);
void destroyMetalShaderModule(gnShaderModule module);

View File

@@ -6,13 +6,13 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
void mtlSpirVErrorCallback(void *userdata, const char *error) { void mtlSpirVErrorCallback(void *userdata, const char *error) {
struct gnDebugger_t* debugger = (struct gnDebugger_t*)userdata; gnDebugger debugger = (gnDebugger)userdata;
gnDebuggerSetErrorMessage(debugger, (gnMessageData){ gnDebuggerSetErrorMessage(debugger, (gnMessageData){
.message = gnCreateString(error) .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)); module->shaderModule = malloc(sizeof(struct gnPlatformShaderModule_t));
spvc_context context = NULL; 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_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_create_compiler_options(compiler, &options);
spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_VERSION, 200); 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; return GN_SUCCESS;
} }
void gnDestroyShaderModuleFn(struct gnShaderModule_t* module) { void destroyMetalShaderModule(gnShaderModule module) {
free(module->shaderModule); free(module->shaderModule);
} }

View File

@@ -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);

View File

@@ -1,16 +1,10 @@
#include "submit/gryphn_submit.h" #include "metal_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 gnSubmitFn(gnDevice* device, gnSubmitInfo info) { gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
for (int i = 0; i < info.waitCount; i++) { for (int i = 0; i < info.waitCount; i++) {
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {} while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
} }
__block gnSemaphore* semsToSignal = info.signalSemaphores; __block gnSemaphore* semsToSignal = info.signalSemaphores;
__block int semsToSignalCount = info.signalCount; __block int semsToSignalCount = info.signalCount;
__block gnFence fenceToSignal = info.fence; __block gnFence fenceToSignal = info.fence;

View File

@@ -7,8 +7,8 @@ typedef struct gnPlatformWindowSurface_t {
} gnPlatformWindowSurface; } gnPlatformWindowSurface;
MTLPixelFormat mtlGryphnFormatToVulkanFormat(gnImageFormat format); MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format);
CGColorSpaceRef mtlGryphnColorSpaceToVulkanColorSpace(gnColorSpace colorSpace); CGColorSpaceRef mtlGryphnColorSpaceToMetalColorSpace(gnColorSpace colorSpace);
gnReturnCode createMetalSurface(gnWindowSurface windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo); gnReturnCode createMetalSurface(gnWindowSurface windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo);
gnSurfaceDetails getMetalSurfaceDetails(gnWindowSurface windowSurface, gnPhysicalDevice device); gnSurfaceDetails getMetalSurfaceDetails(gnWindowSurface windowSurface, gnPhysicalDevice device);

View File

@@ -26,17 +26,22 @@ gnSurfaceDetails getMetalSurfaceDetails(
surfaceDetails.formats = (gnSurfaceFormat[]){ { GN_FORMAT_BGRA8_SRGB, GN_COLOR_SPACE_SRGB_NONLINEAR } }; surfaceDetails.formats = (gnSurfaceFormat[]){ { GN_FORMAT_BGRA8_SRGB, GN_COLOR_SPACE_SRGB_NONLINEAR } };
surfaceDetails.minImageCount = 2; surfaceDetails.minImageCount = 2;
surfaceDetails.maxImageCount = 3; surfaceDetails.maxImageCount = 3;
CGSize size = windowSurface->windowSurface->layer.visibleRect.size;
surfaceDetails.minImageSize = surfaceDetails.maxImageSize = surfaceDetails.currentSize = (gnUInt2){size.width, size.height};
return surfaceDetails; return surfaceDetails;
} }
MTLPixelFormat mtlGryphnFormatToVulkanFormat(gnImageFormat format) { MTLPixelFormat mtlGryphnFormatToMetalFormat(gnImageFormat format) {
switch (format) { switch (format) {
case GN_FORMAT_BGRA8_SRGB: { return MTLPixelFormatBGRA8Unorm_sRGB; } case GN_FORMAT_NONE: return MTLPixelFormatInvalid;
default: 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) { switch (colorSpace) {
case GN_COLOR_SPACE_SRGB_NONLINEAR: { return CGColorSpaceCreateWithName(kCGColorSpaceSRGB); } case GN_COLOR_SPACE_SRGB_NONLINEAR: { return CGColorSpaceCreateWithName(kCGColorSpaceSRGB); }
} }

View File

@@ -3,6 +3,10 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
#import <Metal/MTLEvent.h> #import <Metal/MTLEvent.h>
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);

View File

@@ -1,7 +1,7 @@
#include "metal_fence.h" #include "metal_fence.h"
#include "devices/metal_output_devices.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 = malloc(sizeof(gnPlatformFence));
// fence->fence->fence = [device->outputDevice->device newSharedEvent]; // fence->fence->fence = [device->outputDevice->device newSharedEvent];
@@ -10,14 +10,14 @@ gnReturnCode gnCreateFenceFn(struct gnFence_t* fence, struct gnOutputDevice_t* d
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnSignalFenceFn(struct gnFence_t* fence) { void singalMetalFence(gnFence fence) {
// dispatch_semaphore_signal(fence->fence->semaphore); // 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); // dispatch_semaphore_wait(fence->fence->semaphore, timeout);
while (fence->signaled == gnFalse) {} while (fence->signaled == gnFalse) {}
} }
void gnResetFenceFn(struct gnFence_t* fence) { void resetMetalFence(gnFence fence) {
// dispatch_semaphore_signal(fence->fence->semaphore); // dispatch_semaphore_signal(fence->fence->semaphore);
// [fence->fence->fence setSignaledValue:0]; // [fence->fence->fence setSignaledValue:0];
// [fence->fence->fence notifyListener:fence->fence->listener // [fence->fence->fence notifyListener:fence->fence->listener
@@ -26,7 +26,7 @@ void gnResetFenceFn(struct gnFence_t* fence) {
// dispatch_semaphore_signal(fence->fence->semaphore); // dispatch_semaphore_signal(fence->fence->semaphore);
// }]; // }];
} }
void gnDestroyFenceFn(struct gnFence_t* fence) { void destroyMetalFence(gnFence fence) {
// [fence->fence->fence release]; // [fence->fence->fence release];
// [fence->fence->listener release]; // [fence->fence->listener release];
// free(fence->fence); // free(fence->fence);

View File

@@ -6,3 +6,6 @@ typedef struct gnPlatformSemaphore_t {
id<MTLEvent> event; id<MTLEvent> event;
bool eventTriggered; bool eventTriggered;
} gnPlatformSemaphore; } gnPlatformSemaphore;
gnReturnCode createMetalSemaphore(gnSemaphore semaphore, gnOutputDevice device);
void destroyMetalSemaphore(gnSemaphore semaphore);

View File

@@ -1,13 +1,13 @@
#include "metal_semaphore.h" #include "metal_semaphore.h"
#include "devices/metal_output_devices.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 = malloc(sizeof(gnPlatformSemaphore));
semaphore->semaphore->event = [device->outputDevice->device newEvent]; semaphore->semaphore->event = [device->outputDevice->device newEvent];
return GN_SUCCESS; return GN_SUCCESS;
} }
void gnDestroySemaphoreFn(gnSemaphore semaphore) { void destroyMetalSemaphore(gnSemaphore semaphore) {
[semaphore->semaphore->event release]; [semaphore->semaphore->event release];
free(semaphore->semaphore); free(semaphore->semaphore);
} }

View File

@@ -5,3 +5,7 @@
typedef struct gnPlatformTexture_t { typedef struct gnPlatformTexture_t {
id<MTLTexture> texture; id<MTLTexture> texture;
} gnPlatformTexture; } gnPlatformTexture;
gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnTextureInfo info);
void metalTextureData(gnTextureHandle texture, void* pixelData);
void metalDestroyTexture(gnTexture texture);

View File

@@ -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);
}

View File

@@ -1,12 +0,0 @@
#include <uniforms/gryphn_uniform.h>
#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;
}
}
}

View File

@@ -12,3 +12,6 @@ typedef struct gnPlatformUniform_t {
uint32_t bindingCount; uint32_t bindingCount;
metalUniformBinding* bindings; metalUniformBinding* bindings;
} gnPlatformUniform; } gnPlatformUniform;
void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info);
void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info);

View File

@@ -0,0 +1,23 @@
#include <uniforms/gryphn_uniform.h>
#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;
}
}
}

View File

@@ -1,5 +1,8 @@
#pragma once #pragma once
#include <vulkan/vulkan.h>
#include <uniforms/gryphn_uniform_pool.h> #include <uniforms/gryphn_uniform_pool.h>
typedef struct gnPlatformUniformPool_t {} gnPlatformUniformPool; typedef struct gnPlatformUniformPool_t {} gnPlatformUniformPool;
gnReturnCode createMetalUniformPool(gnUniformPool pool, gnDeviceHandle device);
gnUniform* allocateMetalUniforms(gnUniformPool pool, const gnUniformAllocationInfo allocInfo);
void destroyMetalUniformPool(gnUniformPool pool);

View File

@@ -2,11 +2,11 @@
#include <uniforms/gryphn_uniform.h> #include <uniforms/gryphn_uniform.h>
#include "metal_uniform.h" #include "metal_uniform.h"
gnReturnCode gnCreateUniformPoolFn(gnUniformPool pool, gnDeviceHandle device) { gnReturnCode createMetalUniformPool(gnUniformPool pool, gnDeviceHandle device) {
return GN_SUCCESS; return GN_SUCCESS;
} }
gnUniform* gnUniformPoolAllocateUniformsFn(gnUniformPool pool, const gnUniformAllocationInfo allocInfo) { gnUniform* allocateMetalUniforms(gnUniformPool pool, const gnUniformAllocationInfo allocInfo) {
gnUniform* uniforms = malloc(sizeof(gnUniform) * allocInfo.setCount); gnUniform* uniforms = malloc(sizeof(gnUniform) * allocInfo.setCount);
for (int i = 0; i < allocInfo.setCount; i++) { for (int i = 0; i < allocInfo.setCount; i++) {
uniforms[i] = malloc(sizeof(struct gnUniform_t)); uniforms[i] = malloc(sizeof(struct gnUniform_t));
@@ -20,4 +20,4 @@ gnUniform* gnUniformPoolAllocateUniformsFn(gnUniformPool pool, const gnUniformAl
return uniforms; return uniforms;
} }
void gnDestroyUniformPoolFn(gnUniformPool pool) { } void destroyMetalUniformPool(gnUniformPool pool) { free(pool->uniformPool); }