From 504603e5acb33b7f507d1b96a9e46e8b02e5eb71 Mon Sep 17 00:00:00 2001 From: Greg Wells Date: Tue, 1 Jul 2025 16:15:43 -0400 Subject: [PATCH] fix some bugs on macos and improve presentation queue --- .../metal_graphics_pipeline.m | 5 ++-- .../apis/metal/src/present/metal_present.m | 18 ++++++-------- .../metal_presentation_queue.h | 9 +++---- .../metal_presentation_queue.m | 24 +++++++++---------- .../src/shader_module/metal_shader_module.m | 2 -- projects/apis/metal/src/submit/metal_submit.m | 2 +- .../apis/metal/src/surface/metal_surface.m | 1 - .../apis/metal/src/texture/metal_texture.m | 1 + .../platform_macos/gryphn_platform_macos.h | 1 + .../platform_macos/gryphn_platform_macos.m | 12 +++++++++- projects/utils | 2 +- 11 files changed, 41 insertions(+), 36 deletions(-) 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 5c56c50..4abf056 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 @@ -100,9 +100,8 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn } MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init]; - depthStencilDesc.depthWriteEnabled = info.depthStencil.depthWriteEnable, - depthStencilDesc.depthCompareFunction = info.depthStencil.depthWriteEnable, - depthStencilDesc.depthCompareFunction = mtlGrypnCompareOperation(info.depthStencil.operation), + depthStencilDesc.depthWriteEnabled = info.depthStencil.depthWriteEnable; + depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess; graphicsPipeline->graphicsPipeline->depthState = [device->outputDevice->device newDepthStencilStateWithDescriptor:depthStencilDesc]; diff --git a/projects/apis/metal/src/present/metal_present.m b/projects/apis/metal/src/present/metal_present.m index e765999..9ea2cf4 100644 --- a/projects/apis/metal/src/present/metal_present.m +++ b/projects/apis/metal/src/present/metal_present.m @@ -8,19 +8,15 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { for (int i =0 ; i < info.presentationQueueCount; i++) { info.presentationQueues[i]->info.surface->windowSurface->layer.device = device->outputDevice->device; id drawable = [info.presentationQueues[i]->info.surface->windowSurface->layer nextDrawable]; - if (drawable == nil) { - return GN_FAILED_TO_CREATE_FRAMEBUFFER; - } + if (drawable == nil) return GN_FAILED_TO_CREATE_FRAMEBUFFER; + + __block gnPresentationQueue presentationQueue = info.presentationQueues[i]; + __block uint32_t imageIndex = info.imageIndices[i]; id commandBuffer = [device->outputDevice->transferQueue 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 addCompletedHandler:^(id buffer) { + uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex); + }]; id blit = [commandBuffer blitCommandEncoder]; 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 4fe8525..c17ecfc 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h @@ -2,11 +2,12 @@ #import #include "presentation_queue/gryphn_presentation_queue.h" -typedef struct gnPlatformPresentationQueue_t { - int textureCount; - id* textures; +typedef id metalTexture; +GN_ARRAY_LIST(metalTexture); - uint32_t currentImage; +typedef struct gnPlatformPresentationQueue_t { + metalTextureArrayList textures; + uint32_tArrayList avaliableTextures; } gnPlatformPresentationQueue; gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo); 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 1fb2727..f595d32 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m @@ -25,23 +25,22 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation 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); - MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init]; textureDescriptor.pixelFormat = convertedFormat; textureDescriptor.width = presentationInfo.imageSize.x; textureDescriptor.height = presentationInfo.imageSize.y; - textureDescriptor.usage = MTLTextureUsageRenderTarget; + textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; textureDescriptor.textureType = MTLTextureType2D; presentationQueue->imageCount = presentationInfo.minImageCount; presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount); + presentationQueue->presentationQueue->textures = metalTextureArrayListCreate(); for (int i = 0; i < presentationInfo.minImageCount; i++) { - presentationQueue->presentationQueue->textures[i] = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor]; presentationQueue->images[i] = malloc(sizeof(struct gnTexture_t)); presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture)); - presentationQueue->images[i]->texture->texture = presentationQueue->presentationQueue->textures[i]; + presentationQueue->images[i]->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor]; + metalTextureArrayListAdd(&presentationQueue->presentationQueue->textures, presentationQueue->images[i]->texture->texture); + uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, i); } return GN_SUCCESS; @@ -49,16 +48,17 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex) { semaphore->semaphore->eventTriggered = gnFalse; - *imageIndex = presentationQueue->presentationQueue->currentImage; - presentationQueue->presentationQueue->currentImage++; - presentationQueue->presentationQueue->currentImage %= presentationQueue->imageCount; + while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {} + *imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0]; + uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures); semaphore->semaphore->eventTriggered = gnTrue; return GN_SUCCESS; } void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) { - for (int i = 0; i < presentationQueue->imageCount; i++) { - [presentationQueue->presentationQueue->textures[i] release]; - } + free(presentationQueue->presentationQueue->avaliableTextures.data); + presentationQueue->presentationQueue->avaliableTextures.count = 0; + for (int i = 0; i < presentationQueue->imageCount; i++) + [presentationQueue->images[i]->texture->texture release]; free(presentationQueue->presentationQueue); } 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 a231a60..6756043 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.m +++ b/projects/apis/metal/src/shader_module/metal_shader_module.m @@ -137,8 +137,6 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS return GN_FAILED_TO_FIND_ENTRY_POINT; } - printf("%s", result); - NSString* functionName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; module->shaderModule->function = [shaderLib newFunctionWithName:functionName]; diff --git a/projects/apis/metal/src/submit/metal_submit.m b/projects/apis/metal/src/submit/metal_submit.m index d5e7a04..057a761 100644 --- a/projects/apis/metal/src/submit/metal_submit.m +++ b/projects/apis/metal/src/submit/metal_submit.m @@ -15,8 +15,8 @@ gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) { for (int c = 0; c < semsToSignalCount; c++) { semsToSignal[c]->semaphore->eventTriggered = gnTrue; } + fenceToSignal->signaled = gnTrue; }]; - fenceToSignal->signaled = gnTrue; [commandBuffer commit]; } diff --git a/projects/apis/metal/src/surface/metal_surface.m b/projects/apis/metal/src/surface/metal_surface.m index ab890f5..0e5c8d2 100644 --- a/projects/apis/metal/src/surface/metal_surface.m +++ b/projects/apis/metal/src/surface/metal_surface.m @@ -27,7 +27,6 @@ gnSurfaceDetails getMetalSurfaceDetails( surfaceDetails.minImageCount = 2; surfaceDetails.maxImageCount = 3; CGSize size = windowSurface->windowSurface->layer.drawableSize; - printf("Size: %f %f\n", size.width, size.height); surfaceDetails.minImageSize = surfaceDetails.maxImageSize = surfaceDetails.currentSize = (gnUInt2){size.width, size.height}; return surfaceDetails; } diff --git a/projects/apis/metal/src/texture/metal_texture.m b/projects/apis/metal/src/texture/metal_texture.m index 553079a..4f8282a 100644 --- a/projects/apis/metal/src/texture/metal_texture.m +++ b/projects/apis/metal/src/texture/metal_texture.m @@ -8,6 +8,7 @@ gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnText 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; diff --git a/projects/platform/platform_macos/gryphn_platform_macos.h b/projects/platform/platform_macos/gryphn_platform_macos.h index cc4a60a..79e7d9e 100644 --- a/projects/platform/platform_macos/gryphn_platform_macos.h +++ b/projects/platform/platform_macos/gryphn_platform_macos.h @@ -15,6 +15,7 @@ typedef void MTKView; // MTKView* gnCreateMTKView(NSWindow* window); // void gnWindowSetMTKView(NSWindow* window, MTKView* view); CAMetalLayer* gnCreateCAMetalLayer(NSWindow* window); +void gnResizeCAMetalLayer(NSWindow* window); // CAMetalLayer* gnGetCAMetalLayer(NSWindow* window); // void gnAttachMetalLayer(NSWindow* window, CAMetalLayer* layer); diff --git a/projects/platform/platform_macos/gryphn_platform_macos.m b/projects/platform/platform_macos/gryphn_platform_macos.m index bd075df..5a07556 100644 --- a/projects/platform/platform_macos/gryphn_platform_macos.m +++ b/projects/platform/platform_macos/gryphn_platform_macos.m @@ -24,12 +24,22 @@ CAMetalLayer* gnCreateCAMetalLayer(NSWindow* window) { [view setLayer:layer]; [view setWantsLayer:YES]; CGSize viewSize = view.bounds.size; - CGFloat scale = view.window.screen.backingScaleFactor; + CGFloat scale = window.screen.backingScaleFactor; layer.drawableSize = CGSizeMake(viewSize.width * scale, viewSize.height * scale); return layer; } +void gnResizeCAMetalLayer(NSWindow* window) { + CAMetalLayer* layer = (CAMetalLayer*)window.contentView.layer; + + CGSize viewSize = window.contentView.bounds.size; + CGFloat scale = window.screen.backingScaleFactor; + layer.drawableSize = CGSizeMake(viewSize.width * scale, + viewSize.height * scale); + +} + // CAMetalLayer* gnGetCAMetalLayer(NSWindow* window) { // return (CAMetalLayer*)window.contentView.layer; // } diff --git a/projects/utils b/projects/utils index 48701d9..b2a96ba 160000 --- a/projects/utils +++ b/projects/utils @@ -1 +1 @@ -Subproject commit 48701d9931ca4b137601315c3551d395d9e3d6d9 +Subproject commit b2a96ba8e198d20bc14f5c1cc889033f392ae4d2