metal sync extension

This commit is contained in:
Greg Wells
2025-07-09 21:37:22 -04:00
parent 8d0b9ce8bd
commit 7d22da040a
14 changed files with 109 additions and 21 deletions

View File

@@ -30,12 +30,13 @@ gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCou
.queueType = GN_QUEUE_GRAPHICS | GN_QUEUE_COMPUTE | GN_QUEUE_TRANSFER
};
if ([device supportsTextureSampleCount:1]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_1; }
if ([device supportsTextureSampleCount:2]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_2; }
if ([device supportsTextureSampleCount:4]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_4; }
if ([device supportsTextureSampleCount:8]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_8; }
if ([device supportsTextureSampleCount:16]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_16; }
if ([device supportsTextureSampleCount:32]) { devicesList[i].features.avaliableSamples |= GN_SAMPLE_BIT_32; }
if ([device supportsTextureSampleCount:1]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_1; }
if ([device supportsTextureSampleCount:2]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_2; }
if ([device supportsTextureSampleCount:4]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_4; }
if ([device supportsTextureSampleCount:8]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_8; }
if ([device supportsTextureSampleCount:16]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_16; }
if ([device supportsTextureSampleCount:32]) { devicesList[i].features.maxColorSamples |= GN_SAMPLE_BIT_32; }
devicesList[i].features.maxDepthSamples = devicesList[i].features.maxColorSamples;
devicesList[i].features.maxMemoryAllocations = 0x40000000;
devicesList[i].features.maxPushConstantSize = 4096;

View File

@@ -8,4 +8,5 @@
#include "texture/metal_texture.h"
#import <QuartzCore/CAMetalLayer.h>
gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info);
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info);

View File

@@ -1,6 +1,53 @@
#include "metal_present.h"
#include <synchronization/commands/gryphn_sync_present.h>
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<CAMetalDrawable> drawable = [info.presentationQueues[i]->info.surface->windowSurface->layer nextDrawable];
if (drawable == nil) 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];
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex);
}];
id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder];
[blit copyFromTexture:info.presentationQueues[i]->images[info.imageIndices[i]]->texture->texture
sourceSlice:0
sourceLevel:0
sourceOrigin:(MTLOrigin){0, 0, 0}
sourceSize:(MTLSize){info.presentationQueues[i]->info.imageSize.x, info.presentationQueues[i]->info.imageSize.y, 1}
toTexture:drawable.texture
destinationSlice:0
destinationLevel:0
destinationOrigin:(MTLOrigin){0, 0, 0}];
[blit endEncoding];
[commandBuffer presentDrawable:drawable];
[commandBuffer commit];
device->outputDevice->executingCommandBuffer = commandBuffer;
}
[device->outputDevice->executingCommandBuffer waitUntilScheduled];
for (int i = 0; i < info.presentationQueueCount; i++) {
if (info.presentationQueues[i]->info.imageSize.x != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.width ||
info.presentationQueues[i]->info.imageSize.y != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.height) {
return GN_SUBOPTIMAL_PRESENTATION_QUEUE;
}
}
return GN_SUCCESS;
}
gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info) {
for (int i = 0; i < info.waitCount; i++) {
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
}

View File

@@ -11,5 +11,6 @@ typedef struct gnPlatformPresentationQueue_t {
} gnPlatformPresentationQueue;
gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo);
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex);
gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex);
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex);
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue);

View File

@@ -48,7 +48,7 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation
return GN_SUCCESS;
}
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex) {
gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex) {
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0];
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
@@ -56,6 +56,13 @@ gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQue
return GN_SUCCESS;
}
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex) {
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0];
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
return GN_SUCCESS;
}
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) {
free(presentationQueue->presentationQueue->avaliableTextures.data);
presentationQueue->presentationQueue->avaliableTextures.count = 0;

View File

@@ -3,6 +3,7 @@
#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 "synchronization/commands/gryphn_sync_submit.h"
gnReturnCode metalSyncSubmit(gnOutputDevice device, gnSubmitSyncInfo info);
gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info);

View File

@@ -1,6 +1,7 @@
#include "metal_submit.h"
#include "synchronization/fence/gryphn_fence.h"
gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
gnReturnCode metalSyncSubmit(gnOutputDevice device, gnSubmitSyncInfo info) {
for (int i = 0; i < info.waitCount; i++) {
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
}
@@ -23,3 +24,13 @@ gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
return GN_SUCCESS;
}
gnReturnCode metalSubmit(gnOutputDevice device, gnSubmitInfo info) {
for (int i = 0; i < info.commandBufferCount; i++) {
id<MTLCommandBuffer> commandBuffer = info.commandBuffers[i]->commandBuffer->commandBuffer;
[commandBuffer commit];
}
[info.commandBuffers[info.commandBufferCount - 1]->commandBuffer->commandBuffer waitUntilCompleted];
return GN_SUCCESS;
}

View File

@@ -1,5 +1,5 @@
#pragma once
#include "sync/fence/gryphn_fence.h"
#include "synchronization/fence/gryphn_fence.h"
#import <Metal/Metal.h>
#import <Metal/MTLEvent.h>

View File

@@ -1,5 +1,5 @@
#pragma once
#include "sync/semaphore/gryphn_semaphore.h"
#include "synchronization/semaphore/gryphn_semaphore.h"
#import <Metal/MTLEvent.h>
typedef struct gnPlatformSemaphore_t {