diff --git a/projects/core/src/debugger/gryphn_debugger.h b/projects/core/src/debugger/gryphn_debugger.h index 71e7def..b829fb1 100644 --- a/projects/core/src/debugger/gryphn_debugger.h +++ b/projects/core/src/debugger/gryphn_debugger.h @@ -35,7 +35,7 @@ typedef enum gnDebuggerLayer { } gnDebuggerLayer; typedef struct gnDebuggerInfo { - gnDebuggerCallback callback; + gnDebuggerCallback callback; // instance callback cannot be null void* userData; uint32_t layerCount; diff --git a/projects/core/src/instance/gryphn_instance.c b/projects/core/src/instance/gryphn_instance.c index ce0da12..666a15e 100644 --- a/projects/core/src/instance/gryphn_instance.c +++ b/projects/core/src/instance/gryphn_instance.c @@ -8,13 +8,23 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instance, gnInstanceInfo info) { (*instance)->layers = loaderLayerArrayListCreate(); - // load the API layers (this will) - loaderInfo loadInfo = { + loaderLayerArrayListAdd(&(*instance)->layers, loadLayer((loaderInfo){ .api = info.renderingAPI, .layerToLoad = api_layer - }; + })); - loaderLayerArrayListAdd(&(*instance)->layers, loadLayer(loadInfo)); + loaderLayerArrayListAdd(&(*instance)->layers, loadLayer((loaderInfo){ + .api = info.renderingAPI, + .layerToLoad = function_checker_layer + })); + + loaderLayerArrayListAdd(&(*instance)->layers, loadLayer((loaderInfo){ + .api = info.renderingAPI, + .layerToLoad = function_checker_layer + })); + + (*instance)->currentLayer = ((*instance)->layers.count - 1); + for (int i = 0; i < (*instance)->layers.count; i++) (*instance)->layers.data[i].layerIndex = i; // i hate this line of code but im not fixing it (*instance)->callingLayer = &(*instance)->layers.data[(*instance)->layers.count - 1]; diff --git a/projects/core/src/instance/gryphn_instance.h b/projects/core/src/instance/gryphn_instance.h index e761e1b..9fb99a9 100644 --- a/projects/core/src/instance/gryphn_instance.h +++ b/projects/core/src/instance/gryphn_instance.h @@ -23,6 +23,7 @@ struct gnInstance_t { loaderLayerArrayList layers; loaderLayer* callingLayer; + uint32_t currentLayer; gnDebuggerHandle debugger; }; diff --git a/projects/loader/src/gryphn_loader.c b/projects/loader/src/gryphn_loader.c index 7aaeb26..37d5987 100644 --- a/projects/loader/src/gryphn_loader.c +++ b/projects/loader/src/gryphn_loader.c @@ -7,6 +7,8 @@ #include #endif +#include "core/src/instance/gryphn_instance.h" + // load the speedy API functions or something like that gnInstanceFunctions loadAPIInstanceFunctions(gnRenderingAPI api) { switch (api) { @@ -80,7 +82,30 @@ loaderLayer api_loaded_layer(gnRenderingAPI api) { }; } +loaderLayer function_check_layer() { + return (loaderLayer){ + .instanceFunctions = loadFunctionLoaderInstanceFunctions(), + .deviceFunctions = loadFunctionLoaderDeviceFunctions(), + .commandFunctions = loadFunctionLoaderCommandFunctions() + }; +} + loaderLayer loadLayer(loaderInfo info) { if (info.layerToLoad == api_layer) return api_loaded_layer(info.api); + if (info.layerToLoad == function_checker_layer) return function_check_layer(); return null_layer(); } + +loaderLayer* loaderGetNextLayer(gnInstance instance) { + instance->currentLayer--; + uint32_t nextLayer = instance->currentLayer; + if (instance->currentLayer == 0) { + nextLayer = 0; + resetLayer(instance); + } + return &instance->layers.data[nextLayer]; +} + +void resetLayer(gnInstance instance) { + instance->currentLayer = (instance->layers.count - 1); +} diff --git a/projects/loader/src/gryphn_loader.h b/projects/loader/src/gryphn_loader.h index 462f763..1ba9055 100644 --- a/projects/loader/src/gryphn_loader.h +++ b/projects/loader/src/gryphn_loader.h @@ -13,9 +13,12 @@ typedef struct loaderLayer { gnDeviceFunctions deviceFunctions; gnCommandFunctions commandFunctions; - // this index is not set by loadLayer, set by gnCreateInstance + // this index is not set by loadLayer, set by gnCreateInstance, also not used for now uint32_t layerIndex; } loaderLayer; loaderLayer loadLayer(loaderInfo info); GN_ARRAY_LIST(loaderLayer); + +loaderLayer* loaderGetNextLayer(gnInstance instance); +void resetLayer(gnInstance instance); diff --git a/projects/loader/src/gryphn_loader_info.h b/projects/loader/src/gryphn_loader_info.h index 6bd105d..decc9bd 100644 --- a/projects/loader/src/gryphn_loader_info.h +++ b/projects/loader/src/gryphn_loader_info.h @@ -2,7 +2,7 @@ #include "gryphn_rendering_api.h" typedef enum toLoadLayer { - no_layer, api_layer + no_layer, api_layer, function_checker_layer } toLoadLayer; typedef struct loaderInfo { diff --git a/projects/validation_layers/function_loader/loader/function_loader.c b/projects/validation_layers/function_loader/loader/function_loader.c index aded765..5814f4d 100644 --- a/projects/validation_layers/function_loader/loader/function_loader.c +++ b/projects/validation_layers/function_loader/loader/function_loader.c @@ -1,11 +1,47 @@ #include "function_loader.h" +#include "instance_functions.h" -gnInstanceFunctions loadFunctionLoaderInstanceFunctions(gnInstanceFunctions* callbacks) { - return *callbacks; +gnInstanceFunctions loadFunctionLoaderInstanceFunctions() { + return (gnInstanceFunctions){ + ._gnCreateInstance = checkCreateInstance, + ._gnDestroyInstance = checkDestroyInstance, + + ._gnGetPhysicalDevices = checkGetPhysicalDevices, + ._gnQueueCanPresentToSurface = checkQueueCanPresentToSurface, + + ._gnCreateOutputDevice = checkCreateOutputDevice, + ._gnDestroyOutputDevice = checkDestroyOutputDevice, + + + #ifdef GN_PLATFORM_LINUX + #ifdef GN_WINDOW_X11 + ._gnCreateX11WindowSurface = checkCreateX11WindowSurface, + #endif + #ifdef GN_WINDOW_WAYLAND + ._gnCreateWaylandWindowSurface, + #endif + #endif + + + #ifdef GN_PLATFORM_WIN32 + ._gnCreateWin32WindowSurface, + #endif + + #ifdef GN_PLATFORM_MACOS + ._gnCreateMacOSWindowSurface = checkCreateSurfaceMacOS, + #endif + + ._gnDestroyWindowSurface = checkDestroyWindowSurface, + ._gnGetSurfaceDetails = checkGetSurfaceDetails + }; } -gnDeviceFunctions loadFunctionLoaderDeviceFunctions(gnDeviceFunctions* callbacks) { - return *callbacks; +gnDeviceFunctions loadFunctionLoaderDeviceFunctions() { + return (gnDeviceFunctions){ + NULL + }; } -gnCommandFunctions loadFunctionLoaderCommandFunctions(gnCommandFunctions* callbacks) { - return *callbacks; +gnCommandFunctions loadFunctionLoaderCommandFunctions() { + return (gnCommandFunctions){ + NULL + }; } diff --git a/projects/validation_layers/function_loader/loader/function_loader.h b/projects/validation_layers/function_loader/loader/function_loader.h index 9834f7f..9a064b5 100644 --- a/projects/validation_layers/function_loader/loader/function_loader.h +++ b/projects/validation_layers/function_loader/loader/function_loader.h @@ -3,6 +3,6 @@ #include "loader/src/gryphn_device_functions.h" #include "loader/src/gryphn_command_functions.h" -gnInstanceFunctions loadFunctionLoaderInstanceFunctions(gnInstanceFunctions* callbacks); -gnDeviceFunctions loadFunctionLoaderDeviceFunctions(gnDeviceFunctions* callbacks); -gnCommandFunctions loadFunctionLoaderCommandFunctions(gnCommandFunctions* callbacks); +gnInstanceFunctions loadFunctionLoaderInstanceFunctions(); +gnDeviceFunctions loadFunctionLoaderDeviceFunctions(); +gnCommandFunctions loadFunctionLoaderCommandFunctions(); diff --git a/projects/validation_layers/function_loader/loader/instance_functions.c b/projects/validation_layers/function_loader/loader/instance_functions.c new file mode 100644 index 0000000..f16b693 --- /dev/null +++ b/projects/validation_layers/function_loader/loader/instance_functions.c @@ -0,0 +1,95 @@ +#include "instance_functions.h" +#include "core/src/debugger/gryphn_debugger.h" +#include "core/src/output_device/gryphn_output_device.h" +#include "core/src/window_surface/gryphn_surface.h" + +gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceInfo info) { + loaderLayer* nextLayer = loaderGetNextLayer(instance); + if (nextLayer->instanceFunctions._gnCreateInstance == NULL) { + return GN_FAILED_TO_LOAD_FUNCTION; + resetLayer(instance); + } + return nextLayer->instanceFunctions._gnCreateInstance(instance, info); +} + +void checkDestroyInstance(gnInstance instance) { + loaderLayer* nextLayer = loaderGetNextLayer(instance); + if (nextLayer->instanceFunctions._gnDestroyInstance == NULL) { + gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){ + .message = gnCreateString("Failed to load destroy instance function") + }); + resetLayer(instance); + } + return nextLayer->instanceFunctions._gnDestroyInstance(instance); +} + +gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count) { + loaderLayer* nextLayer = loaderGetNextLayer(instance); + if (nextLayer->instanceFunctions._gnGetPhysicalDevices == NULL) { + gnDebuggerSetErrorMessage(instance->debugger, (gnMessageData){ + .message = gnCreateString("Failed to load get physical devices function") + }); + resetLayer(instance); + } + return nextLayer->instanceFunctions._gnGetPhysicalDevices(instance, count); +} +gnBool checkQueueCanPresentToSurface(const gnPhysicalDevice device, uint32_t queueIndex, const gnWindowSurfaceHandle windowSurface) { + loaderLayer* nextLayer = loaderGetNextLayer(device.instance); + if (nextLayer->instanceFunctions._gnQueueCanPresentToSurface == NULL) { + gnDebuggerSetErrorMessage(device.instance->debugger, (gnMessageData){ + .message = gnCreateString("Failed to load queue can present to surface function") + }); + resetLayer(device.instance); + return gnFalse; + } + return nextLayer->instanceFunctions._gnQueueCanPresentToSurface(device, queueIndex, windowSurface); +} + +gnReturnCode checkCreateOutputDevice(gnOutputDeviceHandle device, gnInstanceHandle instance, gnOutputDeviceInfo deviceInfo) { + loaderLayer* nextLayer = loaderGetNextLayer(device->instance); + if (nextLayer->instanceFunctions._gnCreateOutputDevice == NULL) { + gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ + .message = gnCreateString("Failed to load create output device function") + }); + resetLayer(device->instance); + return GN_FAILED_TO_LOAD_FUNCTION; + } + return nextLayer->instanceFunctions._gnCreateOutputDevice(device, instance, deviceInfo); +} +void checkDestroyOutputDevice(gnOutputDeviceHandle device) { + loaderLayer* nextLayer = loaderGetNextLayer(device->instance); + if (nextLayer->instanceFunctions._gnDestroyOutputDevice == NULL) { + gnDebuggerSetErrorMessage(device->instance->debugger, (gnMessageData){ + .message = gnCreateString("Failed to load destroy output device function") + }); + resetLayer(device->instance); + } + return nextLayer->instanceFunctions._gnDestroyOutputDevice(device); +} + +gnReturnCode checkCreateSurfaceMacOS(gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo) { + loaderLayer* nextLayer = loaderGetNextLayer(instance); + if (nextLayer->instanceFunctions._gnCreateMacOSWindowSurface == NULL) { return GN_FAILED_TO_LOAD_FUNCTION; } + return nextLayer->instanceFunctions._gnCreateMacOSWindowSurface(windowSurface, instance, createInfo); +} + +void checkDestroyWindowSurface(gnWindowSurfaceHandle windowSurface) { + loaderLayer* nextLayer = loaderGetNextLayer(windowSurface->instance); + if (nextLayer->instanceFunctions._gnDestroyWindowSurface == NULL) { + gnDebuggerSetErrorMessage(windowSurface->instance->debugger, (gnMessageData){ + .message = gnCreateString("Failed to load destroy create surface function") + }); + resetLayer(windowSurface->instance); + } + return nextLayer->instanceFunctions._gnDestroyWindowSurface(windowSurface); +} +gnSurfaceDetails checkGetSurfaceDetails(gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device) { + loaderLayer* nextLayer = loaderGetNextLayer(windowSurface->instance); + if (nextLayer->instanceFunctions._gnGetSurfaceDetails == NULL) { + gnDebuggerSetErrorMessage(windowSurface->instance->debugger, (gnMessageData){ + .message = gnCreateString("Failed to load get surface details function") + }); + resetLayer(windowSurface->instance); + } + return nextLayer->instanceFunctions._gnGetSurfaceDetails(windowSurface, device); +} diff --git a/projects/validation_layers/function_loader/loader/instance_functions.h b/projects/validation_layers/function_loader/loader/instance_functions.h new file mode 100644 index 0000000..7c58ae4 --- /dev/null +++ b/projects/validation_layers/function_loader/loader/instance_functions.h @@ -0,0 +1,19 @@ +#pragma once +#include "core/src/instance/gryphn_instance.h" +#include + +gnReturnCode checkCreateInstance(gnInstanceHandle instance, gnInstanceInfo info); +void checkDestroyInstance(gnInstance instance); + +gnPhysicalDevice* checkGetPhysicalDevices(gnInstanceHandle instance, uint32_t* count); +gnBool checkQueueCanPresentToSurface(const gnPhysicalDevice device, uint32_t queueIndex, const gnWindowSurfaceHandle windowSurface); + +gnReturnCode checkCreateOutputDevice(gnOutputDeviceHandle device, gnInstanceHandle instance, gnOutputDeviceInfo deviceInfo); +void checkDestroyOutputDevice(gnOutputDeviceHandle device); + +#ifdef GN_PLATFORM_MACOS +gnReturnCode checkCreateSurfaceMacOS(gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo); +#endif + +void checkDestroyWindowSurface(gnWindowSurfaceHandle windowSurface); +gnSurfaceDetails checkGetSurfaceDetails(gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device);