metal queue submission

This commit is contained in:
Greg Wells
2025-05-31 06:14:33 -04:00
parent eb244447cc
commit 0d02d2e8fc
15 changed files with 120 additions and 35 deletions

View File

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

View File

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

View File

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

View File

@@ -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 <QuartzCore/CAMetalLayer.h>
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<CAMetalDrawable> drawable = [info.presentationQueues->info.surface.windowSurface->layer nextDrawable];
id<MTLCommandBuffer> 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<MTLRenderCommandEncoder> render = [commandBuffer renderCommandEncoderWithDescriptor:passDesc];
[render endEncoding];
[commandBuffer presentDrawable:drawable];
[commandBuffer commit];
return GN_SUCCESS;
}

View File

@@ -5,4 +5,6 @@
typedef struct gnPlatformPresentationQueue_t {
int textureCount;
id<MTLTexture>* textures;
uint32_t currentImage;
} gnPlatformPresentationQueue;

View File

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

View File

@@ -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<MTLCommandBuffer> commandBuffer = info.commandBuffers[i].commandBuffer->commandBuffer;
[info.commandBuffers[i].commandBuffer->commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
for (int c = 0; c < semsToSignalCount; c++) {
semsToSignal[c].semaphore->eventTriggered = gnTrue;
}
}];
[commandBuffer commit];
}
return GN_SUCCESS;
}

View File

@@ -3,6 +3,7 @@
#import <QuartzCore/QuartzCore.h>
typedef struct gnPlatformWindowSurface_t{
CAMetalLayer* layer;
} gnPlatformWindowSurface;

View File

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

View File

@@ -4,7 +4,5 @@
#import <Metal/MTLEvent.h>
typedef struct gnPlatformFence_t {
id<MTLSharedEvent> fence;
MTLSharedEventListener* listener;
dispatch_semaphore_t semaphore;
} gnPlatformFence;

View File

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

View File

@@ -4,4 +4,5 @@
typedef struct gnPlatformSemaphore_t {
id<MTLEvent> event;
gnBool eventTriggered;
} gnPlatformSemaphore;

View File

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

View File

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

View File

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