+enum VulkanExtensions {
+ EXT_EXTERNAL_DMABUF_MEMORY = 1 << 0, /* VK_EXT_external_memory_dma_buf */
+ EXT_DRM_MODIFIER_FLAGS = 1 << 1, /* VK_EXT_image_drm_format_modifier */
+ EXT_EXTERNAL_FD_MEMORY = 1 << 2, /* VK_KHR_external_memory_fd */
+ EXT_EXTERNAL_FD_SEM = 1 << 3, /* VK_KHR_external_semaphore_fd */
+ EXT_EXTERNAL_HOST_MEMORY = 1 << 4, /* VK_EXT_external_memory_host */
+ EXT_PUSH_DESCRIPTORS = 1 << 5, /* VK_KHR_push_descriptor */
+ EXT_DEBUG_UTILS = 1 << 6, /* VK_EXT_debug_utils */
+
+ EXT_NO_FLAG = 1 << 31,
+};
+
+#define FN_LIST(MACRO) \
+ /* Instance */ \
+ MACRO(0, 0, EXT_NO_FLAG, EnumerateInstanceExtensionProperties) \
+ MACRO(0, 0, EXT_NO_FLAG, CreateInstance) \
+ MACRO(1, 0, EXT_NO_FLAG, DestroyInstance) \
+ \
+ /* Debug */ \
+ MACRO(1, 0, EXT_NO_FLAG, CreateDebugUtilsMessengerEXT) \
+ MACRO(1, 0, EXT_NO_FLAG, DestroyDebugUtilsMessengerEXT) \
+ \
+ /* Device */ \
+ MACRO(1, 0, EXT_NO_FLAG, GetDeviceProcAddr) \
+ MACRO(1, 0, EXT_NO_FLAG, CreateDevice) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceFeatures) \
+ MACRO(1, 0, EXT_NO_FLAG, DestroyDevice) \
+ \
+ MACRO(1, 0, EXT_NO_FLAG, EnumeratePhysicalDevices) \
+ MACRO(1, 0, EXT_NO_FLAG, EnumerateDeviceExtensionProperties) \
+ \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceProperties2) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceMemoryProperties) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceFormatProperties2) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceImageFormatProperties2) \
+ MACRO(1, 0, EXT_NO_FLAG, GetPhysicalDeviceQueueFamilyProperties) \
+ \
+ /* Command pool */ \
+ MACRO(1, 1, EXT_NO_FLAG, CreateCommandPool) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyCommandPool) \
+ \
+ /* Command buffer */ \
+ MACRO(1, 1, EXT_NO_FLAG, AllocateCommandBuffers) \
+ MACRO(1, 1, EXT_NO_FLAG, BeginCommandBuffer) \
+ MACRO(1, 1, EXT_NO_FLAG, EndCommandBuffer) \
+ MACRO(1, 1, EXT_NO_FLAG, FreeCommandBuffers) \
+ \
+ /* Queue */ \
+ MACRO(1, 1, EXT_NO_FLAG, GetDeviceQueue) \
+ MACRO(1, 1, EXT_NO_FLAG, QueueSubmit) \
+ \
+ /* Fences */ \
+ MACRO(1, 1, EXT_NO_FLAG, CreateFence) \
+ MACRO(1, 1, EXT_NO_FLAG, WaitForFences) \
+ MACRO(1, 1, EXT_NO_FLAG, ResetFences) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyFence) \
+ \
+ /* Semaphores */ \
+ MACRO(1, 1, EXT_EXTERNAL_FD_SEM, GetSemaphoreFdKHR) \
+ MACRO(1, 1, EXT_NO_FLAG, CreateSemaphore) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroySemaphore) \
+ \
+ /* Memory */ \
+ MACRO(1, 1, EXT_EXTERNAL_FD_MEMORY, GetMemoryFdKHR) \
+ MACRO(1, 1, EXT_NO_FLAG, GetMemoryFdPropertiesKHR) \
+ MACRO(1, 1, EXT_EXTERNAL_HOST_MEMORY, GetMemoryHostPointerPropertiesEXT) \
+ MACRO(1, 1, EXT_NO_FLAG, AllocateMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, MapMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, FlushMappedMemoryRanges) \
+ MACRO(1, 1, EXT_NO_FLAG, InvalidateMappedMemoryRanges) \
+ MACRO(1, 1, EXT_NO_FLAG, UnmapMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, FreeMemory) \
+ \
+ /* Commands */ \
+ MACRO(1, 1, EXT_NO_FLAG, CmdPipelineBarrier) \
+ MACRO(1, 1, EXT_NO_FLAG, CmdCopyBufferToImage) \
+ MACRO(1, 1, EXT_NO_FLAG, CmdCopyImageToBuffer) \
+ \
+ /* Buffer */ \
+ MACRO(1, 1, EXT_NO_FLAG, GetBufferMemoryRequirements2) \
+ MACRO(1, 1, EXT_NO_FLAG, CreateBuffer) \
+ MACRO(1, 1, EXT_NO_FLAG, BindBufferMemory) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyBuffer) \
+ \
+ /* Image */ \
+ MACRO(1, 1, EXT_DRM_MODIFIER_FLAGS, GetImageDrmFormatModifierPropertiesEXT) \
+ MACRO(1, 1, EXT_NO_FLAG, GetImageMemoryRequirements2) \
+ MACRO(1, 1, EXT_NO_FLAG, CreateImage) \
+ MACRO(1, 1, EXT_NO_FLAG, BindImageMemory2) \
+ MACRO(1, 1, EXT_NO_FLAG, GetImageSubresourceLayout) \
+ MACRO(1, 1, EXT_NO_FLAG, DestroyImage)
+
+#define PFN_DEF(req_inst, req_dev, ext_flag, name) \
+ PFN_vk##name name;
+
+typedef struct VulkanFunctions {
+ FN_LIST(PFN_DEF)
+} VulkanFunctions;
+
+#define PFN_LOAD_INFO(req_inst, req_dev, ext_flag, name) \
+ { \
+ req_inst, \
+ req_dev, \
+ offsetof(VulkanFunctions, name), \
+ ext_flag, \
+ { "vk"#name, "vk"#name"EXT", "vk"#name"KHR" } \
+ },
+
+typedef struct VulkanFunctionsLoadInfo {
+ int req_inst;
+ int req_dev;
+ size_t struct_offset;
+ enum VulkanExtensions ext_flag;
+ const char *names[3];
+} VulkanFunctionsLoadInfo;
+
+static const VulkanFunctionsLoadInfo vk_load_info[] = {
+ FN_LIST(PFN_LOAD_INFO)
+};
+