diff --git a/projects/apis/metal/loader/metal_instance_loader.m b/projects/apis/metal/loader/metal_instance_loader.m index 0fef9a7..86857a4 100644 --- a/projects/apis/metal/loader/metal_instance_loader.m +++ b/projects/apis/metal/loader/metal_instance_loader.m @@ -5,8 +5,9 @@ gryphnInstanceFunctionLayers metalLoadAPILayer() { return (gryphnInstanceFunctionLayers) { - .createInstance = { metalCreateInstance, NULL }, - .destroyInstance = { metalDestroyInstance, NULL } + .createInstance = metalCreateInstance, + .destroyInstance = metalDestroyInstance, + .next = NULL }; } diff --git a/projects/apis/metal/src/instance/metal_instance.h b/projects/apis/metal/src/instance/metal_instance.h index 595fed6..351cee3 100644 --- a/projects/apis/metal/src/instance/metal_instance.h +++ b/projects/apis/metal/src/instance/metal_instance.h @@ -7,5 +7,5 @@ typedef struct gnPlatformInstance_t { NSView* metalContentView; } gnPlatformInstance; -gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, PFN_gnCreateInstance_layer* next); -void metalDestroyInstance(gnInstance instance, PFN_gnDestroyInstance_layer* next); +gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next); +void metalDestroyInstance(gnInstance instance, gryphnInstanceFunctionLayers* next); diff --git a/projects/apis/metal/src/instance/metal_instance.m b/projects/apis/metal/src/instance/metal_instance.m index 0002d6f..f94802b 100644 --- a/projects/apis/metal/src/instance/metal_instance.m +++ b/projects/apis/metal/src/instance/metal_instance.m @@ -1,10 +1,10 @@ #include "metal_instance.h" // metal instances are kinda useless -gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, PFN_gnCreateInstance_layer* next) { +gnReturnCode metalCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next) { if (instance->instance == NULL) instance->instance = malloc(sizeof(gnPlatformInstance)); return GN_SUCCESS; } -void metalDestroyInstance(gnInstanceHandle instance, PFN_gnDestroyInstance_layer* next) { +void metalDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next) { free(instance->instance); } diff --git a/projects/apis/vulkan/loader/vulkan_instance_loader.c b/projects/apis/vulkan/loader/vulkan_instance_loader.c index fb0b7cc..52a5ee0 100644 --- a/projects/apis/vulkan/loader/vulkan_instance_loader.c +++ b/projects/apis/vulkan/loader/vulkan_instance_loader.c @@ -6,8 +6,9 @@ gryphnInstanceFunctionLayers loadVulkanAPILayer() { return (gryphnInstanceFunctionLayers) { - .createInstance = { vulkanCreateInstance, NULL }, - .destroyInstance = { vulkanDestroyInstance, NULL } + .createInstance = vulkanCreateInstance, + .destroyInstance = vulkanDestroyInstance, + .next = NULL }; } diff --git a/projects/apis/vulkan/src/instance/vulkan_instance.c b/projects/apis/vulkan/src/instance/vulkan_instance.c index 13346be..85c261d 100644 --- a/projects/apis/vulkan/src/instance/vulkan_instance.c +++ b/projects/apis/vulkan/src/instance/vulkan_instance.c @@ -37,7 +37,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL vk_debuggerDebugCallback( return VK_TRUE; } -gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, PFN_gnCreateInstance_layer* next) { +gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next) { instance->instance = malloc(sizeof(gnPlatformInstance)); vkStringArrayList extensions = vkStringArrayListCreate(); @@ -75,26 +75,24 @@ gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInf createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; #endif - for (int i = 0; i < instanceInfo->debuggerInfo.layerCount; i++) { - if (instanceInfo->debuggerInfo.layers[i] == GN_DEBUGGER_LAYER_PLATFORM) { - vkStringArrayListAdd(&extensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + if (instance->enabledLayerCounts[GN_DEBUGGER_LAYER_PLATFORM] > 0) { + vkStringArrayListAdd(&extensions, VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - const char* validation_layers[1] = { "VK_LAYER_KHRONOS_validation" }; - createInfo.enabledLayerCount = 1; - createInfo.ppEnabledLayerNames = (const char*[]){ "VK_LAYER_KHRONOS_validation" }; + const char* validation_layers[1] = { "VK_LAYER_KHRONOS_validation" }; + createInfo.enabledLayerCount = 1; + createInfo.ppEnabledLayerNames = (const char*[]){ "VK_LAYER_KHRONOS_validation" }; - instance->instance->userData.debuggerCallback = instanceInfo->debuggerInfo.callback; - instance->instance->userData.userData = instanceInfo->debuggerInfo.userData; + instance->instance->userData.debuggerCallback = instanceInfo->debuggerInfo.callback; + instance->instance->userData.userData = instanceInfo->debuggerInfo.userData; - VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, - .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, - .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT - }; - debugCreateInfo.pfnUserCallback = vk_debuggerDebugCallback; - debugCreateInfo.pUserData = &instance->instance->userData; - createInfo.pNext = &debugCreateInfo; - } + VkDebugUtilsMessengerCreateInfoEXT debugCreateInfo = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT, + .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT + }; + debugCreateInfo.pfnUserCallback = vk_debuggerDebugCallback; + debugCreateInfo.pUserData = &instance->instance->userData; + createInfo.pNext = &debugCreateInfo; } @@ -103,6 +101,7 @@ gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInf return VkResultToGnReturnCode(vkCreateInstance(&createInfo, NULL, &instance->instance->vk_instance)); } -void vulkanDestroyInstance(gnInstanceHandle instance, PFN_gnDestroyInstance_layer* next) { +void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next) { + printf("destroying layer\n"); vkDestroyInstance(instance->instance->vk_instance, NULL); } diff --git a/projects/apis/vulkan/src/instance/vulkan_instance.h b/projects/apis/vulkan/src/instance/vulkan_instance.h index 2e949a9..12e6241 100644 --- a/projects/apis/vulkan/src/instance/vulkan_instance.h +++ b/projects/apis/vulkan/src/instance/vulkan_instance.h @@ -14,8 +14,8 @@ typedef struct gnPlatformInstance_t { vkUserData userData; } gnPlatformInstance; -gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, PFN_gnCreateInstance_layer* next); -void vulkanDestroyInstance(gnInstanceHandle instance, PFN_gnDestroyInstance_layer* next); +gnReturnCode vulkanCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* instanceInfo, gryphnInstanceFunctionLayers* next); +void vulkanDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next); typedef const char* vkString; GN_ARRAY_LIST(vkString); diff --git a/projects/core/src/instance/gryphn_debugger.h b/projects/core/src/instance/gryphn_debugger.h index 9ebdfcf..55bcd69 100644 --- a/projects/core/src/instance/gryphn_debugger.h +++ b/projects/core/src/instance/gryphn_debugger.h @@ -28,8 +28,10 @@ typedef gnBool (*gnDebuggerCallback)( void* userData); typedef enum gnDebuggerLayer { - GN_DEBUGGER_LAYER_PLATFORM, // enable platform (vulkan validation) layers - GN_DEBUGGER_LAYER_FUNCTIONS // enable the checks on every function + GN_DEBUGGER_LAYER_PLATFORM, // enable platform (vulkan validation) layers + GN_DEBUGGER_LAYER_FUNCTIONS, // enable the checks on every function + + GN_LAYER_MAX } gnDebuggerLayer; typedef struct gnDebuggerCreateInfo { diff --git a/projects/core/src/instance/gryphn_instance.c b/projects/core/src/instance/gryphn_instance.c index d92e499..29a0084 100644 --- a/projects/core/src/instance/gryphn_instance.c +++ b/projects/core/src/instance/gryphn_instance.c @@ -6,7 +6,8 @@ #include "loader/src/gryphn_loader.h" #include "stdio.h" -#include "apis/vulkan/loader/vulkan_loader.h" +#include "validation_layers/function_loader/loader/function_loader.h" + // this implementation of gnCreateInstance cannot return GN_UNLOADED_LAYER gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo* info) { @@ -14,8 +15,6 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo* (*instance)->hasDebugger = GN_FALSE; (*instance)->layers = loaderLayerArrayListCreate(); - (*instance)->functions = gryphnLoadAPILayer(info->coreAPI); - loaderLayerArrayListAdd(&(*instance)->layers, loadLayer((loaderInfo){ .api = info->coreAPI, .layerToLoad = api_layer @@ -23,6 +22,7 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo* gnBool unsupportedExtension = GN_FALSE; for (int c = 0; c < GN_EXT_MAX; c++) (*instance)->enabledExtensions[c] = GN_FALSE; + for (int c = 0; c < GN_LAYER_MAX; c++) (*instance)->enabledLayerCounts[c] = 0; for (int i = 0; i < info->extensionCount; i++) { (*instance)->enabledExtensions[info->extensions[i]] = GN_TRUE; if (!gnIsExtensionSuppoted(info->coreAPI, info->extensions[i])) unsupportedExtension = GN_TRUE; @@ -33,6 +33,8 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo* if (info->debuggerInfo.layerCount > 0) { for (int i = 0; i < info->debuggerInfo.layerCount; i++) { + (*instance)->enabledLayerCounts[info->debuggerInfo.layers[i]]++; + if (info->debuggerInfo.layers[i] == GN_DEBUGGER_LAYER_FUNCTIONS) { loaderLayerArrayListAdd(&(*instance)->layers, loadLayer((loaderInfo){ .api = info->coreAPI, @@ -44,15 +46,27 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceCreateInfo* (*instance)->hasDebugger = GN_TRUE; } + (*instance)->allLayers = malloc(sizeof(gryphnInstanceFunctionLayers) * ( + (*instance)->enabledLayerCounts[GN_DEBUGGER_LAYER_FUNCTIONS] + + 1 // for the core layer + )); + + int layerIDX = 0; + for (int i = 0; i < info->debuggerInfo.layerCount; i++) { + if (info->debuggerInfo.layers[i] == GN_DEBUGGER_LAYER_FUNCTIONS) (*instance)->allLayers[layerIDX++] = checkerLoadInstanceFunctions(); + (*instance)->allLayers[layerIDX - 1].next = &(*instance)->allLayers[layerIDX]; + } + (*instance)->allLayers[layerIDX] = gryphnLoadAPILayer(info->coreAPI); + (*instance)->functions = &(*instance)->allLayers[0]; (*instance)->currentLayer = ((*instance)->layers.count - 1); for (int i = 0; i < (*instance)->layers.count; i++) (*instance)->layers.data[i].layerIndex = i; (*instance)->callingLayer = &(*instance)->layers.data[(*instance)->layers.count - 1]; if (unsupportedExtension) return GN_UNLOADED_EXTENSION; - return (*instance)->functions.createInstance.func(*instance, info, NULL); + return (*instance)->functions->createInstance(*instance, info, (*instance)->functions->next); } void gnDestroyInstance(gnInstanceHandle* instance) { if (instance == GN_NULL_HANDLE) return; - (*instance)->functions.destroyInstance.func(*instance, NULL); + (*instance)->functions->destroyInstance(*instance, (*instance)->functions->next); *instance = GN_NULL_HANDLE; } diff --git a/projects/core/src/instance/gryphn_instance.h b/projects/core/src/instance/gryphn_instance.h index e837c40..c7bc971 100644 --- a/projects/core/src/instance/gryphn_instance.h +++ b/projects/core/src/instance/gryphn_instance.h @@ -29,8 +29,9 @@ struct gnInstance_t { struct gnPlatformInstance_t* instance; gnDebuggerCreateInfo debugger; gnBool enabledExtensions[GN_EXT_MAX]; - - gryphnInstanceFunctionLayers functions; + int enabledLayerCounts[GN_LAYER_MAX]; + gryphnInstanceFunctionLayers* allLayers; + gryphnInstanceFunctionLayers* functions; loaderLayerArrayList layers; loaderLayer* callingLayer; diff --git a/projects/loader/src/gryphn_instance_functions.h b/projects/loader/src/gryphn_instance_functions.h index 28ba6e0..a923720 100644 --- a/projects/loader/src/gryphn_instance_functions.h +++ b/projects/loader/src/gryphn_instance_functions.h @@ -3,7 +3,6 @@ #include "core/gryphn_return_code.h" #include "utils/gryphn_bool.h" #include "gryphn_handles.h" -#include "gryphn_loader_helpers.h" typedef struct gnInstanceCreateInfo gnInstanceCreateInfo; typedef struct gnSurfaceDetails gnSurfaceDetails; @@ -19,13 +18,9 @@ typedef struct gnOutputDeviceInfo gnOutputDeviceInfo; typedef struct gnMacOSWindowSurfaceInfo gnMacOSWindowSurfaceInfo; #endif -typedef struct PFN_gnCreateInstance_layer PFN_gnCreateInstance_layer; -typedef gnReturnCode (*PFN_gnCreateInstance)(gnInstanceHandle instance, gnInstanceCreateInfo* info, PFN_gnCreateInstance_layer* next); -gryphnFunctionLayer(PFN_gnCreateInstance); - -typedef struct PFN_gnDestroyInstance_layer PFN_gnDestroyInstance_layer; -typedef void (*PFN_gnDestroyInstance)(gnInstanceHandle instance, PFN_gnDestroyInstance_layer* next); -gryphnFunctionLayer(PFN_gnDestroyInstance); +typedef struct gryphnInstanceFunctionLayers gryphnInstanceFunctionLayers; +typedef gnReturnCode (*PFN_gnCreateInstance)(gnInstanceHandle instance, gnInstanceCreateInfo* info, gryphnInstanceFunctionLayers* next); +typedef void (*PFN_gnDestroyInstance)(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next); typedef struct gnInstanceFunctions { gnPhysicalDevice* (*_gnGetPhysicalDevices)(gnInstanceHandle instance, uint32_t* count); diff --git a/projects/loader/src/gryphn_loader.h b/projects/loader/src/gryphn_loader.h index 95cc451..92732a4 100644 --- a/projects/loader/src/gryphn_loader.h +++ b/projects/loader/src/gryphn_loader.h @@ -14,9 +14,11 @@ typedef struct gryphnFunctionLayer { } gryphnFunctionLayer; typedef struct gryphnInstanceFunctionLayers { - PFN_gnCreateInstance_layer createInstance; - PFN_gnDestroyInstance_layer destroyInstance; + PFN_gnCreateInstance createInstance; + PFN_gnDestroyInstance destroyInstance; + struct gryphnInstanceFunctionLayers* next; } gryphnInstanceFunctionLayers; + gryphnInstanceFunctionLayers gryphnLoadAPILayer(gnRenderingAPI api); typedef struct loaderLayer { diff --git a/projects/loader/src/gryphn_loader_helpers.h b/projects/loader/src/gryphn_loader_helpers.h deleted file mode 100644 index ee117c2..0000000 --- a/projects/loader/src/gryphn_loader_helpers.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#define gryphnFunctionLayer(function) typedef struct function##_layer { \ -function func;\ -struct function##_layer* next; \ -} function##_layer;\ diff --git a/projects/validation_layers/function_loader/loader/function_loader.c b/projects/validation_layers/function_loader/loader/function_loader.c index 01ea408..00a12c7 100644 --- a/projects/validation_layers/function_loader/loader/function_loader.c +++ b/projects/validation_layers/function_loader/loader/function_loader.c @@ -7,8 +7,8 @@ gryphnInstanceFunctionLayers checkerLoadInstanceFunctions() { return (gryphnInstanceFunctionLayers) { - .createInstance = { checkCreateInstance, NULL }, - .destroyInstance = { checkDestroyInstance, NULL } + .createInstance = checkCreateInstance, + .destroyInstance = checkDestroyInstance }; } diff --git a/projects/validation_layers/function_loader/loader/function_loader.h b/projects/validation_layers/function_loader/loader/function_loader.h index 1fb987c..30771c2 100644 --- a/projects/validation_layers/function_loader/loader/function_loader.h +++ b/projects/validation_layers/function_loader/loader/function_loader.h @@ -3,6 +3,9 @@ #include "loader/src/gryphn_device_functions.h" #include "loader/src/gryphn_command_functions.h" +typedef struct gryphnInstanceFunctionLayers gryphnInstanceFunctionLayers; +gryphnInstanceFunctionLayers checkerLoadInstanceFunctions(); + gnInstanceFunctions loadFunctionLoaderInstanceFunctions(); gnDeviceFunctions loadFunctionLoaderDeviceFunctions(); gnCommandFunctions loadFunctionLoaderCommandFunctions(); diff --git a/projects/validation_layers/function_loader/src/instance_functions.c b/projects/validation_layers/function_loader/src/instance_functions.c index d3529ef..5bf6fe9 100644 --- a/projects/validation_layers/function_loader/src/instance_functions.c +++ b/projects/validation_layers/function_loader/src/instance_functions.c @@ -4,23 +4,24 @@ #include "core/src/output_device/gryphn_output_device.h" #include "core/src/window_surface/gryphn_surface.h" -gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* info, PFN_gnCreateInstance_layer* next) { - if (next->func == NULL) { +gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* info, gryphnInstanceFunctionLayers* next) { + if (next == NULL || next->createInstance == NULL) { gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){ .message = gnCreateString("Failed to load gnCreateInstance this indicates a bug within gryphn") }); return GN_FAILED_TO_LOAD_FUNCTION; } - return (*(PFN_gnCreateInstance*)next->func)(instance, info, next->next); + return next->createInstance(instance, info, next->next); } -void checkDestroyInstance(gnInstanceHandle instance, PFN_gnDestroyInstance_layer* next) { - if (next->func == NULL) { +void checkDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next) { + if (next == NULL || next->destroyInstance == NULL) { gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){ .message = gnCreateString("Failed to load gnDestroyInstance this indicates a bug within gryphn") }); + return; } - (*(PFN_gnDestroyInstance*)next->func)(instance, next->next); + next->destroyInstance(instance, next->next); } gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count) { diff --git a/projects/validation_layers/function_loader/src/instance_functions.h b/projects/validation_layers/function_loader/src/instance_functions.h index 9201dd1..76e5424 100644 --- a/projects/validation_layers/function_loader/src/instance_functions.h +++ b/projects/validation_layers/function_loader/src/instance_functions.h @@ -2,8 +2,8 @@ #include "core/src/instance/gryphn_instance.h" #include -gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* info, PFN_gnCreateInstance_layer* next); -void checkDestroyInstance(gnInstanceHandle instance, PFN_gnDestroyInstance_layer* next); +gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceCreateInfo* info, gryphnInstanceFunctionLayers* next); +void checkDestroyInstance(gnInstanceHandle instance, gryphnInstanceFunctionLayers* next); gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count); gnBool checkCanDevicePresent(gnPhysicalDevice device, gnWindowSurfaceHandle windowSurface);