fix some bugs on macos and improve presentation queue

This commit is contained in:
Greg Wells
2025-07-01 16:15:43 -04:00
parent 4c7fe77db3
commit 504603e5ac
11 changed files with 41 additions and 36 deletions

View File

@@ -100,9 +100,8 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn
} }
MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init]; MTLDepthStencilDescriptor* depthStencilDesc = [[MTLDepthStencilDescriptor alloc] init];
depthStencilDesc.depthWriteEnabled = info.depthStencil.depthWriteEnable, depthStencilDesc.depthWriteEnabled = info.depthStencil.depthWriteEnable;
depthStencilDesc.depthCompareFunction = info.depthStencil.depthWriteEnable, depthStencilDesc.depthCompareFunction = MTLCompareFunctionLess;
depthStencilDesc.depthCompareFunction = mtlGrypnCompareOperation(info.depthStencil.operation),
graphicsPipeline->graphicsPipeline->depthState = [device->outputDevice->device newDepthStencilStateWithDescriptor:depthStencilDesc]; graphicsPipeline->graphicsPipeline->depthState = [device->outputDevice->device newDepthStencilStateWithDescriptor:depthStencilDesc];

View File

@@ -8,19 +8,15 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
for (int i =0 ; i < info.presentationQueueCount; i++) { for (int i =0 ; i < info.presentationQueueCount; i++) {
info.presentationQueues[i]->info.surface->windowSurface->layer.device = device->outputDevice->device; info.presentationQueues[i]->info.surface->windowSurface->layer.device = device->outputDevice->device;
id<CAMetalDrawable> drawable = [info.presentationQueues[i]->info.surface->windowSurface->layer nextDrawable]; id<CAMetalDrawable> drawable = [info.presentationQueues[i]->info.surface->windowSurface->layer nextDrawable];
if (drawable == nil) { if (drawable == nil) return GN_FAILED_TO_CREATE_FRAMEBUFFER;
return GN_FAILED_TO_CREATE_FRAMEBUFFER;
} __block gnPresentationQueue presentationQueue = info.presentationQueues[i];
__block uint32_t imageIndex = info.imageIndices[i];
id<MTLCommandBuffer> commandBuffer = [device->outputDevice->transferQueue commandBuffer]; id<MTLCommandBuffer> commandBuffer = [device->outputDevice->transferQueue commandBuffer];
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
MTLRenderPassDescriptor* passDesc = [MTLRenderPassDescriptor renderPassDescriptor]; uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex);
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<MTLRenderCommandEncoder> render = [commandBuffer renderCommandEncoderWithDescriptor:passDesc];
[render endEncoding];
id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder]; id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder];

View File

@@ -2,11 +2,12 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
#include "presentation_queue/gryphn_presentation_queue.h" #include "presentation_queue/gryphn_presentation_queue.h"
typedef struct gnPlatformPresentationQueue_t { typedef id<MTLTexture> metalTexture;
int textureCount; GN_ARRAY_LIST(metalTexture);
id<MTLTexture>* textures;
uint32_t currentImage; typedef struct gnPlatformPresentationQueue_t {
metalTextureArrayList textures;
uint32_tArrayList avaliableTextures;
} gnPlatformPresentationQueue; } gnPlatformPresentationQueue;
gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo); gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo);

View File

@@ -25,23 +25,22 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation
MTLPixelFormat convertedFormat = mtlGryphnFormatToMetalFormat(presentationInfo.format.format); MTLPixelFormat convertedFormat = mtlGryphnFormatToMetalFormat(presentationInfo.format.format);
CGColorSpaceRef convertedColorSpace = mtlGryphnColorSpaceToMetalColorSpace(presentationInfo.format.colorSpace); CGColorSpaceRef convertedColorSpace = mtlGryphnColorSpaceToMetalColorSpace(presentationInfo.format.colorSpace);
presentationQueue->presentationQueue->textureCount = presentationInfo.minImageCount;
presentationQueue->presentationQueue->textures = malloc(sizeof(id<MTLTexture>) * presentationInfo.minImageCount);
MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init]; MTLTextureDescriptor* textureDescriptor = [[MTLTextureDescriptor alloc] init];
textureDescriptor.pixelFormat = convertedFormat; textureDescriptor.pixelFormat = convertedFormat;
textureDescriptor.width = presentationInfo.imageSize.x; textureDescriptor.width = presentationInfo.imageSize.x;
textureDescriptor.height = presentationInfo.imageSize.y; textureDescriptor.height = presentationInfo.imageSize.y;
textureDescriptor.usage = MTLTextureUsageRenderTarget; textureDescriptor.usage = MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead;
textureDescriptor.textureType = MTLTextureType2D; textureDescriptor.textureType = MTLTextureType2D;
presentationQueue->imageCount = presentationInfo.minImageCount; presentationQueue->imageCount = presentationInfo.minImageCount;
presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount); presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount);
presentationQueue->presentationQueue->textures = metalTextureArrayListCreate();
for (int i = 0; i < presentationInfo.minImageCount; i++) { 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] = malloc(sizeof(struct gnTexture_t));
presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture)); 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; return GN_SUCCESS;
@@ -49,16 +48,17 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore 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; while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
presentationQueue->presentationQueue->currentImage++; *imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0];
presentationQueue->presentationQueue->currentImage %= presentationQueue->imageCount; uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
semaphore->semaphore->eventTriggered = gnTrue; semaphore->semaphore->eventTriggered = gnTrue;
return GN_SUCCESS; return GN_SUCCESS;
} }
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) { void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) {
for (int i = 0; i < presentationQueue->imageCount; i++) { free(presentationQueue->presentationQueue->avaliableTextures.data);
[presentationQueue->presentationQueue->textures[i] release]; presentationQueue->presentationQueue->avaliableTextures.count = 0;
} for (int i = 0; i < presentationQueue->imageCount; i++)
[presentationQueue->images[i]->texture->texture release];
free(presentationQueue->presentationQueue); free(presentationQueue->presentationQueue);
} }

View File

@@ -137,8 +137,6 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS
return GN_FAILED_TO_FIND_ENTRY_POINT; return GN_FAILED_TO_FIND_ENTRY_POINT;
} }
printf("%s", result);
NSString* functionName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; NSString* functionName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
module->shaderModule->function = [shaderLib newFunctionWithName:functionName]; module->shaderModule->function = [shaderLib newFunctionWithName:functionName];

View File

@@ -15,8 +15,8 @@ gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
for (int c = 0; c < semsToSignalCount; c++) { for (int c = 0; c < semsToSignalCount; c++) {
semsToSignal[c]->semaphore->eventTriggered = gnTrue; semsToSignal[c]->semaphore->eventTriggered = gnTrue;
} }
fenceToSignal->signaled = gnTrue;
}]; }];
fenceToSignal->signaled = gnTrue;
[commandBuffer commit]; [commandBuffer commit];
} }

View File

@@ -27,7 +27,6 @@ gnSurfaceDetails getMetalSurfaceDetails(
surfaceDetails.minImageCount = 2; surfaceDetails.minImageCount = 2;
surfaceDetails.maxImageCount = 3; surfaceDetails.maxImageCount = 3;
CGSize size = windowSurface->windowSurface->layer.drawableSize; 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}; surfaceDetails.minImageSize = surfaceDetails.maxImageSize = surfaceDetails.currentSize = (gnUInt2){size.width, size.height};
return surfaceDetails; return surfaceDetails;
} }

View File

@@ -8,6 +8,7 @@ gnReturnCode createMetalTexture(gnTexture texture, gnDevice device, const gnText
textureDescriptor.pixelFormat = mtlGryphnFormatToMetalFormat(info.format); textureDescriptor.pixelFormat = mtlGryphnFormatToMetalFormat(info.format);
textureDescriptor.width = info.width; textureDescriptor.width = info.width;
textureDescriptor.height = info.height; textureDescriptor.height = info.height;
texture->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor]; texture->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor];
[textureDescriptor release]; [textureDescriptor release];
return GN_SUCCESS; return GN_SUCCESS;

View File

@@ -15,6 +15,7 @@ typedef void MTKView;
// MTKView* gnCreateMTKView(NSWindow* window); // MTKView* gnCreateMTKView(NSWindow* window);
// void gnWindowSetMTKView(NSWindow* window, MTKView* view); // void gnWindowSetMTKView(NSWindow* window, MTKView* view);
CAMetalLayer* gnCreateCAMetalLayer(NSWindow* window); CAMetalLayer* gnCreateCAMetalLayer(NSWindow* window);
void gnResizeCAMetalLayer(NSWindow* window);
// CAMetalLayer* gnGetCAMetalLayer(NSWindow* window); // CAMetalLayer* gnGetCAMetalLayer(NSWindow* window);
// void gnAttachMetalLayer(NSWindow* window, CAMetalLayer* layer); // void gnAttachMetalLayer(NSWindow* window, CAMetalLayer* layer);

View File

@@ -24,12 +24,22 @@ CAMetalLayer* gnCreateCAMetalLayer(NSWindow* window) {
[view setLayer:layer]; [view setLayer:layer];
[view setWantsLayer:YES]; [view setWantsLayer:YES];
CGSize viewSize = view.bounds.size; CGSize viewSize = view.bounds.size;
CGFloat scale = view.window.screen.backingScaleFactor; CGFloat scale = window.screen.backingScaleFactor;
layer.drawableSize = CGSizeMake(viewSize.width * scale, layer.drawableSize = CGSizeMake(viewSize.width * scale,
viewSize.height * scale); viewSize.height * scale);
return layer; 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) { // CAMetalLayer* gnGetCAMetalLayer(NSWindow* window) {
// return (CAMetalLayer*)window.contentView.layer; // return (CAMetalLayer*)window.contentView.layer;
// } // }