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); metalBufferSubData(buffer, 0, dataSize, data);
} }
void metalBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) { void metalBufferSubData(gnBufferHandle buffer, size_t offset, size_t dataSize, gnBufferMemory data) {
void* bufferData;
if (buffer->buffer->useStagingBuffer) { 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<MTLCommandBuffer> commandBuffer = [buffer->device->outputDevice->transferQueue commandBuffer];
id<MTLBlitCommandEncoder> encoder = [commandBuffer blitCommandEncoder]; id<MTLBlitCommandEncoder> encoder = [commandBuffer blitCommandEncoder];
[encoder copyFromBuffer:buffer->buffer->stagingBuffer sourceOffset:0 toBuffer:buffer->buffer->buffer destinationOffset:0 size:dataSize]; [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 commit];
[commandBuffer waitUntilCompleted]; [commandBuffer waitUntilCompleted];
} else } else
memcpy(buffer->buffer->buffer.contents + offset, data, dataSize); memcpy((char*)buffer->buffer->buffer.contents + offset, data, dataSize);
} }
void* mapMetalBuffer(gnBufferHandle buffer) { void* mapMetalBuffer(gnBufferHandle buffer) {
return buffer->buffer->buffer.contents; return buffer->buffer->buffer.contents;

View File

@@ -4,7 +4,7 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
gnReturnCode allocateMetalCommandBuffers(gnCommandBufferHandle* commandBuffers, uint32_t count, gnCommandPool pool) { 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 = malloc(sizeof(gnPlatformCommandBuffer));
commandBuffers[i]->commandBuffer->commandBuffer = [pool->commandPool->commandQueue commandBuffer]; commandBuffers[i]->commandBuffer->commandBuffer = [pool->commandPool->commandQueue commandBuffer];
@@ -25,7 +25,7 @@ gnReturnCode beginMetalCommandBuffer(gnCommandBuffer commandBuffer) {
return GN_SUCCESS; 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) { void destroyMetalCommandBuffer(gnCommandBuffer commandBuffer) {
[commandBuffer->commandBuffer->commandBuffer release]; [commandBuffer->commandBuffer->commandBuffer release];

View File

@@ -2,6 +2,7 @@
#include "devices/metal_output_devices.h" #include "devices/metal_output_devices.h"
gnReturnCode createMetalCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info) { gnReturnCode createMetalCommandPool(gnCommandPool commandPool, gnDevice device, gnCommandPoolInfo info) {
info.flags = 0;
commandPool->commandPool = malloc(sizeof(struct gnPlatformCommandPool_t)); commandPool->commandPool = malloc(sizeof(struct gnPlatformCommandPool_t));
commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue]; commandPool->commandPool->commandQueue = [device->outputDevice->device newCommandQueue];

View File

@@ -4,8 +4,7 @@
#include "utils/math/gryphn_math.h" #include "utils/math/gryphn_math.h"
void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) { void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) {
int currentColorAttachment = 0; for (uint32_t i = 0; i < passInfo.clearValueCount; i++) {
for (int i = 0; i < passInfo.clearValueCount; i++) {
if (passInfo.framebuffer->framebuffer->clearCopies[i].clear) { if (passInfo.framebuffer->framebuffer->clearCopies[i].clear) {
MTLRenderPassColorAttachmentDescriptor* color = passInfo.framebuffer->framebuffer->clearCopies[i].descriptor; MTLRenderPassColorAttachmentDescriptor* color = passInfo.framebuffer->framebuffer->clearCopies[i].descriptor;
color.clearColor = MTLClearColorMake( color.clearColor = MTLClearColorMake(
@@ -14,7 +13,6 @@ void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) {
passInfo.clearValues[i].b, passInfo.clearValues[i].b,
passInfo.clearValues[i].a passInfo.clearValues[i].a
); );
currentColorAttachment++;
} }
} }
buffer->commandBuffer->encoder = [buffer->commandBuffer->commandBuffer renderCommandEncoderWithDescriptor:passInfo.framebuffer->framebuffer->subpasses[0]]; 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 indexCount:indexCount
indexType:((type == GN_UINT32) ? MTLIndexTypeUInt32 : MTLIndexTypeUInt16) indexType:((type == GN_UINT32) ? MTLIndexTypeUInt32 : MTLIndexTypeUInt16)
indexBuffer:buffer->commandBuffer->indexBuffer->buffer->buffer indexBuffer:buffer->commandBuffer->indexBuffer->buffer->buffer
indexBufferOffset:0 indexBufferOffset:firstIndex
instanceCount:instanceCount instanceCount:instanceCount
baseVertex:vertexOffset baseVertex:vertexOffset
baseInstance:firstInstance 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]; [encoder useResources:uniform->uniform->usedResources count:uniform->uniform->usedResourceCount usage:MTLResourceUsageRead stages:MTLRenderStageVertex | MTLRenderStageFragment];
int startIndex = 0; int startIndex = 0;
for (int i = 0; i < dynamicOffsetCount; i++) { for (uint32_t i = 0; i < dynamicOffsetCount; i++) {
int c = startIndex; int c = startIndex;
for (; c < MAX_METAL_BINDINGS; c++) { for (; c < MAX_METAL_BINDINGS; c++) {
if (uniform->uniform->isDynamic[c]) { if (uniform->uniform->isDynamic[c]) {

View File

@@ -5,6 +5,8 @@
#include "instance/gryphn_instance.h" #include "instance/gryphn_instance.h"
gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle outputDevice, gnOutputDeviceInfo deviceInfo) { gnReturnCode createMetalOutputDevice(gnInstanceHandle instance, gnOutputDeviceHandle outputDevice, gnOutputDeviceInfo deviceInfo) {
if (instance == GN_NULL_HANDLE) return GN_INVALID_HANDLE;
outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice)); outputDevice->outputDevice = malloc(sizeof(gnPlatformOutputDevice));
outputDevice->outputDevice->device = deviceInfo.physicalDevice->physicalDevice->device.retain; outputDevice->outputDevice->device = deviceInfo.physicalDevice->physicalDevice->device.retain;
outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue; outputDevice->outputDevice->transferQueue = outputDevice->outputDevice->device.newCommandQueue;

View File

@@ -4,10 +4,12 @@
#include "window_surface/gryphn_surface.h" #include "window_surface/gryphn_surface.h"
gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount) { gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCount) {
if (instance == GN_NULL_HANDLE) return NULL;
NSArray *devices = MTLCopyAllDevices(); NSArray *devices = MTLCopyAllDevices();
*deviceCount = (uint32_t)[devices count]; *deviceCount = (uint32_t)[devices count];
gnPhysicalDevice* devicesList = (gnPhysicalDevice*)malloc(sizeof(gnPhysicalDevice) * *deviceCount); 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] = malloc(sizeof(gnPhysicalOutputDevice_t));
devicesList[i]->physicalDevice = malloc(sizeof(gnPlatformPhysicalDevice)); devicesList[i]->physicalDevice = malloc(sizeof(gnPlatformPhysicalDevice));
devicesList[i]->physicalDevice->device = [devices objectAtIndex:0]; devicesList[i]->physicalDevice->device = [devices objectAtIndex:0];
@@ -39,5 +41,7 @@ gnPhysicalDevice* getMetalDevices(gnInstanceHandle instance, uint32_t* deviceCou
} }
gnBool metalCanDevicePresent(gnPhysicalDevice device, gnWindowSurface windowSurface) { 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 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 "instance/gryphn_instance.h"
#include "output_device/gryphn_output_device.h" #include "output_device/gryphn_output_device.h"
#include "core/gryphn_image_format.h" #include "core/gryphn_image_format.h"
gnReturnCode createMetalFramebuffer(gnFramebuffer framebuffer, gnOutputDevice device, gnFramebufferInfo info) { 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 = malloc(sizeof(struct gnPlatformFramebuffer_t));
framebuffer->framebuffer->clearCopyCount = info.attachmentCount; framebuffer->framebuffer->clearCopyCount = info.attachmentCount;
framebuffer->framebuffer->clearCopies = malloc(sizeof(mtlClearCopy) * 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->clearCopies[i].clear = GN_FALSE;
} }
framebuffer->framebuffer->subpassCount = info.renderPassDescriptor->renderPassDescriptor->subpassCount; framebuffer->framebuffer->subpassCount = info.renderPassDescriptor->renderPassDescriptor->subpassCount;
framebuffer->framebuffer->subpasses = malloc(sizeof(mtlSubpass) * framebuffer->framebuffer->subpassCount); framebuffer->framebuffer->subpasses = malloc(sizeof(mtlSubpass) * framebuffer->framebuffer->subpassCount);
framebuffer->framebuffer->depthAttachmentIndicies = malloc(sizeof(uint32_t) * 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]; framebuffer->framebuffer->subpasses[i] = [info.renderPassDescriptor->renderPassDescriptor->subpasses[i] copy];
MTLRenderPassDescriptor* pass = framebuffer->framebuffer->subpasses[i]; MTLRenderPassDescriptor* pass = framebuffer->framebuffer->subpasses[i];
[pass setRenderTargetWidth:info.size.x]; [pass setRenderTargetWidth:info.size.x];
[pass setRenderTargetHeight:info.size.y]; [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]; MTLRenderPassColorAttachmentDescriptor* colorPass = pass.colorAttachments[c];
colorPass.texture = info.attachments[info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].colorAttachments[c].attachmentIndex]->texture->texture; colorPass.texture = info.attachments[info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].colorAttachments[c].attachmentIndex]->texture->texture;
if (info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].colorAttachments[c].resolveAttachmentIndex >= 0) 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) { if (info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].depthAttachmentIndex >= 0) {
MTLRenderPassDepthAttachmentDescriptor* depthAttachment = framebuffer->framebuffer->subpasses[i].depthAttachment; MTLRenderPassDepthAttachmentDescriptor* depthAttachment = framebuffer->framebuffer->subpasses[i].depthAttachment;
depthAttachment.texture = info.attachments[info.renderPassDescriptor->renderPassDescriptor->copyInfos[i].depthAttachmentIndex]->texture->texture; 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; return GN_SUCCESS;
} }
void destroyMetalFramebuffer(gnFramebuffer framebuffer) { 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->subpasses);
free(framebuffer->framebuffer); free(framebuffer->framebuffer);
} }

View File

@@ -2,9 +2,13 @@
// metal instances are kinda useless // metal instances are kinda useless
gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next) { 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; return GN_SUCCESS;
} }
void metalDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next) { void metalDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next) {
if (next != NULL) return;
free(instance->instance); free(instance->instance);
} }

View File

@@ -50,8 +50,6 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn
mtlSubpass subpass = info.renderPassDescriptor->renderPassDescriptor->subpasses[info.subpassIndex]; mtlSubpass subpass = info.renderPassDescriptor->renderPassDescriptor->subpasses[info.subpassIndex];
mtlSubpassCopyInfo copyInfo = info.renderPassDescriptor->renderPassDescriptor->copyInfos[info.subpassIndex]; mtlSubpassCopyInfo copyInfo = info.renderPassDescriptor->renderPassDescriptor->copyInfos[info.subpassIndex];
for (uint32_t i = 0; i < copyInfo.colorAttachmentCount; i++) { for (uint32_t i = 0; i < copyInfo.colorAttachmentCount; i++) {
MTLRenderPassColorAttachmentDescriptor* colorPass = subpass.colorAttachments[i];
descriptor.colorAttachments[i].pixelFormat = copyInfo.colorAttachments[i].format; descriptor.colorAttachments[i].pixelFormat = copyInfo.colorAttachments[i].format;
if (info.colorBlending.enable == GN_TRUE) { if (info.colorBlending.enable == GN_TRUE) {
[descriptor.colorAttachments objectAtIndexedSubscript:i].blendingEnabled = YES; [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); const char* shaderCode = mtlCompilerShader(info.shaderModules[i]->shaderModule->compiler, &info.uniformLayout);
// printf("shader code: %s\n", shaderCode); // printf("shader code: %s\n", shaderCode);
@@ -95,7 +93,7 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn
if (strcmp(name, "main") == 0) name = "main0"; if (strcmp(name, "main") == 0) name = "main0";
gnBool foundFunction = false; 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) { if (strcmp([shaderLib.functionNames objectAtIndex:0].UTF8String, name) == 0) {
foundFunction = true; foundFunction = true;
break; break;
@@ -114,9 +112,9 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn
MTLVertexBufferLayoutDescriptorArray* buffers = vertexDescriptor.layouts; MTLVertexBufferLayoutDescriptorArray* buffers = vertexDescriptor.layouts;
int k = 0; 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]; [[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].bufferIndex = i;
attributes[k].offset = info.shaderInputLayout.bufferAttributes[i].attributes[j].offset; attributes[k].offset = info.shaderInputLayout.bufferAttributes[i].attributes[j].offset;
attributes[k].format = mtlGryphnVertexFormat(info.shaderInputLayout.bufferAttributes[i].attributes[j].format); attributes[k].format = mtlGryphnVertexFormat(info.shaderInputLayout.bufferAttributes[i].attributes[j].format);

View File

@@ -1,11 +1,10 @@
#include "metal_present.h" #include "metal_present.h"
#include <synchronization/commands/gryphn_sync_present.h> #include <synchronization/commands/gryphn_sync_present.h>
#include "stdio.h"
#include "time.h" #include "time.h"
gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) { 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; 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];
if (drawable == nil) return GN_UNKNOWN_ERROR; if (drawable == nil) return GN_UNKNOWN_ERROR;
@@ -15,7 +14,8 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
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); if (buffer == nil) return;
uint32_tArrayListAdd(presentationQueue->presentationQueue->avaliableTextures, imageIndex);
}]; }];
id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder]; id<MTLBlitCommandEncoder> blit = [commandBuffer blitCommandEncoder];
@@ -40,7 +40,7 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
[device->outputDevice->executingCommandBuffer waitUntilCompleted]; [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 || 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) { info.presentationQueues[i]->info.imageSize.y != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.height) {
return GN_SUBOPTIMAL_PRESENTATION_QUEUE; return GN_SUBOPTIMAL_PRESENTATION_QUEUE;
@@ -51,7 +51,7 @@ gnReturnCode metalPresent(gnOutputDeviceHandle device, gnPresentInfo info) {
} }
gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo 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; 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]; id<CAMetalDrawable> drawable = [info.presentationQueues[i]->info.surface->windowSurface->layer nextDrawable];
if (drawable == nil) return GN_UNKNOWN_ERROR; if (drawable == nil) return GN_UNKNOWN_ERROR;
@@ -61,9 +61,10 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf
id<MTLCommandBuffer> commandBuffer = [device->outputDevice->transferQueue commandBuffer]; 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) { [commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer) {
if (buffer == nil) return;
mtlAddImageBackToQueue(presentationQueue, imageIndex); mtlAddImageBackToQueue(presentationQueue, imageIndex);
}]; }];
@@ -85,7 +86,7 @@ gnReturnCode metalPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo inf
device->outputDevice->executingCommandBuffer = commandBuffer; 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 || 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) { info.presentationQueues[i]->info.imageSize.y != info.presentationQueues[i]->info.surface->windowSurface->layer.drawableSize.height) {
return GN_SUBOPTIMAL_PRESENTATION_QUEUE; return GN_SUBOPTIMAL_PRESENTATION_QUEUE;

View File

@@ -3,18 +3,18 @@
#include "presentation_queue/gryphn_presentation_queue.h" #include "presentation_queue/gryphn_presentation_queue.h"
typedef id<MTLTexture> metalTexture; typedef id<MTLTexture> metalTexture;
GN_ARRAY_LIST(metalTexture);
typedef struct mtlImageNeeded { typedef struct mtlImageNeeded {
gnSemaphore semaphoreToSignal; gnSemaphore semaphoreToSignal;
uint32_t* whereToPut; uint32_t* whereToPut;
} mtlImageNeeded; } mtlImageNeeded;
GN_ARRAY_LIST(mtlImageNeeded);
GN_ARRAY_LIST_HEADER(metalTexture);
GN_ARRAY_LIST_HEADER(mtlImageNeeded);
typedef struct gnPlatformPresentationQueue_t { typedef struct gnPlatformPresentationQueue_t {
metalTextureArrayList textures; metalTextureArrayList textures;
uint32_tArrayList avaliableTextures; uint32_tArrayList avaliableTextures;
mtlImageNeededArrayList neededImages; mtlImageNeededArrayList neededImages;
gnVec2 createdSize; gnVec2 createdSize;

View File

@@ -23,12 +23,12 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation
presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount); presentationQueue->images = malloc(sizeof(gnTexture) * presentationInfo.minImageCount);
presentationQueue->presentationQueue->textures = metalTextureArrayListCreate(); presentationQueue->presentationQueue->textures = metalTextureArrayListCreate();
presentationQueue->presentationQueue->avaliableTextures = uint32_tArrayListCreate(); 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] = malloc(sizeof(struct gnTexture_t));
presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture)); presentationQueue->images[i]->texture = malloc(sizeof(gnPlatformTexture));
presentationQueue->images[i]->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor]; presentationQueue->images[i]->texture->texture = [device->outputDevice->device newTextureWithDescriptor:textureDescriptor];
metalTextureArrayListAdd(&presentationQueue->presentationQueue->textures, presentationQueue->images[i]->texture->texture); metalTextureArrayListAdd(presentationQueue->presentationQueue->textures, presentationQueue->images[i]->texture->texture);
uint32_tArrayListAdd(&presentationQueue->presentationQueue->avaliableTextures, i); uint32_tArrayListAdd(presentationQueue->presentationQueue->avaliableTextures, i);
} }
[textureDescriptor release]; [textureDescriptor release];
@@ -36,27 +36,31 @@ gnReturnCode createMetalPresentationQueue(gnPresentationQueueHandle presentation
} }
void mtlTakeImageFromQueue(uint32_t* whereToPut, gnPresentationQueue queue, gnSemaphore semaphore) { void mtlTakeImageFromQueue(uint32_t* whereToPut, gnPresentationQueue queue, gnSemaphore semaphore) {
*whereToPut = queue->presentationQueue->avaliableTextures.data[0]; *whereToPut = uint32_tArrayListAt(queue->presentationQueue->avaliableTextures, 0);
uint32_tArrayListPopHead(&queue->presentationQueue->avaliableTextures); uint32_tArrayListPopHead(queue->presentationQueue->avaliableTextures);
if (!semaphore) return; if (!semaphore) return;
id<MTLCommandBuffer> buffer = [queue->outputDevice->outputDevice->transferQueue commandBuffer]; id<MTLCommandBuffer> buffer = [queue->outputDevice->outputDevice->transferQueue commandBuffer];
mtlSignalSemaphore(semaphore, buffer); mtlSignalSemaphore(semaphore, buffer);
[buffer commit]; [buffer commit];
} }
void mtlAddImageBackToQueue(gnPresentationQueue queue, uint32_t index) { void mtlAddImageBackToQueue(gnPresentationQueue queue, uint32_t index) {
if (queue->presentationQueue->neededImages.count > 0) { if (mtlImageNeededArrayListCount(queue->presentationQueue->neededImages) > 0) {
mtlTakeImageFromQueue(queue->presentationQueue->neededImages.data[queue->presentationQueue->neededImages.count - 1].whereToPut, queue, queue->presentationQueue->neededImages.data[queue->presentationQueue->neededImages.count - 1].semaphoreToSignal); mtlImageNeeded* needed = mtlImageNeededArrayListRefAt(queue->presentationQueue->neededImages, mtlImageNeededArrayListCount(queue->presentationQueue->neededImages) - 1);
mtlImageNeededArrayListRemove(&queue->presentationQueue->neededImages); mtlTakeImageFromQueue(needed->whereToPut, queue, needed->semaphoreToSignal);
mtlImageNeededArrayListRemove(queue->presentationQueue->neededImages);
} }
else 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) { 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); mtlTakeImageFromQueue(imageIndex, presentationQueue, semaphore);
CGSize currentSize = presentationQueue->info.surface->windowSurface->layer.visibleRect.size; CGSize currentSize = presentationQueue->info.surface->windowSurface->layer.visibleRect.size;
@@ -67,7 +71,7 @@ gnReturnCode getMetalPresentQueueImageAsync(gnPresentationQueueHandle presentati
} }
gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex) { gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQueue, uint32_t* imageIndex) {
while (presentationQueue->presentationQueue->avaliableTextures.count == 0) {} while(uint32_tArrayListCount(presentationQueue->presentationQueue->avaliableTextures) == 0);
mtlTakeImageFromQueue(imageIndex, presentationQueue, NULL); mtlTakeImageFromQueue(imageIndex, presentationQueue, NULL);
CGSize currentSize = presentationQueue->info.surface->windowSurface->layer.visibleRect.size; CGSize currentSize = presentationQueue->info.surface->windowSurface->layer.visibleRect.size;
@@ -78,12 +82,14 @@ gnReturnCode getMetalPresentQueueImage(gnPresentationQueueHandle presentationQue
} }
void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) { void destroyMetalPresentationQueue(gnPresentationQueueHandle presentationQueue) {
free(presentationQueue->presentationQueue->avaliableTextures.data); for (uint32_t i = 0; i < presentationQueue->imageCount; i++) {
presentationQueue->presentationQueue->avaliableTextures.count = 0;
for (int i = 0; i < presentationQueue->imageCount; i++) {
[presentationQueue->images[i]->texture->texture release]; [presentationQueue->images[i]->texture->texture release];
free(presentationQueue->images[i]->texture); free(presentationQueue->images[i]->texture);
free(presentationQueue->images[i]); free(presentationQueue->images[i]);
} }
free(presentationQueue->presentationQueue); free(presentationQueue->presentationQueue);
} }
GN_ARRAY_LIST_DEFINITION(metalTexture)
GN_ARRAY_LIST_DEFINITION(mtlImageNeeded)