diff --git a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h index 187c173..5a1747a 100644 --- a/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h +++ b/projects/apis/metal/src/commands/command_buffer/metal_command_buffer.h @@ -7,7 +7,7 @@ typedef struct gnPlatformCommandBuffer_t { id commandBuffer; id encoder; - struct gnGraphicsPipeline_t* boundGraphcisPipeline; + gnGraphicsPipeline boundGraphcisPipeline; gnBufferHandle indexBuffer; } gnPlatformCommandBuffer; diff --git a/projects/apis/metal/src/commands/commands/metal_commands.m b/projects/apis/metal/src/commands/commands/metal_commands.m index a0c29d6..199a640 100644 --- a/projects/apis/metal/src/commands/commands/metal_commands.m +++ b/projects/apis/metal/src/commands/commands/metal_commands.m @@ -1,4 +1,5 @@ #include "metal_commands.h" +#include "shader_module/metal_shader_module.h" void metelBeginRenderPass(gnCommandBuffer buffer, gnRenderPassInfo passInfo) { int currentColorAttachment = 0; @@ -119,8 +120,14 @@ void metalBindUniform(gnCommandBufferHandle buffer, gnUniform uniform, uint32_t atIndex:(info.binding + 1) ]; } else if (uniform->uniform->bindings[i].type == GN_IMAGE_DESCRIPTOR) { - gnImageUniformInfo info = *(gnImageUniformInfo*)uniform->uniform->bindings[i].data; - [encoder setFragmentTexture:info.texture->texture->texture atIndex:0]; + for (int c = 0; c < buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.textureMaps.count; c++) { + metalBindingMap map = buffer->commandBuffer->boundGraphcisPipeline->graphicsPipeline->fragmentShaderMaps.textureMaps.data[c]; + if (map.set == set && map.binding == uniform->uniform->bindings[i].binding) { + gnImageUniformInfo info = *(gnImageUniformInfo*)uniform->uniform->bindings[i].data; + [encoder setFragmentTexture:info.texture->texture->texture atIndex:map.metalBindingIndex]; + break; + } + } } } } diff --git a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h index 4799811..589f863 100644 --- a/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h +++ b/projects/apis/metal/src/pipelines/graphics_pipeline/metal_graphics_pipeline.h @@ -1,9 +1,11 @@ #pragma once #include "pipelines/graphics_pipeline/gryphn_graphics_pipeline.h" +#include "shader_module/metal_shader_module.h" #import typedef struct gnPlatformGraphicsPipeline_t { id graphicsPipeline; + metalBindingMaps fragmentShaderMaps; } gnPlatformGraphicsPipeline; gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gnOutputDevice device, gnGraphicsPipelineInfo info); 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 c9fccfd..356f895 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 @@ -64,6 +64,7 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn [descriptor setVertexFunction:info.shaderModules[i]->shaderModule->function]; } else if (info.shaderModules[i]->info.stage == GN_FRAGMENT_SHADER_MODULE) { [descriptor setFragmentFunction:info.shaderModules[i]->shaderModule->function]; + graphicsPipeline->graphicsPipeline->fragmentShaderMaps = info.shaderModules[i]->shaderModule->maps; } else { return GN_UNSUPPORTED_SHADER_MODULE; } @@ -77,28 +78,16 @@ gnReturnCode createMetalGraphicsPipeline(gnGraphicsPipeline graphicsPipeline, gn // layout(location = 1) in vec2 inUV; // layout(location = 2) in vec3 inColor; - - [attributes[0] setFormat:MTLVertexFormatFloat3]; - [attributes[0] setOffset:0]; - [attributes[0] setBufferIndex:0]; - [attributes[1] setFormat:MTLVertexFormatFloat2]; - [attributes[1] setOffset:(sizeof(float) * 3)]; - [attributes[1] setBufferIndex:0]; - [attributes[2] setFormat:MTLVertexFormatFloat3]; - [attributes[2] setOffset:(sizeof(float) * 5)]; - [attributes[2] setBufferIndex:0]; - [buffers[0] setStride:(sizeof(float) * 8)]; - - // int k = 0; - // for (int 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++) { - // 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); - // k++; - // } - // } + int k = 0; + for (int 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++) { + 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); + k++; + } + } [descriptor setVertexDescriptor:vertexDescriptor]; NSError* error = nil; diff --git a/projects/apis/metal/src/shader_module/metal_shader_module.h b/projects/apis/metal/src/shader_module/metal_shader_module.h index 98d265d..f4e9181 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.h +++ b/projects/apis/metal/src/shader_module/metal_shader_module.h @@ -1,10 +1,23 @@ #pragma once #include "shader_module/gryphn_shader_module.h" +#include "utils/lists/gryphn_array_list.h" #import +typedef struct metalBindingMap { + uint32_t set; + uint32_t binding; + uint32_t metalBindingIndex; +} metalBindingMap; +GN_ARRAY_LIST(metalBindingMap); + +typedef struct metalBindingMaps { + metalBindingMapArrayList textureMaps; +} metalBindingMaps; + typedef struct gnPlatformShaderModule_t { id function; uint32_t pushConstantIndex; + metalBindingMaps maps; } gnPlatformShaderModule; gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo); 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 6eda7c2..00a3875 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.m +++ b/projects/apis/metal/src/shader_module/metal_shader_module.m @@ -12,6 +12,29 @@ void mtlSpirVErrorCallback(void *userdata, const char *error) { }); } +metalBindingMapArrayList loadTextureBindingInformation(spvc_resources resources, spvc_compiler compiler) { + metalBindingMapArrayList bindings = metalBindingMapArrayListCreate(); + + const spvc_reflected_resource *list = NULL; + size_t count; + + spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE, &list, &count); + + + for (int i = 0; i < count; i++) { + uint32_t set = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationDescriptorSet), + binding = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationBinding); + + metalBindingMap map = { + .set = set, .binding = binding, + .metalBindingIndex = i + }; + metalBindingMapArrayListAdd(&bindings, map); + } + + return bindings; +} + gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo) { module->shaderModule = malloc(sizeof(struct gnPlatformShaderModule_t)); @@ -47,6 +70,8 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS // TODO: get the buffer index } + module->shaderModule->maps.textureMaps = loadTextureBindingInformation(resources, compiler); + spvc_compiler_create_compiler_options(compiler, &options); spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_VERSION, 200); spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); @@ -60,8 +85,6 @@ gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnS if (res != SPVC_SUCCESS) return GN_FAILED_TO_CONVERT_SHADER_CODE; - printf("Shader Module code: %s\n", result); - NSError* error = nil; MTLCompileOptions* mtloptions = nil; NSString* sourceCode = [NSString stringWithCString:result encoding:NSUTF8StringEncoding];