diff --git a/src/core/debugger/gryphn_debugger.h b/src/core/debugger/gryphn_debugger.h index cb16461..d9bc83b 100644 --- a/src/core/debugger/gryphn_debugger.h +++ b/src/core/debugger/gryphn_debugger.h @@ -30,7 +30,8 @@ typedef gnBool (*gnDebuggerCallback)( void* userData); typedef enum gnDebuggerLayer { - GN_DEBUGGER_LAYER_PLATFORM // enable platform (vulkan validation) layers + GN_DEBUGGER_LAYER_PLATFORM, // enable platform (vulkan validation) layers + GN_DEBUGGER_LAYER_FUNCTIONS // enable the checks on every function } gnDebuggerLayer; typedef struct gnDebuggerInfo { diff --git a/src/core/gryphn_platform_functions.h b/src/core/gryphn_platform_functions.h index cb0dbbf..0674498 100644 --- a/src/core/gryphn_platform_functions.h +++ b/src/core/gryphn_platform_functions.h @@ -20,14 +20,14 @@ #include "core/textures/gryphn_texture.h" #include "core/uniforms/gryphn_uniform_pool.h" -typedef struct gnFunctions_t { +typedef struct gnInstanceFunctions { gnReturnCode (*_gnCreateInstance)(gnInstanceHandle instance, gnInstanceInfo info); void (*_gnDestroyInstance)(gnInstanceHandle instance); gnPhysicalDevice* (*_gnGetPhysicalDevices)(gnInstanceHandle instance, uint32_t* count); gnBool (*_gnQueueCanPresentToSurface)(const gnPhysicalDevice device, uint32_t queueIndex, const gnWindowSurfaceHandle windowSurface); - gnReturnCode (*_gnCreateOutputDevoce)(gnOutputDeviceHandle device, gnInstanceHandle instance, struct gnOutputDeviceInfo_t deviceInfo); + gnReturnCode (*_gnCreateOutputDevice)(gnOutputDeviceHandle device, gnInstanceHandle instance, struct gnOutputDeviceInfo_t deviceInfo); void (*_gnDestroyOutputDevice)(gnOutputDeviceHandle device); @@ -51,7 +51,7 @@ typedef struct gnFunctions_t { void (*_gnDestroyWindowSurface)(gnWindowSurfaceHandle windowSurface); gnSurfaceDetails (*_gnGetSurfaceDetails)(gnWindowSurfaceHandle windowSurface, struct gnPhysicalDevice_t device); -} gnFunctions; +} gnInstanceFunctions; #include "core/presentation_queue/gryphn_presentation_queue.h" typedef struct gnDeviceFunctions_t { diff --git a/src/core/instance/gryphn_instance.c b/src/core/instance/gryphn_instance.c index bb7bed3..0678a56 100644 --- a/src/core/instance/gryphn_instance.c +++ b/src/core/instance/gryphn_instance.c @@ -2,9 +2,99 @@ #include "init/gryphn_init.h" #include #include "core/instance/gryphn_instance.h" +#include "core/debugger/gryphn_debugger.h" +#include "core/gryphn_handles.h" #include "stdio.h" -gnReturnCode gnCreateInstance(gnInstanceHandle* instanceHandlePtr, struct gnInstanceInfo_t info) { +#define GN_VALIDATED_FUNCTION(where, func, param_list, args, code) \ +code _##func##Fn param_list { \ + if ((where->unvalidatedFunctions)->_##func == NULL) { \ + gnDebuggerSetErrorMessage(where->debugger, (gnMessageData){ \ + "function " #func " was not loaded" \ + }); \ + } \ + return (where->unvalidatedFunctions)->_##func args; \ +} + +#define GN_VALIDATED_FUNCTION_ERROR_CODE(where, func, param_list, args) \ +gnErrorCode _##func##Fn param_list { \ + if ((where->unvalidatedFunctions)->_##func == NULL) { \ + gnDebuggerSetErrorMessage(where->debugger, (gnMessageData){ \ + "function " #func " was not loaded" \ + }); \ + return GN_FAILED_TO_LOAD_FUNCTION; \ + } \ + return (where->unvalidatedFunctions)->_##func args; \ +} + + +#define GN_VALIDATED_FUNCTION_VOID(where, func, param_list, args) \ +void _##func##Fn param_list { \ + if ((where->unvalidatedFunctions)->_##func == NULL) { \ + gnDebuggerSetErrorMessage(where->debugger, (gnMessageData){ \ + "function " #func " was not loaded" \ + }); \ + return;\ + } \ + (where->unvalidatedFunctions)->_##func args;\ +} + +GN_VALIDATED_FUNCTION_ERROR_CODE(instance, gnCreateInstance, + (gnInstanceHandle instance, gnInstanceInfo info), + (instance, info)) +GN_VALIDATED_FUNCTION_VOID(instance, gnDestroyInstance, + (gnInstanceHandle instance), + (instance)) +GN_VALIDATED_FUNCTION(instance, gnGetPhysicalDevices, + (gnInstanceHandle instance, uint32_t* count), + (instance, count), gnPhysicalDevice*) +GN_VALIDATED_FUNCTION(device.instance, gnQueueCanPresentToSurface, + (const gnPhysicalDevice device, uint32_t queueIndex, const gnWindowSurfaceHandle windowSurface), + (device, queueIndex, windowSurface), gnBool) +GN_VALIDATED_FUNCTION_ERROR_CODE(device->instance, gnCreateOutputDevice, + (gnOutputDeviceHandle device, gnInstanceHandle instance, struct gnOutputDeviceInfo_t deviceInfo), + (device, instance, deviceInfo)) +GN_VALIDATED_FUNCTION_VOID(device->instance, gnDestroyOutputDevice, + (gnOutputDeviceHandle device), + (device)) + + +#ifdef GN_PLATFORM_LINUX + #ifdef GN_WINDOW_X11 + GN_VALIDATED_FUNCTION_ERROR_CODE(instance, gnCreateX11WindowSurface, + (gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnX11WindowSurfaceInfo createInfo), + (windowSurface, instance, createInfo)) + #endif + #ifdef GN_WINDOW_WAYLAND + GN_VALIDATED_FUNCTION_ERROR_CODE(instance, gnCreateWaylandWindowSurface, + (gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnWaylandWindowSurfaceInfo createInfo), + (windowSurface, instance, createInfo)) + #endif +#endif + +#ifdef GN_PLATFORM_WIN32 + GN_VALIDATED_FUNCTION_ERROR_CODE(instance, gnCreateWin32WindowSurface, + (gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnWin32WindowSurfaceInfo createInfo), + (windowSurface, instance, createInfo)) +#endif + +#ifdef GN_PLATFORM_MACOS + GN_VALIDATED_FUNCTION_ERROR_CODE(instance, gnCreateMacOSWindowSurface, + (gnWindowSurfaceHandle windowSurface, gnInstanceHandle instance, gnMacOSWindowSurfaceInfo createInfo), + (windowSurface, instance, createInfo)) +#endif + +GN_VALIDATED_FUNCTION_VOID(windowSurface->instance, gnDestroyWindowSurface, + (gnWindowSurfaceHandle windowSurface), + (windowSurface)) + +GN_VALIDATED_FUNCTION(windowSurface->instance, gnGetSurfaceDetails, + (gnWindowSurfaceHandle windowSurface, gnPhysicalDevice device), + (windowSurface, device), gnSurfaceDetails) + + + +gnReturnCode gnCreateInstance(gnInstanceHandle* instanceHandlePtr, gnInstanceInfo info) { *instanceHandlePtr = malloc(sizeof(struct gnInstance_t)); gnInstanceHandle instance = *instanceHandlePtr; instance->debugger = NULL; @@ -14,11 +104,45 @@ gnReturnCode gnCreateInstance(gnInstanceHandle* instanceHandlePtr, struct gnInst instance->debugger = NULL; instance->dynamicLib = gnLoadRenderingDLL(info.renderingAPI); if (instance->dynamicLib == NULL) return GN_UNABLE_TO_LOAD_DYNAMIC_LIBARRY; - instance->functions = malloc(sizeof(struct gnFunctions_t)); + instance->functions = gnLoadFunctions(instance); + + gnBool validateFunctions = gnFalse; + for (int i = 0; i < info.debugger->info.layerCount; i++) + if (info.debugger->info.layers[i] == GN_DEBUGGER_LAYER_FUNCTIONS) validateFunctions = gnTrue; + + if (validateFunctions) { + instance->functions->_gnCreateInstance = _gnCreateInstanceFn; + instance->functions->_gnDestroyInstance = _gnDestroyInstanceFn; + instance->functions->_gnGetPhysicalDevices = _gnGetPhysicalDevicesFn; + instance->functions->_gnQueueCanPresentToSurface = _gnQueueCanPresentToSurfaceFn; + instance->functions->_gnCreateOutputDevice = _gnCreateOutputDeviceFn; + instance->functions->_gnDestroyOutputDevice = _gnDestroyOutputDeviceFn; + + #ifdef GN_PLATFORM_LINUX + #ifdef GN_WINDOW_X11 + instance->functions->_gnCreateX11WindowSurface = _gnCreateX11WindowSurfaceFn; + #endif + #ifdef GN_WINDOW_WAYLAND + instance->functions->_gnCreateWaylandWindowSurface = _gnCreateWaylandWindowSurfaceFn; + #endif + #endif + + #ifdef GN_PLATFORM_WIN32 + instance->functions->_gnCreateWaylandWindowSurface = _gnCreateWaylandWindowSurfaceFn; + #endif + + #ifdef GN_PLATFORM_MACOS + instance->functions->_gnCreateMacOSWindowSurface = _gnCreateMacOSWindowSurfaceFn; + #endif + instance->functions->_gnDestroyWindowSurface = _gnDestroyWindowSurfaceFn; + instance->functions->_gnGetSurfaceDetails = _gnGetSurfaceDetailsFn; + + instance->unvalidatedFunctions = gnLoadFunctions(instance); + } + instance->loadCommandFunctions = gnFalse; instance->loadDeviceFunctions = gnFalse; instance->debugger = info.debugger; - gnLoadFunctions(instance->dynamicLib, instance->functions); return instance->functions->_gnCreateInstance(instance, info); } diff --git a/src/core/instance/gryphn_instance.h b/src/core/instance/gryphn_instance.h index 74bc38f..45472ec 100644 --- a/src/core/instance/gryphn_instance.h +++ b/src/core/instance/gryphn_instance.h @@ -3,9 +3,7 @@ #include "core/gryphn_rendering_api.h" #include "core/gryphn_handles.h" -struct gnPlatformInstance_t; -struct gnFunctions_t; -struct gnDynamicLibrary_t; +typedef struct gnInstanceFunctions gnInstanceFunctions; typedef struct gnInstanceInfo_t { gnString applicationName; @@ -27,7 +25,7 @@ struct gnInstance_t { struct gnDynamicLibrary_t* dynamicLib; - struct gnFunctions_t* functions; + gnInstanceFunctions *functions, *unvalidatedFunctions; struct gnDeviceFunctions_t* deviceFunctions; struct gnCommandFunctions_t* commandFunctions; diff --git a/src/core/instance/init/gryphn_init.c b/src/core/instance/init/gryphn_init.c index ab1f974..377d89a 100644 --- a/src/core/instance/init/gryphn_init.c +++ b/src/core/instance/init/gryphn_init.c @@ -37,36 +37,38 @@ struct gnDynamicLibrary_t* gnLoadRenderingDLL(gnRenderingAPI renderingAPI) { return gnLoadDynamicLibrary(gnCombineStrings(gnCreateString("gryphn/rendering_apis/"), libName)); } -void gnLoadFunctions(struct gnDynamicLibrary_t* lib, struct gnFunctions_t* functions) { - gnLoadDLLFunction(lib, functions->_gnCreateInstance, "gnCreateInstanceFn"); - gnLoadDLLFunction(lib, functions->_gnDestroyInstance, "gnDestroyInstanceFn"); - // gnLoadDLLFunction(lib, functions->_gnCreateDebugger, "gnCreateDebuggerFn"); - // gnLoadDLLFunction(lib, functions->_gnDestroyDebugger, "gnDestroyDebuggerFn"); - gnLoadDLLFunction(lib, functions->_gnGetPhysicalDevices, "gnGetPhysicalDevicesFn"); - gnLoadDLLFunction(lib, functions->_gnQueueCanPresentToSurface, "gnQueueCanPresentToSurfaceFn"); - gnLoadDLLFunction(lib, functions->_gnCreateOutputDevoce, "gnCreateOutputDeviceFn"); - gnLoadDLLFunction(lib, functions->_gnDestroyOutputDevice, "gnDestroyOutputDeviceFn"); +gnInstanceFunctions* gnLoadFunctions(gnInstanceHandle instance) { + gnInstanceFunctions* functions = malloc(sizeof(gnInstanceFunctions)); + + gnLoadDLLFunction(instance->dynamicLib, functions->_gnCreateInstance, "gnCreateInstanceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnDestroyInstance, "gnDestroyInstanceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnGetPhysicalDevices, "gnGetPhysicalDevicesFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnQueueCanPresentToSurface, "gnQueueCanPresentToSurfaceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnCreateOutputDevice, "gnCreateOutputDeviceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnDestroyOutputDevice, "gnDestroyOutputDeviceFn"); #ifdef GN_PLATFORM_LINUX #ifdef GN_WINDOW_X11 - gnLoadDLLFunction(lib, functions->_gnCreateX11WindowSurface, "gnCreateX11WindowSurfaceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnCreateX11WindowSurface, "gnCreateX11WindowSurfaceFn"); #endif #ifdef GN_WINDOW_WAYLAND - gnLoadDLLFunction(lib, functions->_gnCreateWaylandWindowSurface, "gnCreateWaylandWindowSurfaceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnCreateWaylandWindowSurface, "gnCreateWaylandWindowSurfaceFn"); #endif #endif #ifdef GN_PLATFORM_WIN32 - gnLoadDLLFunction(lib, functions->_gnCreateWin32WindowSurface, "gnCreateWin32WindowSurfaceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnCreateWin32WindowSurface, "gnCreateWin32WindowSurfaceFn"); #endif #ifdef GN_PLATFORM_MACOS - gnLoadDLLFunction(lib, functions->_gnCreateMacOSWindowSurface, "gnCreateMacOSWindowSurfaceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnCreateMacOSWindowSurface, "gnCreateMacOSWindowSurfaceFn"); #endif - gnLoadDLLFunction(lib, functions->_gnDestroyWindowSurface, "gnDestroyWindowSurfaceFn"); - gnLoadDLLFunction(lib, functions->_gnGetSurfaceDetails, "gnGetSurfaceDetailsFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnDestroyWindowSurface, "gnDestroyWindowSurfaceFn"); + gnLoadDLLFunction(instance->dynamicLib, functions->_gnGetSurfaceDetails, "gnGetSurfaceDetailsFn"); + + return functions; } void gnLoadDeviceFunctions(struct gnDynamicLibrary_t* lib, struct gnDeviceFunctions_t* functions) { diff --git a/src/core/instance/init/gryphn_init.h b/src/core/instance/init/gryphn_init.h index 85a0efe..ca68bce 100644 --- a/src/core/instance/init/gryphn_init.h +++ b/src/core/instance/init/gryphn_init.h @@ -6,12 +6,6 @@ gnBool gnIsAPISupported(gnRenderingAPI RenderingAPI); struct gnDynamicLibrary_t* gnLoadRenderingDLL(gnRenderingAPI RenderingAPI); -void gnLoadFunctions(struct gnDynamicLibrary_t* lib, struct gnFunctions_t* functions); +gnInstanceFunctions* gnLoadFunctions(gnInstance instance); void gnLoadDeviceFunctions(struct gnDynamicLibrary_t* lib, struct gnDeviceFunctions_t* functions); void gnLoadCommandFunctions(struct gnDynamicLibrary_t* lib, struct gnCommandFunctions_t* function); - -// #ifdef GN_REVEAL_IMPL -// gnErrorCode gnInit(gnRenderingAPI RenderingAPI); -// void gnDestroy(); -// void* gnLoadFunction(gnString name); -// #endif diff --git a/src/core/output_device/gryphn_output_device.c b/src/core/output_device/gryphn_output_device.c index d3ae1f5..52329b9 100644 --- a/src/core/output_device/gryphn_output_device.c +++ b/src/core/output_device/gryphn_output_device.c @@ -18,7 +18,7 @@ gnReturnCode gnCreateOutputDevice(gnOutputDeviceHandle* outputDevice, gnInstance (*outputDevice)->instance = instance; (*outputDevice)->physicalDevice = deviceInfo.physicalDevice; (*outputDevice)->deviceInfo = deviceInfo; - return instance->functions->_gnCreateOutputDevoce(*outputDevice, instance, deviceInfo); + return instance->functions->_gnCreateOutputDevice(*outputDevice, instance, deviceInfo); } void gnWaitForDevice(gnOutputDeviceHandle device) { device->deviceFunctions->_gnWaitForDevice(device);