redo presentation queue waiting

This commit is contained in:
Greg Wells
2025-07-11 14:02:55 -04:00
parent 04a19fce18
commit 2def510f69
5 changed files with 52 additions and 12 deletions

View File

@@ -1,8 +1,10 @@
#include "metal_present.h" #include "metal_present.h"
#include <synchronization/commands/gryphn_sync_present.h> #include <synchronization/commands/gryphn_sync_present.h>
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { #include "stdio.h"
#include "time.h"
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];
@@ -34,7 +36,7 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
device->outputDevice->executingCommandBuffer = commandBuffer; device->outputDevice->executingCommandBuffer = commandBuffer;
} }
[device->outputDevice->executingCommandBuffer waitUntilScheduled]; [device->outputDevice->executingCommandBuffer waitUntilCompleted];
for (int i = 0; i < info.presentationQueueCount; i++) { for (int i = 0; i < info.presentationQueueCount; i++) {
if (info.presentationQueues[i]->info.imageSize.x != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.width || if (info.presentationQueues[i]->info.imageSize.x != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.width ||
@@ -46,11 +48,14 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
return GN_SUCCESS; return GN_SUCCESS;
} }
gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info) { gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info) {
clock_t begin = clock();
for (int i = 0; i < info.waitCount; i++) { for (int i = 0; i < info.waitCount; i++) {
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {} while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
} }
clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("time spent waiting to present: %lf\n", time_spent);
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;
@@ -62,7 +67,7 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf
id<MTLCommandBuffer> commandBuffer = [device->outputDevice->transferQueue commandBuffer]; id<MTLCommandBuffer> commandBuffer = [device->outputDevice->transferQueue commandBuffer];
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) { [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex); mtlAddImageBackToQueue(presentationQueue, imageIndex);
}]; }];
id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder]; id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder];
@@ -83,7 +88,7 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf
device->outputDevice->executingCommandBuffer = commandBuffer; device->outputDevice->executingCommandBuffer = commandBuffer;
} }
[device->outputDevice->executingCommandBuffer waitUntilScheduled]; // [device->outputDevice->executingCommandBuffer waitUntilScheduled];
for (int i = 0; i < info.presentationQueueCount; i++) { for (int i = 0; i < info.presentationQueueCount; i++) {
if (info.presentationQueues[i]->info.imageSize.x != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.width || if (info.presentationQueues[i]->info.imageSize.x != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.width ||

View File

@@ -5,12 +5,22 @@
typedef id<MTLTexture> metalTexture; typedef id<MTLTexture> metalTexture;
GN_ARRAY_LIST(metalTexture); GN_ARRAY_LIST(metalTexture);
typedef struct mtlImageNeeded {
gnSemaphore semaphoreToSignal;
uint32_t* whereToPut;
} mtlImageNeeded;
GN_ARRAY_LIST(mtlImageNeeded);
typedef struct gnPlatformPresentationQueue_t { typedef struct gnPlatformPresentationQueue_t {
metalTextureArrayList textures; metalTextureArrayList textures;
uint32_tArrayList avaliableTextures; uint32_tArrayList avaliableTextures;
mtlImageNeededArrayList neededImages;
} gnPlatformPresentationQueue; } gnPlatformPresentationQueue;
gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo); gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo);
gnReturnCode getMetalPresentQueueImageAsync(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); gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex);
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue); void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue);
void mtlAddImageBackToQueue(gnPresentationQueue queue, uint32_t index);

View File

@@ -48,18 +48,35 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation
return GN_SUCCESS; return GN_SUCCESS;
} }
void mtlTakeImageFromQueue(uint32_t* whereToPut, gnPresentationQueue queue, gnSemaphore semaphore) {
*whereToPut = queue->presentationQueue->avaliableTextures.data[0];
uint32_tArrayListPopHead(&queue->presentationQueue->avaliableTextures);
if (semaphore) semaphore->semaphore->eventTriggered = gnTrue;
}
void mtlAddImageBackToQueue(gnPresentationQueue queue, uint32_t index) {
if (queue->presentationQueue->neededImages.count > 0)
mtlTakeImageFromQueue(queue->presentationQueue->neededImages.data[queue->presentationQueue->neededImages.count - 1].whereToPut, queue, queue->presentationQueue->neededImages.data[queue->presentationQueue->neededImages.count - 1].semaphoreToSignal);
else
uint32_tArrayListAdd(&queue->presentationQueue->avaliableTextures, index);
}
gnReturnCode getMetalPresentQueueImageAsync(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) {} if (presentationQueue->presentationQueue->avaliableTextures.count == 0) {
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0]; mtlImageNeeded image = {
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures); .semaphoreToSignal = semaphore,
semaphore->semaphore->eventTriggered = gnTrue; .whereToPut = imageIndex
};
mtlImageNeededArrayListAdd(&presentationQueue->presentationQueue->neededImages, image);
} else {
mtlTakeImageFromQueue(imageIndex, presentationQueue, semaphore);
}
return GN_SUCCESS; return GN_SUCCESS;
} }
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex) { gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex) {
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {} while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {}
*imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0]; mtlTakeImageFromQueue(imageIndex, presentationQueue, NULL);
uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures);
return GN_SUCCESS; return GN_SUCCESS;
} }

View File

@@ -1,10 +1,18 @@
#include "metal_submit.h" #include "metal_submit.h"
#include "synchronization/fence/gryphn_fence.h" #include "synchronization/fence/gryphn_fence.h"
#include "stdio.h"
#include "time.h"
gnReturnCode metalSyncSubmit(gnOutputDevice device, gnSubmitSyncInfo info) { gnReturnCode metalSyncSubmit(gnOutputDevice device, gnSubmitSyncInfo info) {
clock_t begin = clock();
for (int i = 0; i < info.waitCount; i++) { for (int i = 0; i < info.waitCount; i++) {
while (!info.waitSemaphores[i]->semaphore->eventTriggered) {} while (!info.waitSemaphores[i]->semaphore->eventTriggered) {}
} }
clock_t end = clock();
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("time spent waiting for image in submit: %lf\n", time_spent);
__block gnSemaphore* semsToSignal = info.signalSemaphores; __block gnSemaphore* semsToSignal = info.signalSemaphores;
__block int semsToSignalCount = info.signalCount; __block int semsToSignalCount = info.signalCount;