diff --git a/projects/apis/metal/src/commands/commands/metal_commands.m b/projects/apis/metal/src/commands/commands/metal_commands.m index 59eb323..54bdc15 100644 --- a/projects/apis/metal/src/commands/commands/metal_commands.m +++ b/projects/apis/metal/src/commands/commands/metal_commands.m @@ -114,6 +114,9 @@ void metalDrawIndexed(gnCommandBufferHandle buffer, gnIndexType type, int indexC void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t set) { id encoder = (id)buffer->commandBuffer->encoder; + [encoder useResources:uniform->uniform->resources.data count:uniform->uniform->resources.count usage:MTLResourceUsageRead stages:MTLRenderStageFragment]; + [encoder setFragmentBuffer:uniform->uniform->argumentBuffer offset:0 atIndex:2]; + // for (int i = 0; i < uniform->uniform->bindingCount; i++) { // if (uniform->uniform->bindings[i].type == GN_UNIFORM_BUFFER_DESCRIPTOR) { // gnBufferUniformInfo info = *(gnBufferUniformInfo*)uniform->uniform->bindings[i].data; diff --git a/projects/apis/metal/src/shader_module/metal_shader_module.m b/projects/apis/metal/src/shader_module/metal_shader_module.m index 8ba10bf..489f325 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.m +++ b/projects/apis/metal/src/shader_module/metal_shader_module.m @@ -19,6 +19,7 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS mtlShader shader = mtlCompileShader(shaderModuleInfo.code, shaderModuleInfo.size / 4, &options); const char* res = shader.code; if (res == NULL) return GN_FAILED_TO_CONVERT_SHADER_CODE; + printf("res: %s\n", res); NSError* error = nil; MTLCompileOptions* mtloptions = nil; @@ -29,6 +30,8 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ .message = gnCombineStrings(gnCreateString("Failed to compile metal library "), errorString) }); + [shaderLib release]; + free((void*)res); return GN_FAILED_TO_CREATE_SHADER_MODULE; } @@ -48,7 +51,7 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS module->shaderModule->function = [shaderLib newFunctionWithName:functionName]; [shaderLib release]; - free((void*)res); + if (options.stage == vertex) free((void*)res); module->shaderModule->shaderMap = shader.map; return GN_SUCCESS; } diff --git a/projects/apis/metal/src/uniforms/metal_uniform.h b/projects/apis/metal/src/uniforms/metal_uniform.h index 4455a41..13f9090 100644 --- a/projects/apis/metal/src/uniforms/metal_uniform.h +++ b/projects/apis/metal/src/uniforms/metal_uniform.h @@ -1,6 +1,8 @@ #pragma once #include "uniforms/gryphn_uniform.h" +#include #include +#include "shader_module/metal_shader_module.h" typedef struct metalUniformBinding { gnUniformType type; @@ -8,9 +10,15 @@ typedef struct metalUniformBinding { void* data; } metalUniformBinding; +typedef id mtlResource; +GN_ARRAY_LIST(mtlResource); + typedef struct gnPlatformUniform_t { - uint32_t bindingCount; - metalUniformBinding* bindings; + uint32_t index[MAX_METAL_BINDINGS]; + id encoder; + id argumentBuffer; + + mtlResourceArrayList resources; } gnPlatformUniform; void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info); diff --git a/projects/apis/metal/src/uniforms/metal_uniform.m b/projects/apis/metal/src/uniforms/metal_uniform.m index 9beebd3..fac2e6a 100644 --- a/projects/apis/metal/src/uniforms/metal_uniform.m +++ b/projects/apis/metal/src/uniforms/metal_uniform.m @@ -1,32 +1,47 @@ #include #include "metal_uniform.h" +#include "devices/metal_output_devices.h" +#include "texture/metal_texture.h" +#include void updateMetalBufferUniform(gnUniform uniform, gnBufferUniformInfo* info) { - for (int i = 0; i < uniform->uniform->bindingCount; i++) { - if (uniform->uniform->bindings[i].binding == info->binding) { - uniform->uniform->bindings[i].data = malloc(sizeof(gnBufferUniformInfo)); - memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnBufferUniformInfo)); - break; - } - } + // [uniform->uniform->encoder setBuffer:info->buffer->buffer->buffer offset:0 atIndex:0]; } void updateMetalStorageUniform(gnUniform uniform, gnStorageUniformInfo* info) { - for (int i = 0; i < uniform->uniform->bindingCount; i++) { - if (uniform->uniform->bindings[i].binding == info->binding) { - uniform->uniform->bindings[i].data = malloc(sizeof(gnStorageUniformInfo)); - memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnStorageUniformInfo)); - break; - } - } + // [uniform->uniform->encoder setBuffer:info->buffer->buffer->buffer offset:0 atIndex:uniform->uniform->index[info->binding]]; + // for (int i = 0; i < uniform->uniform->bindingCount; i++) { + // if (uniform->uniform->bindings[i].binding == info->binding) { + // uniform->uniform->bindings[i].data = malloc(sizeof(gnStorageUniformInfo)); + // memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnStorageUniformInfo)); + // break; + // } + // } } void updateMetalImageUniform(gnUniform uniform, gnImageUniformInfo* info) { - for (int i = 0; i < uniform->uniform->bindingCount; i++) { - if (uniform->uniform->bindings[i].binding == info->binding) { - uniform->uniform->bindings[i].data = malloc(sizeof(gnImageUniformInfo)); - memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnImageUniformInfo)); - break; - } - } + printf("%p\n", info->texture->texture->texture); + [uniform->uniform->encoder setTexture:info->texture->texture->texture atIndex:uniform->uniform->index[info->binding]]; + [uniform->uniform->encoder setSamplerState:info->texture->texture->sampler atIndex:uniform->uniform->index[info->binding] + 1]; + + uniform->uniform->resources = mtlResourceArrayListCreate(); + mtlResourceArrayListAdd(&uniform->uniform->resources, info->texture->texture->texture); + // mtlResourceArrayListAdd(&uniform->uniform->resources, info->texture->texture->sampler); + + // printf("updating metal image uniform %i\n", uniform->uniform->index[info->binding]); + + // printf("binding: %i\n", info->binding); + // printf("mapped index: %i\n", uniform->uniform->index[info->binding]); + // id buffer = [uniform->pool->device->outputDevice->device newBufferWithLength:sizeof(int) options:MTLResourceStorageModeShared]; + // printf("uniform %p | uniform->uniform %p | encoder %p\n", uniform, uniform->uniform, uniform->uniform->encoder); + // [uniform->uniform->encoder setBuffer:buffer offset:0 atIndex:0]; + //info->binding + + // for (int i = 0; i < uniform->uniform->bindingCount; i++) { + // if (uniform->uniform->bindings[i].binding == info->binding) { + // uniform->uniform->bindings[i].data = malloc(sizeof(gnImageUniformInfo)); + // memcpy(uniform->uniform->bindings[i].data, info, sizeof(gnImageUniformInfo)); + // break; + // } + // } } diff --git a/projects/apis/metal/src/uniforms/metal_uniform_pool.m b/projects/apis/metal/src/uniforms/metal_uniform_pool.m index 2f51c69..7560577 100644 --- a/projects/apis/metal/src/uniforms/metal_uniform_pool.m +++ b/projects/apis/metal/src/uniforms/metal_uniform_pool.m @@ -1,6 +1,7 @@ #include #include #include "metal_uniform.h" +#include "devices/metal_output_devices.h" gnReturnCode createMetalUniformPool(gnUniformPool pool, gnDeviceHandle device) { return GN_SUCCESS; @@ -11,12 +12,86 @@ gnUniform* allocateMetalUniforms(gnUniformPool pool, const gnUniformAllocationIn for (int i = 0; i < allocInfo.setCount; i++) { uniforms[i] = malloc(sizeof(struct gnUniform_t)); uniforms[i]->uniform = malloc(sizeof(gnPlatformUniform)); - uniforms[i]->uniform->bindingCount = allocInfo.sets[i].uniformBindingCount; - uniforms[i]->uniform->bindings = malloc(sizeof(metalUniformBinding) * allocInfo.sets[i].uniformBindingCount); - for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) { - uniforms[i]->uniform->bindings[c].type = allocInfo.sets[i].uniformBindings[c].type; - uniforms[i]->uniform->bindings[c].binding = allocInfo.sets[i].uniformBindings[c].binding; - } + + MTLArgumentDescriptor *texDesc = [[MTLArgumentDescriptor alloc] init]; + texDesc.dataType = MTLDataTypeTexture; + texDesc.index = 0; + texDesc.access = MTLBindingAccessReadOnly; + + MTLArgumentDescriptor *samplerDesc = [[MTLArgumentDescriptor alloc] init]; + samplerDesc.dataType = MTLDataTypeSampler; + samplerDesc.index = 1; + + uniforms[i]->uniform->encoder = [pool->device->outputDevice->device newArgumentEncoderWithArguments:@[texDesc, samplerDesc]]; + uniforms[i]->uniform->argumentBuffer = [pool->device->outputDevice->device newBufferWithLength:[uniforms[i]->uniform->encoder encodedLength] + options:MTLResourceStorageModeShared]; + + [uniforms[i]->uniform->encoder setArgumentBuffer:uniforms[i]->uniform->argumentBuffer offset:0]; + + // int currentIndex = 0; + // NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:allocInfo.sets[i].uniformBindingCount]; + + // MTLArgumentDescriptor* textureDescriptor = [[MTLArgumentDescriptor alloc] init]; + // textureDescriptor.dataType = MTLDataTypeTexture; + // textureDescriptor.index = 0; + // textureDescriptor.arrayLength = 1; + // textureDescriptor.access = MTLBindingAccessReadOnly; + // textureDescriptor.textureType = MTLTextureType2D; + + // MTLArgumentDescriptor* samplerDescriptor = [[MTLArgumentDescriptor alloc] init]; + // samplerDescriptor.dataType = MTLDataTypeSampler; + // samplerDescriptor.index = 1; + // samplerDescriptor.arrayLength = 1; + // samplerDescriptor.access = MTLBindingAccessReadOnly; + + // [arguments addObject:textureDescriptor]; + // [arguments addObject:samplerDescriptor]; + + + // for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) { + // if (allocInfo.sets[i].uniformBindings[c].type == GN_IMAGE_DESCRIPTOR) { + // MTLArgumentDescriptor* textureDescriptor = [[MTLArgumentDescriptor alloc] init]; + // textureDescriptor.dataType = MTLDataTypeTexture; + // textureDescriptor.index = 0; + // textureDescriptor.arrayLength = 1; + // textureDescriptor.access = MTLBindingAccessReadOnly; + // textureDescriptor.textureType = MTLTextureType2DMultisample; + // [arguments addObject:textureDescriptor]; + + // MTLArgumentDescriptor* samplerDescriptor = [[MTLArgumentDescriptor alloc] init]; + // samplerDescriptor.dataType = MTLDataTypeSampler; + // samplerDescriptor.index = 1; + // samplerDescriptor.arrayLength = 1; + // samplerDescriptor.access = MTLBindingAccessReadOnly; + // [arguments addObject:samplerDescriptor]; + // uniforms[i]->uniform->index[allocInfo.sets[i].uniformBindings[c].binding] = currentIndex; + + // currentIndex += 2; + // } + + // } + // for (int c = 0; c < allocInfo.sets[i].uniformBindingCount; c++) { + // if (allocInfo.sets[i].uniformBindings[c].type == GN_UNIFORM_BUFFER_DESCRIPTOR || + // allocInfo.sets[i].uniformBindings[c].type == GN_SHADER_STORE_BUFFER_DESCRIPTOR) { + // // MTLArgumentDescriptor* bufferDescriptor = [[MTLArgumentDescriptor alloc] init]; + // // bufferDescriptor.dataType = MTLDataTypePointer; + // // bufferDescriptor.index = currentIndex; + // // bufferDescriptor.arrayLength = 1; + // // bufferDescriptor.access = MTLBindingAccessReadOnly; + // // [arguments addObject:bufferDescriptor]; + // // uniforms[i]->uniform->index[allocInfo.sets[i].uniformBindings[c].binding] = currentIndex; + + // // currentIndex++; + // } + // } + // if (arguments.count > 0) { + // uniforms[i]->uniform->encoder = [pool->device->outputDevice->device newArgumentEncoderWithArguments:arguments]; + // uniforms[i]->uniform->argumentBuffer = [pool->device->outputDevice->device newBufferWithLength:uniforms[i]->uniform->encoder.encodedLength options:MTLResourceStorageModeShared]; + // [uniforms[i]->uniform->encoder setArgumentBuffer:uniforms[i]->uniform->argumentBuffer offset:0]; + // } + // printf("argument encoder %p, argument buffer %p\n", uniforms[i]->uniform->encoder, uniforms[i]->uniform->argumentBuffer); + + // for (int k = 0; k < arguments.count; k++) [[arguments objectAtIndex:k] release]; } return uniforms; }