fixed a good couple of metal warnings

This commit is contained in:
Gregory Wells
2025-08-03 15:44:09 -04:00
parent 2a6d3a108a
commit a49a0a5a3e
12 changed files with 65 additions and 54 deletions

View File

@@ -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<MTLCommandBuffer> commandBuffer = [buffer->device->outputDevice->transferQueue commandBuffer];
id<MTLBlitCommandEncoder> 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;

View File

@@ -4,7 +4,7 @@
#import <Metal/Metal.h>
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];

View File

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

View File

@@ -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]) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,11 +1,10 @@
#include "metal_present.h"
#include <synchronization/commands/gryphn_sync_present.h>
#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<CAMetalDrawable> 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<MTLCommandBuffer> commandBuffer = [device->outputDevice->transferQueue commandBuffer];
[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, imageIndex);
if (buffer == nil) return;
uint32_tArrayListAdd(presentationQueue->presentationQueue->avaliableTextures, imageIndex);
}];
id<MTLBlitCommandEncoder> 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<CAMetalDrawable> 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<MTLCommandBuffer> 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<MTLCommandBuffer> 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;

View File

@@ -3,18 +3,18 @@
#include "presentation_queue/gryphn_presentation_queue.h"
typedef id<MTLTexture> 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;

View File

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