diff --git a/projects/apis/metal/src/present/metal_present.m b/projects/apis/metal/src/present/metal_present.m index c6561cf..d36d4b7 100644 --- a/projects/apis/metal/src/present/metal_present.m +++ b/projects/apis/metal/src/present/metal_present.m @@ -1,8 +1,10 @@ #include "metal_present.h" #include -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++) { info.presentationQueues[i]->info.surface->windowSurface->layer.device = device->outputDevice->device; id 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 waitUntilScheduled]; + [device->outputDevice->executingCommandBuffer waitUntilCompleted]; for (int i = 0; i < info.presentationQueueCount; i++) { 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; } - gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info) { + clock_t begin = clock(); for (int i = 0; i < info.waitCount; i++) { 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++) { info.presentationQueues[i]->info.surface->windowSurface->layer.device = device->outputDevice->device; @@ -62,7 +67,7 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf id commandBuffer = [device->outputDevice->transferQueue commandBuffer]; [commandBuffer addCompletedHandler:^(id buffer) { - uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex); + mtlAddImageBackToQueue(presentationQueue, imageIndex); }]; id blit = [commandBuffer blitCommandEncoder]; @@ -83,7 +88,7 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf device->outputDevice->executingCommandBuffer = commandBuffer; } - [device->outputDevice->executingCommandBuffer waitUntilScheduled]; + // [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 || 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 e38301f..71ae2e7 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h @@ -5,12 +5,22 @@ typedef id metalTexture; GN_ARRAY_LIST(metalTexture); +typedef struct mtlImageNeeded { + gnSemaphore semaphoreToSignal; + uint32_t* whereToPut; +} mtlImageNeeded; +GN_ARRAY_LIST(mtlImageNeeded); + typedef struct gnPlatformPresentationQueue_t { metalTextureArrayList textures; uint32_tArrayList avaliableTextures; + + mtlImageNeededArrayList neededImages; } gnPlatformPresentationQueue; gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentationQueue, const gnDevice device, gnPresentationQueueInfo presentationInfo); gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex); gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex); void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue); + +void mtlAddImageBackToQueue(gnPresentationQueue queue, uint32_t index); 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 464de7b..c7e135f 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m @@ -48,18 +48,35 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation 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) { - while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {} - *imageIndex = presentationQueue->presentationQueue->avaliableTextures.data[0]; - uint32_tArrayListPopHead(&presentationQueue->presentationQueue->avaliableTextures); - semaphore->semaphore->eventTriggered = gnTrue; + if (presentationQueue->presentationQueue->avaliableTextures.count == 0) { + mtlImageNeeded image = { + .semaphoreToSignal = semaphore, + .whereToPut = imageIndex + }; + mtlImageNeededArrayListAdd(&presentationQueue->presentationQueue->neededImages, image); + } else { + mtlTakeImageFromQueue(imageIndex, presentationQueue, semaphore); + } 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); + mtlTakeImageFromQueue(imageIndex, presentationQueue, NULL); return GN_SUCCESS; } diff --git a/projects/apis/metal/src/submit/metal_submit.m b/projects/apis/metal/src/submit/metal_submit.m index 9532405..4cd54ab 100644 --- a/projects/apis/metal/src/submit/metal_submit.m +++ b/projects/apis/metal/src/submit/metal_submit.m @@ -1,10 +1,18 @@ #include "metal_submit.h" #include "synchronization/fence/gryphn_fence.h" +#include "stdio.h" +#include "time.h" + + gnReturnCode metalSyncSubmit(gnOutputDevice device, gnSubmitSyncInfo info) { + clock_t begin = clock(); for (int i = 0; i < info.waitCount; i++) { 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 int semsToSignalCount = info.signalCount; diff --git a/projects/utils b/projects/utils index d84bbb9..ef81554 160000 --- a/projects/utils +++ b/projects/utils @@ -1 +1 @@ -Subproject commit d84bbb9b05c5aaa10a05bbf71347fb87fb392c14 +Subproject commit ef815541c7b6d0126c5d639ffdaa555ac41b426d