diff --git a/include/gryphn/utils/gryphn_glfw_util.h b/include/gryphn/utils/gryphn_glfw_util.h index 3f99748..4370a86 100644 --- a/include/gryphn/utils/gryphn_glfw_util.h +++ b/include/gryphn/utils/gryphn_glfw_util.h @@ -21,4 +21,11 @@ gnReturnCode gnCreateGLFWWindowSurface(struct gnWindowSurface_t* windowSurface, return gnCreateMacOSWindowSurface(windowSurface, instance, surfaceCreateInfo); } +// gnReturnCode gnCreateGLFWWindowSurface(struct gnWindowSurface_t* windowSurface, struct gnInstance_t* instance, GLFWwindow* window) { +// gnMetalWindowSurfaceInfo surfaceCreateInfo = { +// .layer = (CAMetalLayer*)glfwGetCocoaWindow(window).contentView.layer; +// }; +// return gnCreateMetalWindowSurface(windowSurface, instance, surfaceCreateInfo); +// } + #endif diff --git a/rendering_api/metal/src/core/commands/command_buffer/metal_command_buffer.m b/rendering_api/metal/src/core/commands/command_buffer/metal_command_buffer.m index 9aa50d0..70afad8 100644 --- a/rendering_api/metal/src/core/commands/command_buffer/metal_command_buffer.m +++ b/rendering_api/metal/src/core/commands/command_buffer/metal_command_buffer.m @@ -5,17 +5,20 @@ gnReturnCode gnCommandPoolAllocateCommandBuffersFn(struct gnCommandBuffer_t* commandBuffers, uint32_t count, struct gnCommandPool_t* pool) { for (int i = 0; i < count; i++) { commandBuffers[i].commandBuffer = malloc(sizeof(gnPlatformCommandBuffer)); - commandBuffers[i].commandBuffer->commandBuffer = [pool->commandPool->commandQueue commandBuffer]; } return GN_SUCCESS; } - -gnReturnCode gnBeginCommandBuffer(struct gnCommandBuffer_t* commandBuffer) { +void gnResetCommandBufferFn(struct gnCommandBuffer_t *commandBuffer) { + // do nothing +} +gnReturnCode gnBeginCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) { commandBuffer->commandBuffer->boundGraphcisPipeline = NULL; + commandBuffer->commandBuffer->commandBuffer = [commandBuffer->commandPool->commandPool->commandQueue commandBuffer]; return GN_SUCCESS; } -gnReturnCode gnEndCommandBuffer(struct gnCommandBuffer_t* commandBuffer) { +gnReturnCode gnEndCommandBufferFn(struct gnCommandBuffer_t* commandBuffer) { + // [commandBuffer->commandBuffer->commandBuffer commit]; return GN_SUCCESS; } diff --git a/rendering_api/metal/src/core/devices/metal_output_device.m b/rendering_api/metal/src/core/devices/metal_output_device.m index 5f85f92..eedfd2d 100644 --- a/rendering_api/metal/src/core/devices/metal_output_device.m +++ b/rendering_api/metal/src/core/devices/metal_output_device.m @@ -8,19 +8,19 @@ gnReturnCode gnCreateOutputDeviceFn(gnOutputDevice* outputDevice, gnInstance* instance, struct gnOutputDeviceInfo_t deviceInfo) { outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice)); outputDevice->outputDevice->device = deviceInfo.physicalDevice.physicalDevice->device.retain; - // outputDevice->outputDevice->queueCount = deviceInfo.queueInfoCount; - // outputDevice->outputDevice->queues = malloc(sizeof(id) * deviceInfo.queueInfoCount); - // for (int i = 0; i < deviceInfo.queueInfoCount; i++) { - // outputDevice->outputDevice->queues[i] = outputDevice->outputDevice->device.newCommandQueue; - // } + outputDevice->outputDevice->queueCount = deviceInfo.queueInfoCount; + outputDevice->outputDevice->queues = malloc(sizeof(id) * deviceInfo.queueInfoCount); + for (int i = 0; i < deviceInfo.queueInfoCount; i++) { + outputDevice->outputDevice->queues[i] = outputDevice->outputDevice->device.newCommandQueue; + } return GN_SUCCESS; } void gnDestroyOutputDeviceFn(gnOutputDevice* device) { - // for (int i = 0; i < device->outputDevice->queueCount; i++) { - // [device->outputDevice->queues[i] release]; - // } + for (int i = 0; i < device->outputDevice->queueCount; i++) { + [device->outputDevice->queues[i] release]; + } [device->outputDevice->device release]; free(device->outputDevice); } diff --git a/rendering_api/metal/src/core/present/metal_present.m b/rendering_api/metal/src/core/present/metal_present.m new file mode 100644 index 0000000..cddf53b --- /dev/null +++ b/rendering_api/metal/src/core/present/metal_present.m @@ -0,0 +1,33 @@ +#include "core/present/gryphn_present.h" +#include "core/instance/metal_instance.h" +#include "core/surface/metal_surface.h" +#include "core/devices/metal_output_devices.h" +#include "core/sync/semaphore/metal_semaphore.h" +#include "core/presentation_queue/metal_presentation_queue.h" +#include "core/debugger/gryphn_debugger.h" +#import + +gnReturnCode gnPresentFn(struct gnOutputDevice_t* device, struct gnPresentInfo_t info) { + for (int i = 0; i < info.waitCount; i++) { + while (!info.waitSemaphores[i].semaphore->eventTriggered) {} + } + + info.presentationQueues->info.surface.windowSurface->layer.device = device->outputDevice->device; + id drawable = [info.presentationQueues->info.surface.windowSurface->layer nextDrawable]; + + id commandBuffer = [device->outputDevice->queues[info.queueIndex] commandBuffer]; + + MTLRenderPassDescriptor* passDesc = [MTLRenderPassDescriptor renderPassDescriptor]; + passDesc.colorAttachments[0].texture = drawable.texture; + passDesc.colorAttachments[0].loadAction = MTLLoadActionClear; + passDesc.colorAttachments[0].storeAction = MTLStoreActionStore; + passDesc.colorAttachments[0].clearColor = MTLClearColorMake(1.0f, 0, 0, 1.0f); + id render = [commandBuffer renderCommandEncoderWithDescriptor:passDesc]; + [render endEncoding]; + + [commandBuffer presentDrawable:drawable]; + [commandBuffer commit]; + + + return GN_SUCCESS; +} diff --git a/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.h b/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.h index 7eb1d03..87855af 100644 --- a/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.h +++ b/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.h @@ -5,4 +5,6 @@ typedef struct gnPlatformPresentationQueue_t { int textureCount; id* textures; + + uint32_t currentImage; } gnPlatformPresentationQueue; diff --git a/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.m b/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.m index 1da44b0..cdf05f5 100644 --- a/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.m +++ b/rendering_api/metal/src/core/presentation_queue/metal_presentation_queue.m @@ -3,6 +3,7 @@ #include "core/devices/metal_output_devices.h" #include "core/debugger/gryphn_debugger.h" #include "core/texture/metal_texture.h" +#include "core/sync/semaphore/metal_semaphore.h" gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueue* presentationQueue, const gnOutputDevice* device, struct gnPresentationQueueInfo_t presentationInfo) { if (presentationInfo.minImageCount > 3) { @@ -45,6 +46,14 @@ gnReturnCode gnCreatePresentationQueueFn(gnPresentationQueue* presentationQueue, return GN_SUCCESS; } +void gnPresentationQueueGetImageFn(gnPresentationQueue* presentationQueue, uint64_t timeout, struct gnSemaphore_t* semaphore, uint32_t* imageIndex) { + semaphore->semaphore->eventTriggered = gnFalse; + *imageIndex = presentationQueue->presentationQueue->currentImage; + presentationQueue->presentationQueue->currentImage++; + presentationQueue->presentationQueue->currentImage %= presentationQueue->imageCount; + semaphore->semaphore->eventTriggered = gnTrue; +} + void gnDestroyPresentationQueueFn(gnPresentationQueue *presentationQueue) { for (int i = 0; i < presentationQueue->imageCount; i++) { [presentationQueue->presentationQueue->textures[i] release]; diff --git a/rendering_api/metal/src/core/submit/metal_submit.m b/rendering_api/metal/src/core/submit/metal_submit.m new file mode 100644 index 0000000..a7b80b8 --- /dev/null +++ b/rendering_api/metal/src/core/submit/metal_submit.m @@ -0,0 +1,28 @@ +#include "core/submit/gryphn_submit.h" +#include "core/sync/semaphore/metal_semaphore.h" +#include "core/commands/command_buffer/metal_command_buffer.h" +#include "core/debugger/gryphn_debugger.h" +#include "core/commands/command_pool/metal_command_pool.h" + +gnReturnCode gnSubmitFn(struct gnOutputDevice_t* device, struct gnSubmitInfo_t 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; + + for (int i = 0; i < info.commandBufferCount; i++) { + id commandBuffer = info.commandBuffers[i].commandBuffer->commandBuffer; + [info.commandBuffers[i].commandBuffer->commandBuffer addCompletedHandler:^(id buffer) { + for (int c = 0; c < semsToSignalCount; c++) { + semsToSignal[c].semaphore->eventTriggered = gnTrue; + } + }]; + + [commandBuffer commit]; + } + + return GN_SUCCESS; +} diff --git a/rendering_api/metal/src/core/surface/metal_surface.h b/rendering_api/metal/src/core/surface/metal_surface.h index 23e5227..645d892 100644 --- a/rendering_api/metal/src/core/surface/metal_surface.h +++ b/rendering_api/metal/src/core/surface/metal_surface.h @@ -3,6 +3,7 @@ #import typedef struct gnPlatformWindowSurface_t{ + CAMetalLayer* layer; } gnPlatformWindowSurface; diff --git a/rendering_api/metal/src/core/surface/metal_surface.m b/rendering_api/metal/src/core/surface/metal_surface.m index 07aaadc..a3b2b90 100644 --- a/rendering_api/metal/src/core/surface/metal_surface.m +++ b/rendering_api/metal/src/core/surface/metal_surface.m @@ -15,11 +15,14 @@ gnReturnCode gnCreateMacOSWindowSurfaceFn(struct gnWindowSurface_t* windowSurfac CAMetalLayer* layer = [CAMetalLayer layer]; [layer setContentsScale:[window backingScaleFactor]]; [layer setFramebufferOnly:YES]; + [layer setPixelFormat:MTLPixelFormatBGRA8Unorm_sRGB]; + [layer setFrame:view.bounds]; [view setLayer:layer]; [view setWantsLayer:YES]; windowSurface->windowSurface = malloc(sizeof(gnPlatformWindowSurface)); + windowSurface->windowSurface->layer = layer; return GN_SUCCESS; } @@ -28,9 +31,6 @@ void gnDestroyWindowSurfaceFn(struct gnWindowSurface_t *windowSurface) { } struct gnSurfaceDetails_t gnGetSurfaceDetailsFn( - // struct gnWindowSurface_t* windowSurface, - // struct gnPhysicalDevice_t device, - // uint32_t* formatCount struct gnWindowSurface_t* windowSurface, struct gnPhysicalDevice_t device ) { struct gnSurfaceDetails_t surfaceDetails; diff --git a/rendering_api/metal/src/core/sync/fence/metal_fence.h b/rendering_api/metal/src/core/sync/fence/metal_fence.h index ac34cff..28b5a0c 100644 --- a/rendering_api/metal/src/core/sync/fence/metal_fence.h +++ b/rendering_api/metal/src/core/sync/fence/metal_fence.h @@ -4,7 +4,5 @@ #import typedef struct gnPlatformFence_t { - id fence; - MTLSharedEventListener* listener; - dispatch_semaphore_t semaphore; + } gnPlatformFence; diff --git a/rendering_api/metal/src/core/sync/fence/metal_fence.m b/rendering_api/metal/src/core/sync/fence/metal_fence.m index 678248c..8c2f389 100644 --- a/rendering_api/metal/src/core/sync/fence/metal_fence.m +++ b/rendering_api/metal/src/core/sync/fence/metal_fence.m @@ -2,31 +2,32 @@ #include "core/devices/metal_output_devices.h" gnReturnCode gnCreateFenceFn(struct gnFence_t* fence, struct gnOutputDevice_t* device) { - fence->fence = malloc(sizeof(gnPlatformFence)); + // fence->fence = malloc(sizeof(gnPlatformFence)); - fence->fence->fence = [device->outputDevice->device newSharedEvent]; - fence->fence->listener = [[MTLSharedEventListener alloc] init]; - fence->fence->semaphore = dispatch_semaphore_create(1); + // fence->fence->fence = [device->outputDevice->device newSharedEvent]; + // fence->fence->listener = [[MTLSharedEventListener alloc] init]; + // fence->fence->semaphore = dispatch_semaphore_create(1); return GN_SUCCESS; } void gnSignalFenceFn(struct gnFence_t* fence) { - dispatch_semaphore_signal(fence->fence->semaphore); + // dispatch_semaphore_signal(fence->fence->semaphore); } void gnWaitForFenceFn(struct gnFence_t* fence, uint64_t timeout) { - dispatch_semaphore_wait(fence->fence->semaphore, timeout); + // dispatch_semaphore_wait(fence->fence->semaphore, timeout); + while (fence->signaled == gnFalse) {} } void gnResetFenceFn(struct gnFence_t* fence) { - dispatch_semaphore_signal(fence->fence->semaphore); - [fence->fence->fence setSignaledValue:0]; - [fence->fence->fence notifyListener:fence->fence->listener - atValue:1 - block:^(id ev, uint64_t val) { - dispatch_semaphore_signal(fence->fence->semaphore); - }]; + // dispatch_semaphore_signal(fence->fence->semaphore); + // [fence->fence->fence setSignaledValue:0]; + // [fence->fence->fence notifyListener:fence->fence->listener + // atValue:1 + // block:^(id ev, uint64_t val) { + // dispatch_semaphore_signal(fence->fence->semaphore); + // }]; } void gnDestroyFenceFn(struct gnFence_t* fence) { - [fence->fence->fence release]; - [fence->fence->listener release]; - free(fence->fence); + // [fence->fence->fence release]; + // [fence->fence->listener release]; + // free(fence->fence); } diff --git a/rendering_api/metal/src/core/sync/semaphore/metal_semaphore.h b/rendering_api/metal/src/core/sync/semaphore/metal_semaphore.h index f359699..f433c97 100644 --- a/rendering_api/metal/src/core/sync/semaphore/metal_semaphore.h +++ b/rendering_api/metal/src/core/sync/semaphore/metal_semaphore.h @@ -4,4 +4,5 @@ typedef struct gnPlatformSemaphore_t { id event; + gnBool eventTriggered; } gnPlatformSemaphore; diff --git a/src/core/presentation_queue/gryphn_presentation_queue.c b/src/core/presentation_queue/gryphn_presentation_queue.c index b7efd18..77902c0 100644 --- a/src/core/presentation_queue/gryphn_presentation_queue.c +++ b/src/core/presentation_queue/gryphn_presentation_queue.c @@ -3,6 +3,7 @@ gnReturnCode gnCreatePresentationQueue(gnPresentationQueue* presentationQueue, struct gnOutputDevice_t* device, struct gnPresentationQueueInfo_t presentationInfo){ presentationQueue->outputDevice = device; + presentationQueue->info = presentationInfo; return device->deviceFunctions->_gnCreatePresentationQueue(presentationQueue, device, presentationInfo); } diff --git a/src/core/presentation_queue/gryphn_presentation_queue.h b/src/core/presentation_queue/gryphn_presentation_queue.h index a338703..10ce0ac 100644 --- a/src/core/presentation_queue/gryphn_presentation_queue.h +++ b/src/core/presentation_queue/gryphn_presentation_queue.h @@ -23,6 +23,7 @@ typedef struct gnPresentationQueue_t { gnBool valid; uint32_t imageCount; struct gnTexture_t* images; + struct gnPresentationQueueInfo_t info; } gnPresentationQueue; gnReturnCode gnCreatePresentationQueue(gnPresentationQueue* presentationQueue, struct gnOutputDevice_t* device, struct gnPresentationQueueInfo_t presentationInfo); diff --git a/src/core/window_surface/gryphn_surface.c b/src/core/window_surface/gryphn_surface.c index 51016d0..5803e2c 100644 --- a/src/core/window_surface/gryphn_surface.c +++ b/src/core/window_surface/gryphn_surface.c @@ -65,7 +65,7 @@ uint32_t gnGetMaxImageCount(struct gnWindowSurface_t surface, struct gnPhysicalD uint32_t gnGetPreferredImageCount(struct gnWindowSurface_t surface, struct gnPhysicalDevice_t device) { struct gnSurfaceDetails_t surfaceDetails = surface.instance->functions->_gnGetSurfaceDetails(&surface, device); - uint32_t imageCount = surfaceDetails.minImageCount; + uint32_t imageCount = surfaceDetails.minImageCount + 1; if (surfaceDetails.maxImageCount > 0 && imageCount > surfaceDetails.maxImageCount) { imageCount = surfaceDetails.maxImageCount; }