using System.Runtime.InteropServices; namespace Engine.Graphics.Vulkan; internal static unsafe class Vk { public delegate VkResult VkCreateInstance(VkInstanceCreateInfo* pCreateInfo, nint pAllocator, VkInstance* pInstance); public delegate void VkDestroyInstance(VkInstance instance, nint pAllocator); public delegate VkResult VkEnumeratePhysicalDevices(VkInstance instance, uint* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices); public delegate void VkGetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties* pProperties); public delegate void VkGetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties* pMemoryProperties); public delegate void VkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice, uint* pQueueFamilyPropertyCount, VkQueueFamilyProperties* pQueueFamilyProperties); public delegate VkResult VkGetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice, uint queueFamilyIndex, VkSurfaceKHR surface, VkBool32* pSupported); public delegate VkResult VkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* pSurfaceCapabilities); public delegate VkResult VkGetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint* pSurfaceFormatCount, VkSurfaceFormatKHR* pSurfaceFormats); public delegate VkResult VkGetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint* pPresentModeCount, VkPresentModeKHR* pPresentModes); public delegate VkResult VkCreateDevice(VkPhysicalDevice physicalDevice, VkDeviceCreateInfo* pCreateInfo, nint pAllocator, VkDevice* pDevice); public delegate void VkDestroyDevice(VkDevice device, nint pAllocator); public delegate void VkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, nint pAllocator); public delegate nint VkGetDeviceProcAddr(VkDevice device, byte* pName); public delegate void VkGetDeviceQueue(VkDevice device, uint queueFamilyIndex, uint queueIndex, VkQueue* pQueue); public delegate VkResult VkCreateSwapchainKHR(VkDevice device, VkSwapchainCreateInfoKHR* pCreateInfo, nint pAllocator, VkSwapchainKHR* pSwapchain); public delegate void VkDestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain, nint pAllocator); public delegate VkResult VkGetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain, uint* pSwapchainImageCount, VkImage* pSwapchainImages); public delegate VkResult VkCreateImageView(VkDevice device, VkImageViewCreateInfo* pCreateInfo, nint pAllocator, VkImageView* pImageView); public delegate void VkDestroyImageView(VkDevice device, VkImageView imageView, nint pAllocator); public delegate VkResult VkCreateShaderModule(VkDevice device, VkShaderModuleCreateInfo* pCreateInfo, nint pAllocator, VkShaderModule* pShaderModule); public delegate void VkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, nint pAllocator); public delegate VkResult VkCreatePipelineLayout(VkDevice device, VkPipelineLayoutCreateInfo* pCreateInfo, nint pAllocator, VkPipelineLayout* pPipelineLayout); public delegate void VkDestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout, nint pAllocator); public delegate VkResult VkCreateGraphicsPipelines(VkDevice device, nint pipelineCache, uint createInfoCount, VkGraphicsPipelineCreateInfo* pCreateInfos, nint pAllocator, VkPipeline* pPipelines); public delegate void VkDestroyPipeline(VkDevice device, VkPipeline pipeline, nint pAllocator); public delegate VkResult VkCreateCommandPool(VkDevice device, VkCommandPoolCreateInfo* pCreateInfo, nint pAllocator, VkCommandPool* pCommandPool); public delegate void VkDestroyCommandPool(VkDevice device, VkCommandPool commandPool, nint pAllocator); public delegate VkResult VkAllocateCommandBuffers(VkDevice device, VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers); public delegate void VkFreeCommandBuffers(VkDevice device, VkCommandPool commandPool, uint commandBufferCount, VkCommandBuffer* pCommandBuffers); public delegate VkResult VkBeginCommandBuffer(VkCommandBuffer commandBuffer, VkCommandBufferBeginInfo* pBeginInfo); public delegate VkResult VkEndCommandBuffer(VkCommandBuffer commandBuffer); public delegate VkResult VkResetCommandBuffer(VkCommandBuffer commandBuffer, uint flags); public delegate VkResult VkCreateSemaphore(VkDevice device, VkSemaphoreCreateInfo* pCreateInfo, nint pAllocator, VkSemaphore* pSemaphore); public delegate void VkDestroySemaphore(VkDevice device, VkSemaphore semaphore, nint pAllocator); public delegate VkResult VkCreateFence(VkDevice device, VkFenceCreateInfo* pCreateInfo, nint pAllocator, VkFence* pFence); public delegate void VkDestroyFence(VkDevice device, VkFence fence, nint pAllocator); public delegate VkResult VkResetFences(VkDevice device, uint fenceCount, VkFence* pFences); public delegate VkResult VkWaitForFences(VkDevice device, uint fenceCount, VkFence* pFences, VkBool32 waitAll, ulong timeout); public delegate VkResult VkGetFenceStatus(VkDevice device, VkFence fence); public delegate VkResult VkCreateBuffer(VkDevice device, VkBufferCreateInfo* pCreateInfo, nint pAllocator, VkBuffer* pBuffer); public delegate void VkDestroyBuffer(VkDevice device, VkBuffer buffer, nint pAllocator); public delegate VkResult VkCreateImage(VkDevice device, VkImageCreateInfo* pCreateInfo, nint pAllocator, VkImage* pImage); public delegate void VkDestroyImage(VkDevice device, VkImage image, nint pAllocator); public delegate void VkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements); public delegate VkResult VkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, ulong memoryOffset); public delegate VkResult VkAllocateMemory(VkDevice device, VkMemoryAllocateInfo* pAllocateInfo, nint pAllocator, VkDeviceMemory* pMemory); public delegate void VkFreeMemory(VkDevice device, VkDeviceMemory memory, nint pAllocator); public delegate VkResult VkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, ulong memoryOffset); public delegate void VkGetBufferMemoryRequirements(VkDevice device, VkBuffer buffer, VkMemoryRequirements* pMemoryRequirements); public delegate VkResult VkMapMemory(VkDevice device, VkDeviceMemory memory, ulong offset, ulong size, uint flags, void** ppData); public delegate void VkUnmapMemory(VkDevice device, VkDeviceMemory memory); public delegate void VkCmdBindPipeline(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipeline pipeline); public delegate void VkCmdSetViewport(VkCommandBuffer commandBuffer, uint firstViewport, uint viewportCount, VkViewport* pViewports); public delegate void VkCmdSetScissor(VkCommandBuffer commandBuffer, uint firstScissor, uint scissorCount, VkRect2D* pScissors); public delegate void VkCmdBindVertexBuffers(VkCommandBuffer commandBuffer, uint firstBinding, uint bindingCount, VkBuffer* pBuffers, ulong* pOffsets); public delegate void VkCmdDraw(VkCommandBuffer commandBuffer, uint vertexCount, uint instanceCount, uint firstVertex, uint firstInstance); public delegate void VkCmdDrawIndexed(VkCommandBuffer commandBuffer, uint indexCount, uint instanceCount, uint firstIndex, int vertexOffset, uint firstInstance); public delegate void VkCmdBindIndexBuffer(VkCommandBuffer commandBuffer, VkBuffer buffer, ulong offset, int indexType); public delegate void VkCmdBeginRendering(VkCommandBuffer commandBuffer, VkRenderingInfo* pRenderingInfo); public delegate void VkCmdEndRendering(VkCommandBuffer commandBuffer); public delegate void VkCmdPipelineBarrier2(VkCommandBuffer commandBuffer, VkDependencyInfo* pDependencyInfo); public delegate void VkCmdCopyBuffer(VkCommandBuffer commandBuffer, VkBuffer srcBuffer, VkBuffer dstBuffer, uint regionCount, VkBufferCopy* pRegions); public delegate void VkCmdPushConstants(VkCommandBuffer commandBuffer, VkPipelineLayout layout, VkShaderStageFlags stageFlags, uint offset, uint size, void* pValues); public delegate void VkCmdBindDescriptorSets(VkCommandBuffer commandBuffer, VkPipelineBindPoint pipelineBindPoint, VkPipelineLayout layout, uint firstSet, uint descriptorSetCount, VkDescriptorSet* pDescriptorSets, uint dynamicOffsetCount, uint* pDynamicOffsets); public delegate VkResult VkCreateDescriptorSetLayout(VkDevice device, VkDescriptorSetLayoutCreateInfo* pCreateInfo, nint pAllocator, VkDescriptorSetLayout* pSetLayout); public delegate void VkDestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout, nint pAllocator); public delegate VkResult VkCreateDescriptorPool(VkDevice device, VkDescriptorPoolCreateInfo* pCreateInfo, nint pAllocator, VkDescriptorPool* pDescriptorPool); public delegate void VkDestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool, nint pAllocator); public delegate VkResult VkAllocateDescriptorSets(VkDevice device, VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets); public delegate void VkUpdateDescriptorSets(VkDevice device, uint descriptorWriteCount, VkWriteDescriptorSet* pDescriptorWrites, uint descriptorCopyCount, nint pDescriptorCopies); public delegate VkResult VkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, ulong timeout, VkSemaphore semaphore, VkFence fence, uint* pImageIndex); public delegate VkResult VkQueueSubmit2(VkQueue queue, uint submitCount, VkSubmitInfo2* pSubmits, VkFence fence); public delegate VkResult VkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo); public delegate VkResult VkDeviceWaitIdle(VkDevice device); public delegate VkResult VkQueueWaitIdle(VkQueue queue); public delegate VkResult VkCreateDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, nint pAllocator, VkDebugUtilsMessengerEXT* pMessenger); public delegate void VkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT messenger, nint pAllocator); public static VkCreateInstance vkCreateInstance; public static VkDestroyInstance vkDestroyInstance; public static VkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; public static VkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; public static VkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; public static VkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties; public static VkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; public static VkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; public static VkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; public static VkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; public static VkCreateDevice vkCreateDevice; public static VkDestroyDevice vkDestroyDevice; public static VkDestroySurfaceKHR vkDestroySurfaceKHR; public static VkGetDeviceProcAddr vkGetDeviceProcAddr; public static VkGetDeviceQueue vkGetDeviceQueue; public static VkCreateSwapchainKHR vkCreateSwapchainKHR; public static VkDestroySwapchainKHR vkDestroySwapchainKHR; public static VkGetSwapchainImagesKHR vkGetSwapchainImagesKHR; public static VkCreateImageView vkCreateImageView; public static VkDestroyImageView vkDestroyImageView; public static VkCreateShaderModule vkCreateShaderModule; public static VkDestroyShaderModule vkDestroyShaderModule; public static VkCreatePipelineLayout vkCreatePipelineLayout; public static VkDestroyPipelineLayout vkDestroyPipelineLayout; public static VkCreateGraphicsPipelines vkCreateGraphicsPipelines; public static VkDestroyPipeline vkDestroyPipeline; public static VkCreateCommandPool vkCreateCommandPool; public static VkDestroyCommandPool vkDestroyCommandPool; public static VkAllocateCommandBuffers vkAllocateCommandBuffers; public static VkFreeCommandBuffers vkFreeCommandBuffers; public static VkBeginCommandBuffer vkBeginCommandBuffer; public static VkEndCommandBuffer vkEndCommandBuffer; public static VkResetCommandBuffer vkResetCommandBuffer; public static VkCreateSemaphore vkCreateSemaphore; public static VkDestroySemaphore vkDestroySemaphore; public static VkCreateFence vkCreateFence; public static VkDestroyFence vkDestroyFence; public static VkResetFences vkResetFences; public static VkWaitForFences vkWaitForFences; public static VkGetFenceStatus vkGetFenceStatus; public static VkCreateBuffer vkCreateBuffer; public static VkDestroyBuffer vkDestroyBuffer; public static VkCreateImage vkCreateImage; public static VkDestroyImage vkDestroyImage; public static VkGetImageMemoryRequirements vkGetImageMemoryRequirements; public static VkBindImageMemory vkBindImageMemory; public static VkAllocateMemory vkAllocateMemory; public static VkFreeMemory vkFreeMemory; public static VkBindBufferMemory vkBindBufferMemory; public static VkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; public static VkMapMemory vkMapMemory; public static VkUnmapMemory vkUnmapMemory; public static VkCmdBindPipeline vkCmdBindPipeline; public static VkCmdSetViewport vkCmdSetViewport; public static VkCmdSetScissor vkCmdSetScissor; public static VkCmdBindVertexBuffers vkCmdBindVertexBuffers; public static VkCmdDraw vkCmdDraw; public static VkCmdDrawIndexed vkCmdDrawIndexed; public static VkCmdBindIndexBuffer vkCmdBindIndexBuffer; public static VkCmdBeginRendering vkCmdBeginRendering; public static VkCmdEndRendering vkCmdEndRendering; public static VkCmdPipelineBarrier2 vkCmdPipelineBarrier2; public static VkCmdCopyBuffer vkCmdCopyBuffer; public static VkCmdPushConstants vkCmdPushConstants; public static VkCmdBindDescriptorSets vkCmdBindDescriptorSets; public static VkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; public static VkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; public static VkCreateDescriptorPool vkCreateDescriptorPool; public static VkDestroyDescriptorPool vkDestroyDescriptorPool; public static VkAllocateDescriptorSets vkAllocateDescriptorSets; public static VkUpdateDescriptorSets vkUpdateDescriptorSets; public static VkAcquireNextImageKHR vkAcquireNextImageKHR; public static VkQueueSubmit2 vkQueueSubmit2; public static VkQueuePresentKHR vkQueuePresentKHR; public static VkDeviceWaitIdle vkDeviceWaitIdle; public static VkQueueWaitIdle vkQueueWaitIdle; public static VkCreateDebugUtilsMessengerEXT vkCreateDebugUtilsMessengerEXT; public static VkDestroyDebugUtilsMessengerEXT vkDestroyDebugUtilsMessengerEXT; public static void LoadInstanceFunctions(VkInstance instance) { var p = instance.Handle; vkDestroyInstance = Load(p, "vkDestroyInstance"); vkEnumeratePhysicalDevices = Load(p, "vkEnumeratePhysicalDevices"); vkGetPhysicalDeviceProperties = Load(p, "vkGetPhysicalDeviceProperties"); vkGetPhysicalDeviceMemoryProperties = Load(p, "vkGetPhysicalDeviceMemoryProperties"); vkGetPhysicalDeviceQueueFamilyProperties = Load(p, "vkGetPhysicalDeviceQueueFamilyProperties"); vkGetPhysicalDeviceSurfaceSupportKHR = Load(p, "vkGetPhysicalDeviceSurfaceSupportKHR"); vkGetPhysicalDeviceSurfaceCapabilitiesKHR = Load(p, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); vkGetPhysicalDeviceSurfaceFormatsKHR = Load(p, "vkGetPhysicalDeviceSurfaceFormatsKHR"); vkGetPhysicalDeviceSurfacePresentModesKHR = Load(p, "vkGetPhysicalDeviceSurfacePresentModesKHR"); vkCreateDevice = Load(p, "vkCreateDevice"); vkDestroyDevice = Load(p, "vkDestroyDevice"); vkDestroySurfaceKHR = Load(p, "vkDestroySurfaceKHR"); vkGetDeviceProcAddr = Load(p, "vkGetDeviceProcAddr"); TryLoadDebugUtils(p); } public static void LoadDeviceFunctions(VkDevice device) { var p = device.Handle; vkGetDeviceQueue = LoadDev(p, "vkGetDeviceQueue"); vkCreateSwapchainKHR = LoadDev(p, "vkCreateSwapchainKHR"); vkDestroySwapchainKHR = LoadDev(p, "vkDestroySwapchainKHR"); vkGetSwapchainImagesKHR = LoadDev(p, "vkGetSwapchainImagesKHR"); vkCreateImageView = LoadDev(p, "vkCreateImageView"); vkDestroyImageView = LoadDev(p, "vkDestroyImageView"); vkCreateShaderModule = LoadDev(p, "vkCreateShaderModule"); vkDestroyShaderModule = LoadDev(p, "vkDestroyShaderModule"); vkCreatePipelineLayout = LoadDev(p, "vkCreatePipelineLayout"); vkDestroyPipelineLayout = LoadDev(p, "vkDestroyPipelineLayout"); vkCreateGraphicsPipelines = LoadDev(p, "vkCreateGraphicsPipelines"); vkDestroyPipeline = LoadDev(p, "vkDestroyPipeline"); vkCreateCommandPool = LoadDev(p, "vkCreateCommandPool"); vkDestroyCommandPool = LoadDev(p, "vkDestroyCommandPool"); vkAllocateCommandBuffers = LoadDev(p, "vkAllocateCommandBuffers"); vkFreeCommandBuffers = LoadDev(p, "vkFreeCommandBuffers"); vkBeginCommandBuffer = LoadDev(p, "vkBeginCommandBuffer"); vkEndCommandBuffer = LoadDev(p, "vkEndCommandBuffer"); vkResetCommandBuffer = LoadDev(p, "vkResetCommandBuffer"); vkCreateSemaphore = LoadDev(p, "vkCreateSemaphore"); vkDestroySemaphore = LoadDev(p, "vkDestroySemaphore"); vkCreateFence = LoadDev(p, "vkCreateFence"); vkDestroyFence = LoadDev(p, "vkDestroyFence"); vkResetFences = LoadDev(p, "vkResetFences"); vkWaitForFences = LoadDev(p, "vkWaitForFences"); vkGetFenceStatus = LoadDev(p, "vkGetFenceStatus"); vkCreateBuffer = LoadDev(p, "vkCreateBuffer"); vkDestroyBuffer = LoadDev(p, "vkDestroyBuffer"); vkCreateImage = LoadDev(p, "vkCreateImage"); vkDestroyImage = LoadDev(p, "vkDestroyImage"); vkGetImageMemoryRequirements = LoadDev(p, "vkGetImageMemoryRequirements"); vkBindImageMemory = LoadDev(p, "vkBindImageMemory"); vkAllocateMemory = LoadDev(p, "vkAllocateMemory"); vkFreeMemory = LoadDev(p, "vkFreeMemory"); vkBindBufferMemory = LoadDev(p, "vkBindBufferMemory"); vkGetBufferMemoryRequirements = LoadDev(p, "vkGetBufferMemoryRequirements"); vkMapMemory = LoadDev(p, "vkMapMemory"); vkUnmapMemory = LoadDev(p, "vkUnmapMemory"); vkCmdBindPipeline = LoadDev(p, "vkCmdBindPipeline"); vkCmdSetViewport = LoadDev(p, "vkCmdSetViewport"); vkCmdSetScissor = LoadDev(p, "vkCmdSetScissor"); vkCmdBindVertexBuffers = LoadDev(p, "vkCmdBindVertexBuffers"); vkCmdDraw = LoadDev(p, "vkCmdDraw"); vkCmdDrawIndexed = LoadDev(p, "vkCmdDrawIndexed"); vkCmdBindIndexBuffer = LoadDev(p, "vkCmdBindIndexBuffer"); vkCmdBeginRendering = LoadDev(p, "vkCmdBeginRendering"); vkCmdEndRendering = LoadDev(p, "vkCmdEndRendering"); vkCmdPipelineBarrier2 = LoadDev(p, "vkCmdPipelineBarrier2"); vkCmdCopyBuffer = LoadDev(p, "vkCmdCopyBuffer"); vkCmdPushConstants = LoadDev(p, "vkCmdPushConstants"); vkCmdBindDescriptorSets = LoadDev(p, "vkCmdBindDescriptorSets"); vkCreateDescriptorSetLayout = LoadDev(p, "vkCreateDescriptorSetLayout"); vkDestroyDescriptorSetLayout = LoadDev(p, "vkDestroyDescriptorSetLayout"); vkCreateDescriptorPool = LoadDev(p, "vkCreateDescriptorPool"); vkDestroyDescriptorPool = LoadDev(p, "vkDestroyDescriptorPool"); vkAllocateDescriptorSets = LoadDev(p, "vkAllocateDescriptorSets"); vkUpdateDescriptorSets = LoadDev(p, "vkUpdateDescriptorSets"); vkAcquireNextImageKHR = LoadDev(p, "vkAcquireNextImageKHR"); vkQueueSubmit2 = LoadDev(p, "vkQueueSubmit2"); vkQueuePresentKHR = LoadDev(p, "vkQueuePresentKHR"); vkDeviceWaitIdle = LoadDev(p, "vkDeviceWaitIdle"); vkQueueWaitIdle = LoadDev(p, "vkQueueWaitIdle"); } private static void TryLoadDebugUtils(nint instance) { try { vkCreateDebugUtilsMessengerEXT = Load(instance, "vkCreateDebugUtilsMessengerEXT"); vkDestroyDebugUtilsMessengerEXT = Load(instance, "vkDestroyDebugUtilsMessengerEXT"); } catch { vkCreateDebugUtilsMessengerEXT = null!; vkDestroyDebugUtilsMessengerEXT = null!; } } private static T Load(nint instance, string name) where T : Delegate { fixed (byte* pName = VulkanString.ToUtf8Terminated(name)) { var addr = VulkanNative.vkGetInstanceProcAddr(instance, pName); if (addr == 0) throw new EntryPointNotFoundException($"vkGetInstanceProcAddr returned null for: {name}"); return Marshal.GetDelegateForFunctionPointer(addr); } } private static T LoadDev(nint device, string name) where T : Delegate { fixed (byte* pName = VulkanString.ToUtf8Terminated(name)) { var addr = vkGetDeviceProcAddr(new VkDevice { Handle = device }, pName); if (addr == 0) { addr = VulkanNative.vkGetInstanceProcAddr(0, pName); if (addr == 0) throw new EntryPointNotFoundException($"vkGetDeviceProcAddr returned null for: {name}"); } return Marshal.GetDelegateForFunctionPointer(addr); } } }