diff --git a/projects/apis/metal/CMakeLists.txt b/projects/apis/metal/CMakeLists.txt index df9aa1b..be7f83e 100644 --- a/projects/apis/metal/CMakeLists.txt +++ b/projects/apis/metal/CMakeLists.txt @@ -3,7 +3,7 @@ set(CMAKE_CXX_STANDARD 17) project(GryphnMetalImpl) file(GLOB_RECURSE SOURCE_FILES CONFIGURE_DEPENDS - "src/*.c" "src/*.h" "src/*.m" + "src/*.c" "src/*.h" "src/*.m" "src/*.mm" ) file(GLOB_RECURSE LOADER_FILES CONFIGURE_DEPENDS "loader/*.m" diff --git a/projects/apis/metal/src/shader_module/metal_shader_compiler.h b/projects/apis/metal/src/shader_module/metal_shader_compiler.h new file mode 100644 index 0000000..345bf84 --- /dev/null +++ b/projects/apis/metal/src/shader_module/metal_shader_compiler.h @@ -0,0 +1,9 @@ +#pragma once +#include "stdint.h" +#include "stdlib.h" + +typedef struct mtlShaderOptions { + +} mtlShaderOptions; + +const char* mtlCompileShader(uint32_t* code, size_t size, mtlShaderOptions* options); diff --git a/projects/apis/metal/src/shader_module/metal_shader_compiler.mm b/projects/apis/metal/src/shader_module/metal_shader_compiler.mm new file mode 100644 index 0000000..62eb44b --- /dev/null +++ b/projects/apis/metal/src/shader_module/metal_shader_compiler.mm @@ -0,0 +1,5 @@ +#include "metal_shader_compiler.h" + +extern "C" const char* mtlCompileShader(const char* src, mtlShaderOptions options) { + return "i hate this BS"; +} 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 22a6a46..a70e514 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.h +++ b/projects/apis/metal/src/shader_module/metal_shader_module.h @@ -18,7 +18,14 @@ typedef struct metalShaderMap { typedef struct gnPlatformShaderModule_t { id function; metalShaderMap map; + gnBool useShaderMap; } gnPlatformShaderModule; -gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo); -void destroyMetalShaderModule(gnShaderModule module); +#ifdef __cplusplus +extern "C" { +#endif + gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo); + void destroyMetalShaderModule(gnShaderModule module); +#ifdef __cplusplus +} +#endif 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 2f24384..27cf114 100644 --- a/projects/apis/metal/src/shader_module/metal_shader_module.m +++ b/projects/apis/metal/src/shader_module/metal_shader_module.m @@ -2,126 +2,171 @@ #include "spirv_cross_c.h" #include "instance/gryphn_debugger.h" #include "devices/metal_output_devices.h" +#include "metal_shader_compiler.h" #import #import -void mtlSpirVErrorCallback(void *userdata, const char *error) { - gnDebuggerInfo debugger = *((gnDebuggerInfo*)userdata); - gnDebuggerSetErrorMessage(debugger, (gnMessageData){ - .message = gnCombineStrings(gnCreateString("shader compilation error MSL "), gnCreateString(error)) - }); -} - gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo) { - module->shaderModule = malloc(sizeof(struct gnPlatformShaderModule_t)); + mtlShaderOptions options = { - spvc_context context = NULL; - spvc_parsed_ir ir = NULL; - spvc_compiler compiler = NULL; - const char *result = NULL; - spvc_resources resources = NULL; - const spvc_reflected_resource *list = NULL; - spvc_compiler_options options = NULL; - size_t count; + }; - spvc_context_create(&context); - spvc_context_set_error_callback(context, mtlSpirVErrorCallback, &module->device->instance->debugger); - spvc_context_parse_spirv(context, shaderModuleInfo.code, shaderModuleInfo.size / 4, &ir); - spvc_context_create_compiler(context, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_COPY, &compiler); + const char* res = mtlCompileShader(shaderModuleInfo.code, shaderModuleInfo.size, &options); + printf("compiled res: %s\n", res); - spvc_compiler_create_shader_resources(compiler, &resources); - - spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); - // [[buffer(0)]] is reserved for stage_in, [[buffer(1)]] is reserved for push_constant - uint32_t currentBufferBinding = 2, currentTextureBinding = 0; - 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); - spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); - spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, currentBufferBinding); - module->shaderModule->map.sets[set].bindings[binding] = currentBufferBinding; - currentBufferBinding++; - } - - 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); - spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); - spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, currentTextureBinding); - module->shaderModule->map.sets[set].bindings[binding] = currentTextureBinding; - currentTextureBinding++; - } - - spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STORAGE_BUFFER, &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); - spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); - spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, currentBufferBinding); - module->shaderModule->map.sets[set].bindings[binding] = currentBufferBinding; - currentBufferBinding++; - } - - spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &list, &count); - for (int i = 0; i < count; i++) { - spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); - spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, 1); - } - - 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); - spvc_compiler_install_compiler_options(compiler, options); - - SpvExecutionModel executionModel = SpvExecutionModelVertex; - if (shaderModuleInfo.stage == GN_FRAGMENT_SHADER_MODULE) executionModel = SpvExecutionModelFragment; - - spvc_compiler_set_entry_point(compiler, shaderModuleInfo.entryPoint.value, executionModel); - spvc_result res = spvc_compiler_compile(compiler, &result); - if (res != SPVC_SUCCESS) - return GN_FAILED_TO_CONVERT_SHADER_CODE; - - NSError* error = nil; - MTLCompileOptions* mtloptions = nil; - NSString* sourceCode = [NSString stringWithCString:result encoding:NSUTF8StringEncoding]; - id shaderLib = [device->outputDevice->device newLibraryWithSource:sourceCode options:mtloptions error:&error]; - if (!shaderLib) { - const char* errorString = error.localizedDescription.UTF8String; - gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ - .message = gnCombineStrings(gnCreateString("Failed to compile metal library "), errorString) - }); - return GN_FAILED_TO_CREATE_SHADER_MODULE; - } - - const char* name = shaderModuleInfo.entryPoint.value; - if (strcmp(name, "main") == 0) { - name = "main0"; - } - - gnBool foundFunction = false; - for (int i = 0; i < shaderLib.functionNames.count; i++) { - if (strcmp([shaderLib.functionNames objectAtIndex:0].UTF8String, name) == 0) { - foundFunction = true; - } - } - - if (!foundFunction) { - gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ - .message = gnCombineStrings(gnCreateString("Failed to find specified entry point "), name) - }); - return GN_FAILED_TO_FIND_ENTRY_POINT; - } - - - NSString* functionName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; - module->shaderModule->function = [shaderLib newFunctionWithName:functionName]; - - [shaderLib release]; - - spvc_context_destroy(context); return GN_SUCCESS; } +// void mtlSpirVErrorCallback(void *userdata, const char *error) { +// gnDebuggerInfo debugger = *((gnDebuggerInfo*)userdata); +// gnDebuggerSetErrorMessage(debugger, (gnMessageData){ +// .message = gnCombineStrings(gnCreateString("shader compilation error MSL "), gnCreateString(error)) +// }); +// } + +// extern "C" gnReturnCode createMetalShaderModule(gnShaderModule module, gnDevice device, gnShaderModuleInfo shaderModuleInfo) { +// module->shaderModule = (gnPlatformShaderModule_t*)malloc(sizeof(gnPlatformShaderModule_t)); + +// MTLArgumentBuffersTier supportsArgumentBuffers = device->outputDevice->device.argumentBuffersSupport; +// module->shaderModule->useShaderMap = !(supportsArgumentBuffers == MTLArgumentBuffersTier2); + +// spvc_context context = NULL; +// spvc_parsed_ir ir = NULL; +// spvc_compiler compiler = NULL; +// const char *result = NULL; +// spvc_resources resources = NULL; +// const spvc_reflected_resource *list = NULL; +// spvc_compiler_options options = NULL; +// size_t count; + +// spvc_context_create(&context); +// spvc_context_set_error_callback(context, mtlSpirVErrorCallback, &module->device->instance->debugger); +// spvc_context_parse_spirv(context, shaderModuleInfo.code, shaderModuleInfo.size / 4, &ir); +// spvc_context_create_compiler(context, SPVC_BACKEND_MSL, ir, SPVC_CAPTURE_MODE_COPY, &compiler); +// spvc_compiler_create_shader_resources(compiler, &resources); + +// spvc_compiler_create_compiler_options(compiler, &options); +// if (module->shaderModule->useShaderMap) { +// spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_UNIFORM_BUFFER, &list, &count); +// // [[buffer(0)]] is reserved for stage_in, [[buffer(1)]] is reserved for push_constant +// uint32_t currentBufferBinding = 2, currentTextureBinding = 0; +// 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); +// spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); +// spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, currentBufferBinding); +// module->shaderModule->map.sets[set].bindings[binding] = currentBufferBinding; +// currentBufferBinding++; +// } + +// 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); +// spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); +// spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, currentTextureBinding); +// module->shaderModule->map.sets[set].bindings[binding] = currentTextureBinding; +// currentTextureBinding++; +// } + +// spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_STORAGE_BUFFER, &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); +// spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); +// spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, currentBufferBinding); +// module->shaderModule->map.sets[set].bindings[binding] = currentBufferBinding; +// currentBufferBinding++; +// } + +// spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_PUSH_CONSTANT, &list, &count); +// for (int i = 0; i < count; i++) { +// spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); +// spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, 1); +// } +// spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_VERSION, SPVC_MAKE_MSL_VERSION(1, 0, 0)); +// } else { +// spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_VERSION, SPVC_MAKE_MSL_VERSION(3, 0, 0)); +// spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS, true); +// spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES, true); +// spvc_compiler_options_set_uint(options, SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER, 2); + +// const spvc_combined_image_sampler* samplers; +// size_t sampler_count; + +// spvc_compiler_build_combined_image_samplers(compiler); +// spvc_compiler_get_combined_image_samplers(compiler, &samplers, &sampler_count); +// printf("sampler count: %zu\n", sampler_count); +// for (size_t i = 0; i < sampler_count; ++i) { +// printf("Combined: image ID %u + sampler ID %u = ID %u\n", +// samplers[i].image_id, +// samplers[i].sampler_id, +// samplers[i].combined_id); +// } + +// // spvc_resources_get_resource_list_for_type(resources, SPVC_RESOURCE_TYPE_SAMPLED_IMAGE, &list, &count); +// // for (int i = 0; i < count; i++) { +// // spvc_compiler +// // // uint32_t set = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationDescriptorSet), +// // // binding = spvc_compiler_get_decoration(compiler, list[i].id, SpvDecorationBinding); +// // // spvc_compiler_unset_decoration(compiler, list[i].id, SpvDecorationBinding); +// // // spvc_compiler_set_decoration(compiler, list[i].id, SpvDecorationBinding, currentTextureBinding); +// // // module->shaderModule->map.sets[set].bindings[binding] = currentTextureBinding; +// // // currentTextureBinding++; +// // } +// } + +// spvc_compiler_options_set_bool(options, SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING, true); +// spvc_compiler_install_compiler_options(compiler, options); + +// SpvExecutionModel executionModel = SpvExecutionModelVertex; +// if (shaderModuleInfo.stage == GN_FRAGMENT_SHADER_MODULE) executionModel = SpvExecutionModelFragment; + +// spvc_compiler_set_entry_point(compiler, shaderModuleInfo.entryPoint.value, executionModel); +// spvc_result res = spvc_compiler_compile(compiler, &result); +// printf("res: %s\n", result); + +// if (res != SPVC_SUCCESS) +// return GN_FAILED_TO_CONVERT_SHADER_CODE; + +// NSError* error = nil; +// MTLCompileOptions* mtloptions = nil; +// NSString* sourceCode = [NSString stringWithCString:result encoding:NSUTF8StringEncoding]; +// id shaderLib = [device->outputDevice->device newLibraryWithSource:sourceCode options:mtloptions error:&error]; +// if (!shaderLib) { +// const char* errorString = error.localizedDescription.UTF8String; +// gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ +// .message = gnCombineStrings(gnCreateString("Failed to compile metal library "), errorString) +// }); +// return GN_FAILED_TO_CREATE_SHADER_MODULE; +// } + +// const char* name = shaderModuleInfo.entryPoint.value; +// if (strcmp(name, "main") == 0) { +// name = "main0"; +// } + +// gnBool foundFunction = false; +// for (int i = 0; i < shaderLib.functionNames.count; i++) { +// if (strcmp([shaderLib.functionNames objectAtIndex:0].UTF8String, name) == 0) { +// foundFunction = true; +// } +// } + +// if (!foundFunction) { +// gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ +// .message = gnCombineStrings(gnCreateString("Failed to find specified entry point "), name) +// }); +// return GN_FAILED_TO_FIND_ENTRY_POINT; +// } + +// NSString* functionName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; +// module->shaderModule->function = [shaderLib newFunctionWithName:functionName]; + +// [shaderLib release]; + +// spvc_context_destroy(context); +// return GN_SUCCESS; +// } void destroyMetalShaderModule(gnShaderModule module) { free(module->shaderModule); diff --git a/projects/extensions/synchronization/commands/gryphn_sync_present.h b/projects/extensions/synchronization/commands/gryphn_sync_present.h index 874eee4..40e1f06 100644 --- a/projects/extensions/synchronization/commands/gryphn_sync_present.h +++ b/projects/extensions/synchronization/commands/gryphn_sync_present.h @@ -9,7 +9,6 @@ typedef struct gnPresentSyncInfo { uint32_t presentationQueueCount; gnPresentationQueueHandle* presentationQueues; uint32_t* imageIndices; - uint32_t queueIndex; } gnPresentSyncInfo; gnReturnCode gnPresentSync(gnOutputDeviceHandle device, gnPresentSyncInfo info); diff --git a/projects/extensions/synchronization/commands/gryphn_sync_submit.h b/projects/extensions/synchronization/commands/gryphn_sync_submit.h index 09ebff5..362ab9d 100644 --- a/projects/extensions/synchronization/commands/gryphn_sync_submit.h +++ b/projects/extensions/synchronization/commands/gryphn_sync_submit.h @@ -11,7 +11,6 @@ typedef struct gnSubmitSyncInfo { gnSemaphoreHandle* signalSemaphores; uint32_t commandBufferCount; gnCommandBufferHandle* commandBuffers; - uint32_t queueIndex; gnFenceHandle fence; } gnSubmitSyncInfo;