diff --git a/projects/apis/metal/src/buffer/metal_buffer.m b/projects/apis/metal/src/buffer/metal_buffer.m index 4546a02..2968e48 100644 --- a/projects/apis/metal/src/buffer/metal_buffer.m +++ b/projects/apis/metal/src/buffer/metal_buffer.m @@ -17,9 +17,8 @@ void metalBufferData(gnBufferHandle buffer, size_t dataSize, void* data) { metalBufferSubData(buffer, 0, dataSize, data); } void metalBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) { - void* bufferData; if (buffer->buffer->useStagingBuffer) { - memcpy(buffer->buffer->stagingBuffer.contents + offset, data, dataSize); + memcpy((char*)buffer->buffer->stagingBuffer.contents + offset, data, dataSize); id commandBuffer = [buffer->device->outputDevice->transferQueue commandBuffer]; id encoder = [commandBuffer blitCommandEncoder]; [encoder copyFromBuffer:buffer->buffer->stagingBuffer sourceOffset:0 toBuffer:buffer->buffer->buffer destinationOffset:0 size:dataSize]; @@ -27,7 +26,7 @@ void metalBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, g [commandBuffer commit]; [commandBuffer waitUntilCompleted]; } else - memcpy(buffer->buffer->buffer.contents + offset, data, dataSize); + memcpy((char*)buffer->buffer->buffer.contents + offset, data, dataSize); } void* mapMetalBuffer(gnBufferHandle buffer) { return buffer->buffer->buffer.contents; diff --git a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m index 45aa493..84fcb7b 100644 --- a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m +++ b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.m @@ -4,7 +4,7 @@ #import gnReturnCode allocateMetalCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPool pool) { - for (int i = 0; i < count; i++) { + for (uint32_t i = 0; i < count; i++) { commandBuffers[i]->commandBuffer = malloc(sizeof(gnPlatformCommandBuffer)); commandBuffers[i]->commandBuffer->commandBuffer = [pool->commandPool->commandQueue commandBuffer]; @@ -25,7 +25,7 @@ gnReturnCode beginMetalCommandBuffer(gnCommandBuffer commandBuffer) { return GN_SUCCESS; } -gnReturnCode endMetalCommandBuffer(gnCommandBuffer commandBuffer) { return GN_SUCCESS; } +gnReturnCode endMetalCommandBuffer(gnCommandBuffer commandBuffer) { if (commandBuffer == GN_NULL_HANDLE) return GN_INVALID_HANDLE; return GN_SUCCESS; } void destroyMetalCommandBuffer(gnCommandBuffer commandBuffer) { [commandBuffer->commandBuffer->commandBuffer release]; diff --git a/projects/apis/metal/src/commands/command_pool/metal_command_pool.m b/projects/apis/metal/src/commands/command_pool/metal_command_pool.m index 95c3bd4..5432cee 100644 --- a/projects/apis/metal/src/commands/command_pool/metal_command_pool.m +++ b/projects/apis/metal/src/commands/command_pool/metal_command_pool.m @@ -2,6 +2,7 @@ #include "devices/metal_output_devices.h" gnReturnCode createMetalCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info) { + info.flags = 0; commandPool->commandPool = malloc(sizeof(struct gnPlatformCommandPool_t)); commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue]; diff --git a/projects/apis/metal/src/commands/commands/metal_commands.m b/projects/apis/metal/src/commands/commands/metal_commands.m index 6facd54..eb5a750 100644 --- a/projects/apis/metal/src/commands/commands/metal_commands.m +++ b/projects/apis/metal/src/commands/commands/metal_commands.m @@ -4,8 +4,7 @@ #include "utils/math/gryphn_math.h" void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) { - int currentColorAttachment = 0; - for (int i = 0; i < passInfo.clearValueCount; i++) { + for (uint32_t i = 0; i < passInfo.clearValueCount; i++) { if (passInfo.framebuffer->framebuffer->clearCopies[i].clear) { MTLRenderPassColorAttachmentDescriptor* color = passInfo.framebuffer->framebuffer->clearCopies[i].descriptor; color.clearColor = MTLClearColorMake( @@ -14,7 +13,6 @@ void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) { passInfo.clearValues[i].b, passInfo.clearValues[i].a ); - currentColorAttachment++; } } buffer->commandBuffer->encoder = [buffer->commandBuffer->commandBuffer renderCommandEncoderWithDescriptor:passInfo.framebuffer->framebuffer->subpasses[0]]; @@ -98,7 +96,7 @@ void metalDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexC indexCount:indexCount indexType:((type == GN_UINT32) ? MTLIndexTypeUInt32 : MTLIndexTypeUInt16) indexBuffer:buffer->commandBuffer->indexBuffer->buffer->buffer - indexBufferOffset:0 + indexBufferOffset:firstIndex instanceCount:instanceCount baseVertex:vertexOffset baseInstance:firstInstance @@ -111,7 +109,7 @@ void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t [encoder useResources:uniform->uniform->usedResources count:uniform->uniform->usedResourceCount usage:MTLResourceUsageRead stages:MTLRenderStageVertex | MTLRenderStageFragment]; int startIndex = 0; - for (int i = 0; i < dynamicOffsetCount; i++) { + for (uint32_t i = 0; i < dynamicOffsetCount; i++) { int c = startIndex; for (; c < MAX_METAL_BINDINGS; c++) { if (uniform->uniform->isDynamic[c]) { diff --git a/projects/apis/metal/src/devices/metal_output_device.m b/projects/apis/metal/src/devices/metal_output_device.m index 6ca3ae9..329e054 100644 --- a/projects/apis/metal/src/devices/metal_output_device.m +++ b/projects/apis/metal/src/devices/metal_output_device.m @@ -5,6 +5,8 @@ #include "instance/gryphn_instance.h" gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle outputDevice, gnOutputDeviceInfo deviceInfo) { + if (instance == GN_NULL_HANDLE) return GN_INVALID_HANDLE; + outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice)); outputDevice->outputDevice->device = deviceInfo.physicalDevice->physicalDevice->device.retain; outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue; diff --git a/projects/apis/metal/src/devices/metal_physical_device.m b/projects/apis/metal/src/devices/metal_physical_device.m index e7d18c6..7b52339 100644 --- a/projects/apis/metal/src/devices/metal_physical_device.m +++ b/projects/apis/metal/src/devices/metal_physical_device.m @@ -4,10 +4,12 @@ #include "window_surface/gryphn_surface.h" gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount) { + if (instance == GN_NULL_HANDLE) return NULL; + NSArray *devices = MTLCopyAllDevices(); *deviceCount = (uint32_t)[devices count]; gnPhysicalDevice* devicesList = (gnPhysicalDevice*)malloc(sizeof(gnPhysicalDevice) * *deviceCount); - for (int i = 0; i < *deviceCount; i++) { + for (uint32_t i = 0; i < *deviceCount; i++) { devicesList[i] = malloc(sizeof(gnPhysicalOutputDevice_t)); devicesList[i]->physicalDevice = malloc(sizeof(gnPlatformPhysicalDevice)); devicesList[i]->physicalDevice->device = [devices objectAtIndex:0]; @@ -39,5 +41,7 @@ gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCou } gnBool metalCanDevicePresent(gnPhysicalDevice device, gnWindowSurface windowSurface) { + if (device == GN_NULL_HANDLE || windowSurface == GN_NULL_HANDLE) return GN_FALSE; + return GN_TRUE; // I belive that a window should always be able to present to a surface in metal } diff --git a/projects/apis/metal/src/framebuffers/metal_framebuffer.m b/projects/apis/metal/src/framebuffers/metal_framebuffer.m index 2cf3dfd..229f6c1 100644 --- a/projects/apis/metal/src/framebuffers/metal_framebuffer.m +++ b/projects/apis/metal/src/framebuffers/metal_framebuffer.m @@ -4,25 +4,27 @@ #include "instance/gryphn_instance.h" #include "output_device/gryphn_output_device.h" #include "core/gryphn_image_format.h" + gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info) { + if (device == GN_NULL_HANDLE) return GN_INVALID_HANDLE; framebuffer->framebuffer = malloc(sizeof(struct gnPlatformFramebuffer_t)); framebuffer->framebuffer->clearCopyCount = info.attachmentCount; framebuffer->framebuffer->clearCopies = malloc(sizeof(mtlClearCopy) * info.attachmentCount); - for (int i = 0; i < info.attachmentCount; i++) { + for (uint32_t i = 0; i < info.attachmentCount; i++) { framebuffer->framebuffer->clearCopies[i].clear = GN_FALSE; } framebuffer->framebuffer->subpassCount = info.renderPassDescriptor->renderPassDescriptor->subpassCount; framebuffer->framebuffer->subpasses = malloc(sizeof(mtlSubpass) * framebuffer->framebuffer->subpassCount); framebuffer->framebuffer->depthAttachmentIndicies = malloc(sizeof(uint32_t) * framebuffer->framebuffer->subpassCount); - for (int i = 0; i < framebuffer->framebuffer->subpassCount; i++) { + for (uint32_t i = 0; i < framebuffer->framebuffer->subpassCount; i++) { framebuffer->framebuffer->subpasses[i] = [info.renderPassDescriptor->renderPassDescriptor->subpasses[i] copy]; MTLRenderPassDescriptor* pass = framebuffer->framebuffer->subpasses[i]; [pass setRenderTargetWidth:info.size.x]; [pass setRenderTargetHeight:info.size.y]; - for (int c = 0; c < info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].colorAttachmentCount; c++) { + for (uint32_t c = 0; c < info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].colorAttachmentCount; c++) { MTLRenderPassColorAttachmentDescriptor* colorPass = pass.colorAttachments[c]; colorPass.texture = info.attachments[info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].colorAttachments[c].attachmentIndex]->texture->texture; if (info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].colorAttachments[c].resolveAttachmentIndex >= 0) @@ -34,20 +36,16 @@ gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice de if (info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].depthAttachmentIndex >= 0) { MTLRenderPassDepthAttachmentDescriptor* depthAttachment = framebuffer->framebuffer->subpasses[i].depthAttachment; depthAttachment.texture = info.attachments[info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].depthAttachmentIndex]->texture->texture; + MTLRenderPassStencilAttachmentDescriptor* stencilAttachment = framebuffer->framebuffer->subpasses[i].stencilAttachment; + stencilAttachment.texture = info.attachments[info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].depthAttachmentIndex]->texture->texture; } - - // if (info.attachments[i]->info.format == GN_FORMAT_D24S8_UINT || info.attachments[i]->info.format == GN_FORMAT_D32S8_UINT) { - // framebuffer->framebuffer->depthAttachmentIndicies[i] = i; - // MTLRenderPassStencilAttachmentDescriptor* stencilAttachment = framebuffer->framebuffer->subpasses[i].stencilAttachment; - // stencilAttachment.texture = info.attachments[i]->texture->texture; - // } } return GN_SUCCESS; } void destroyMetalFramebuffer(gnFramebuffer framebuffer) { - for (int i = 0; i < framebuffer->framebuffer->subpassCount; i++) [framebuffer->framebuffer->subpasses[i] release]; + for (uint32_t i = 0; i < framebuffer->framebuffer->subpassCount; i++) [framebuffer->framebuffer->subpasses[i] release]; free(framebuffer->framebuffer->subpasses); free(framebuffer->framebuffer); } diff --git a/projects/apis/metal/src/instance/metal_instance.m b/projects/apis/metal/src/instance/metal_instance.m index f94802b..3c93422 100644 --- a/projects/apis/metal/src/instance/metal_instance.m +++ b/projects/apis/metal/src/instance/metal_instance.m @@ -2,9 +2,13 @@ // metal instances are kinda useless gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next) { - if (instance->instance == NULL) instance->instance = malloc(sizeof(gnPlatformInstance)); + if (next != NULL) return GN_SUCCESS; + + if (instanceInfo == NULL) return GN_INCOMPLETE; + instance->instance = malloc(sizeof(gnPlatformInstance)); return GN_SUCCESS; } void metalDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next) { + if (next != NULL) return; free(instance->instance); } diff --git a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m index 73f447e..079901d 100644 --- a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m +++ b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.m @@ -50,8 +50,6 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn mtlSubpass subpass = info.renderPassDescriptor->renderPassDescriptor->subpasses[info.subpassIndex]; mtlSubpassCopyInfo copyInfo = info.renderPassDescriptor->renderPassDescriptor->copyInfos[info.subpassIndex]; for (uint32_t i = 0; i < copyInfo.colorAttachmentCount; i++) { - MTLRenderPassColorAttachmentDescriptor* colorPass = subpass.colorAttachments[i]; - descriptor.colorAttachments[i].pixelFormat = copyInfo.colorAttachments[i].format; if (info.colorBlending.enable == GN_TRUE) { [descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = YES; @@ -72,7 +70,7 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn } } - for (int i = 0; i < info.shaderModuleCount; i++) { + for (uint32_t i = 0; i < info.shaderModuleCount; i++) { const char* shaderCode = mtlCompilerShader(info.shaderModules[i]->shaderModule->compiler, &info.uniformLayout); // printf("shader code: %s\n", shaderCode); @@ -95,7 +93,7 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn if (strcmp(name, "main") == 0) name = "main0"; gnBool foundFunction = false; - for (int i = 0; i < shaderLib.functionNames.count; i++) { + for (uint32_t i = 0; i < shaderLib.functionNames.count; i++) { if (strcmp([shaderLib.functionNames objectAtIndex:0].UTF8String, name) == 0) { foundFunction = true; break; @@ -114,9 +112,9 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn MTLVertexBufferLayoutDescriptorArray* buffers = vertexDescriptor.layouts; int k = 0; - for (int i = 0; i < info.shaderInputLayout.bufferCount; i++) { + for (uint32_t i = 0; i < info.shaderInputLayout.bufferCount; i++) { [[buffers objectAtIndexedSubscript:info.shaderInputLayout.bufferAttributes[i].binding] setStride:info.shaderInputLayout.bufferAttributes[i].size]; - for (int j = 0; j < info.shaderInputLayout.bufferAttributes[i].attributeCount; j++) { + for (uint32_t j = 0; j < info.shaderInputLayout.bufferAttributes[i].attributeCount; j++) { attributes[k].bufferIndex = i; attributes[k].offset = info.shaderInputLayout.bufferAttributes[i].attributes[j].offset; attributes[k].format = mtlGryphnVertexFormat(info.shaderInputLayout.bufferAttributes[i].attributes[j].format); diff --git a/projects/apis/metal/src/present/metal_present.m b/projects/apis/metal/src/present/metal_present.m index 88ab6ad..06d00a4 100644 --- a/projects/apis/metal/src/present/metal_present.m +++ b/projects/apis/metal/src/present/metal_present.m @@ -1,11 +1,10 @@ #include "metal_present.h" #include -#include "stdio.h" #include "time.h" gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { - for (int i =0 ; i < info.presentationQueueCount; i++) { + for (uint32_t 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]; if (drawable == nil) return GN_UNKNOWN_ERROR; @@ -15,7 +14,8 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { id commandBuffer = [device->outputDevice->transferQueue commandBuffer]; [commandBuffer addCompletedHandler:^(id buffer) { - uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex); + if (buffer == nil) return; + uint32_tArrayListAdd(presentationQueue->presentationQueue->avaliableTextures, imageIndex); }]; id blit = [commandBuffer blitCommandEncoder]; @@ -40,7 +40,7 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { [device->outputDevice->executingCommandBuffer waitUntilCompleted]; - for (int i = 0; i < info.presentationQueueCount; i++) { + for (uint32_t 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; @@ -51,7 +51,7 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { } gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info) { - for (int i =0 ; i < info.presentationQueueCount; i++) { + for (uint32_t i = 0; i < info.presentationQueueCount; i++) { if (info.presentationQueues[i]->info.surface->windowSurface->layer.device == nil) info.presentationQueues[i]->info.surface->windowSurface->layer.device = device->outputDevice->device; id drawable = [info.presentationQueues[i]->info.surface->windowSurface->layer nextDrawable]; if (drawable == nil) return GN_UNKNOWN_ERROR; @@ -61,9 +61,10 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf id commandBuffer = [device->outputDevice->transferQueue commandBuffer]; - for (int c = 0; c < info.waitCount; c++) mtlWaitSemaphore(info.waitSemaphores[c], commandBuffer); + for (uint32_t c = 0; c < info.waitCount; c++) mtlWaitSemaphore(info.waitSemaphores[c], commandBuffer); [commandBuffer addCompletedHandler:^(id buffer) { + if (buffer == nil) return; mtlAddImageBackToQueue(presentationQueue, imageIndex); }]; @@ -85,7 +86,7 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf device->outputDevice->executingCommandBuffer = commandBuffer; } - for (int i = 0; i < info.presentationQueueCount; i++) { + for (uint32_t 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; 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 1281712..6edc123 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.h @@ -3,18 +3,18 @@ #include "presentation_queue/gryphn_presentation_queue.h" typedef id metalTexture; -GN_ARRAY_LIST(metalTexture); typedef struct mtlImageNeeded { gnSemaphore semaphoreToSignal; uint32_t* whereToPut; } mtlImageNeeded; -GN_ARRAY_LIST(mtlImageNeeded); + +GN_ARRAY_LIST_HEADER(metalTexture); +GN_ARRAY_LIST_HEADER(mtlImageNeeded); typedef struct gnPlatformPresentationQueue_t { metalTextureArrayList textures; uint32_tArrayList avaliableTextures; - mtlImageNeededArrayList neededImages; gnVec2 createdSize; 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 c2e4807..b182792 100644 --- a/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m +++ b/projects/apis/metal/src/presentation_queue/metal_presentation_queue.m @@ -23,12 +23,12 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount); presentationQueue->presentationQueue->textures = metalTextureArrayListCreate(); presentationQueue->presentationQueue->avaliableTextures = uint32_tArrayListCreate(); - for (int i = 0; i < presentationInfo.minImageCount; i++) { + for (uint32_t i = 0; i < presentationInfo.minImageCount; i++) { presentationQueue->images[i] = malloc(sizeof(struct gnTexture_t)); presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture)); 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); + metalTextureArrayListAdd(presentationQueue->presentationQueue->textures, presentationQueue->images[i]->texture->texture); + uint32_tArrayListAdd(presentationQueue->presentationQueue->avaliableTextures, i); } [textureDescriptor release]; @@ -36,27 +36,31 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation } void mtlTakeImageFromQueue(uint32_t* whereToPut, gnPresentationQueue queue, gnSemaphore semaphore) { - *whereToPut = queue->presentationQueue->avaliableTextures.data[0]; - uint32_tArrayListPopHead(&queue->presentationQueue->avaliableTextures); - + *whereToPut = uint32_tArrayListAt(queue->presentationQueue->avaliableTextures, 0); + uint32_tArrayListPopHead(queue->presentationQueue->avaliableTextures); if (!semaphore) return; - id buffer = [queue->outputDevice->outputDevice->transferQueue commandBuffer]; mtlSignalSemaphore(semaphore, buffer); [buffer commit]; } 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); - mtlImageNeededArrayListRemove(&queue->presentationQueue->neededImages); + if (mtlImageNeededArrayListCount(queue->presentationQueue->neededImages) > 0) { + mtlImageNeeded* needed = mtlImageNeededArrayListRefAt(queue->presentationQueue->neededImages, mtlImageNeededArrayListCount(queue->presentationQueue->neededImages) - 1); + mtlTakeImageFromQueue(needed->whereToPut, queue, needed->semaphoreToSignal); + mtlImageNeededArrayListRemove(queue->presentationQueue->neededImages); } else - uint32_tArrayListAdd(&queue->presentationQueue->avaliableTextures, index); + uint32_tArrayListAdd(queue->presentationQueue->avaliableTextures, index); } gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentationQueue, uint64_t timeout, gnSemaphore semaphore, uint32_t* imageIndex) { - while(presentationQueue->presentationQueue->avaliableTextures.count == 0); + time_t last_time = time(NULL); + while(uint32_tArrayListCount(presentationQueue->presentationQueue->avaliableTextures) == 0 || timeout >= 0) { + time_t curr_time = time(NULL); + timeout -= (curr_time - last_time); + last_time = curr_time; + } mtlTakeImageFromQueue(imageIndex, presentationQueue, semaphore); CGSize currentSize = presentationQueue->info.surface->windowSurface->layer.visibleRect.size; @@ -67,7 +71,7 @@ gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentati } gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex) { - while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {} + while(uint32_tArrayListCount(presentationQueue->presentationQueue->avaliableTextures) == 0); mtlTakeImageFromQueue(imageIndex, presentationQueue, NULL); CGSize currentSize = presentationQueue->info.surface->windowSurface->layer.visibleRect.size; @@ -78,12 +82,14 @@ gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQue } void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) { - free(presentationQueue->presentationQueue->avaliableTextures.data); - presentationQueue->presentationQueue->avaliableTextures.count = 0; - for (int i = 0; i < presentationQueue->imageCount; i++) { + for (uint32_t i = 0; i < presentationQueue->imageCount; i++) { [presentationQueue->images[i]->texture->texture release]; free(presentationQueue->images[i]->texture); free(presentationQueue->images[i]); } free(presentationQueue->presentationQueue); } + + +GN_ARRAY_LIST_DEFINITION(metalTexture) +GN_ARRAY_LIST_DEFINITION(mtlImageNeeded)