From a553ed74b7fe3d5d14da312d47144ccfc4514a4b Mon Sep 17 00:00:00 2001 From: Charles Giessen Date: Wed, 19 Feb 2020 16:58:57 -0700 Subject: [PATCH] vulkaninfo: dynamically load vulkan This commit makes it so that vulkaninfo will not statically link to the vulkan loader dll. This is to satisfy the Microsoft ApiValidator requirements. Change-Id: Ibac46dd13df9568e9a97ce1ba4e50613902848a1 --- .travis.yml | 3 +- vulkaninfo/vulkaninfo.cpp | 6 +- vulkaninfo/vulkaninfo.h | 405 ++++++++++++++++++++++++++++++++++------------ 3 files changed, 304 insertions(+), 110 deletions(-) diff --git a/.travis.yml b/.travis.yml index e338b10..757b4f1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -103,10 +103,9 @@ script: if [[ "$VULKAN_BUILD_TARGET" == "LINUX" ]]; then # Run vulkaninfo as a test cd ${TRAVIS_BUILD_DIR} - LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${TRAVIS_BUILD_DIR}/external/Vulkan-Loader/build/install/lib/ cd build/vulkaninfo ldd vulkaninfo - VK_ICD_FILENAMES=../icd/VkICD_mock_icd.json ./vulkaninfo + LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${TRAVIS_BUILD_DIR}/external/Vulkan-Loader/build/install/lib/ VK_ICD_FILENAMES=../icd/VkICD_mock_icd.json ./vulkaninfo cd ${TRAVIS_BUILD_DIR} fi - | diff --git a/vulkaninfo/vulkaninfo.cpp b/vulkaninfo/vulkaninfo.cpp index a0b843a..4dc1dfe 100644 --- a/vulkaninfo/vulkaninfo.cpp +++ b/vulkaninfo/vulkaninfo.cpp @@ -261,7 +261,7 @@ void DumpGroups(Printer &p, AppInstance &inst) { int group_id = 0; for (auto &group : groups) { ObjectWrapper obj(p, "Group " + std::to_string(group_id)); - auto group_props = GetGroupProps(group); + auto group_props = GetGroupProps(inst, group); { ObjectWrapper obj(p, "Properties"); { @@ -647,7 +647,7 @@ void GpuDevDump(Printer &p, AppGpu &gpu) { VkFormat fmt = static_cast(fmt_counter); VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props); + gpu.inst.dll.vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props); GpuDumpFormatProperty(p, fmt, props); } @@ -667,7 +667,7 @@ void GpuDevDumpJson(Printer &p, AppGpu &gpu) { VkFormat fmt = static_cast(fmt_counter); VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props); + gpu.inst.dll.vkGetPhysicalDeviceFormatProperties(gpu.phys_device, fmt, &props); // don't print format properties that are unsupported if ((props.linearTilingFeatures || props.optimalTilingFeatures || props.bufferFeatures) == 0) continue; diff --git a/vulkaninfo/vulkaninfo.h b/vulkaninfo/vulkaninfo.h index 67fa7fc..ed0ed4e 100644 --- a/vulkaninfo/vulkaninfo.h +++ b/vulkaninfo/vulkaninfo.h @@ -53,11 +53,16 @@ #define strndup(p, n) strdup(p) #endif -#ifdef _WIN32 +#if defined(_WIN32) #include #include +#include #endif // _WIN32 +#if defined(__linux__) || defined(__APPLE__) +#include +#endif + #if defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_XCB_KHR) #include #endif @@ -230,7 +235,225 @@ auto GetVector(F &&f, Ts &&... ts) -> std::vector { } // ----------- Instance Setup ------- // +struct VkDll { + VkResult Initialize() { +#if defined(__linux__) + library = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL); + if (!library) library = dlopen("libvulkan.so.1", RTLD_NOW | RTLD_LOCAL); +#elif defined(__APPLE__) + library = dlopen("libvulkan.dylib", RTLD_NOW | RTLD_LOCAL); + if (!library) library = dlopen("libvulkan.1.dylib", RTLD_NOW | RTLD_LOCAL); + if (!library) library = dlopen("libMoltenVK.dylib", RTLD_NOW | RTLD_LOCAL); +#elif defined(_WIN32) + library = LoadLibrary(TEXT("vulkan-1.dll")); +#else + assert(false && "unsupported platform"); +#endif + if (library == 0) return VK_ERROR_INITIALIZATION_FAILED; + return VK_SUCCESS; + } + void Close() { +#if defined(__linux__) || defined(__APPLE__) + dlclose(library); +#elif defined(_WIN32) + FreeLibrary(library); +#endif + library = 0; + } + // Function pointers, loaded from the dll + PFN_vkCreateInstance vkCreateInstance; + PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties; + PFN_vkEnumerateInstanceLayerProperties vkEnumerateInstanceLayerProperties; + PFN_vkDestroyInstance vkDestroyInstance; + PFN_vkEnumeratePhysicalDevices vkEnumeratePhysicalDevices; + PFN_vkGetPhysicalDeviceFeatures vkGetPhysicalDeviceFeatures; + PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties; + PFN_vkGetPhysicalDeviceImageFormatProperties vkGetPhysicalDeviceImageFormatProperties; + PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties; + PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties; + PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties; + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; + PFN_vkGetDeviceProcAddr vkGetDeviceProcAddr; + PFN_vkCreateDevice vkCreateDevice; + PFN_vkDestroyDevice vkDestroyDevice; + PFN_vkEnumerateDeviceExtensionProperties vkEnumerateDeviceExtensionProperties; + PFN_vkGetDeviceQueue vkGetDeviceQueue; + PFN_vkCreateImage vkCreateImage; + PFN_vkDestroyImage vkDestroyImage; + PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; + PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; + PFN_vkGetImageSparseMemoryRequirements vkGetImageSparseMemoryRequirements; + PFN_vkEnumerateInstanceVersion vkEnumerateInstanceVersion; + PFN_vkEnumeratePhysicalDeviceGroups vkEnumeratePhysicalDeviceGroups; + PFN_vkGetPhysicalDeviceFeatures2 vkGetPhysicalDeviceFeatures2; + PFN_vkGetPhysicalDeviceProperties2 vkGetPhysicalDeviceProperties2; + PFN_vkGetPhysicalDeviceFormatProperties2 vkGetPhysicalDeviceFormatProperties2; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2 vkGetPhysicalDeviceQueueFamilyProperties2; + PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2; + PFN_vkDestroySurfaceKHR vkDestroySurfaceKHR; + +#ifdef VK_USE_PLATFORM_XLIB_KHR + PFN_vkCreateXlibSurfaceKHR vkCreateXlibSurfaceKHR; +#endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_XLIB_KHR + PFN_vkGetPhysicalDeviceXlibPresentationSupportKHR vkGetPhysicalDeviceXlibPresentationSupportKHR; +#endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_XCB_KHR + PFN_vkCreateXcbSurfaceKHR vkCreateXcbSurfaceKHR; +#endif // VK_USE_PLATFORM_XCB_KHR +#ifdef VK_USE_PLATFORM_XCB_KHR + PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR vkGetPhysicalDeviceXcbPresentationSupportKHR; +#endif // VK_USE_PLATFORM_XCB_KHR +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + PFN_vkCreateWaylandSurfaceKHR vkCreateWaylandSurfaceKHR; +#endif // VK_USE_PLATFORM_WAYLAND_KHR +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR vkGetPhysicalDeviceWaylandPresentationSupportKHR; +#endif // VK_USE_PLATFORM_WAYLAND_KHR +#ifdef VK_USE_PLATFORM_ANDROID_KHR + PFN_vkCreateAndroidSurfaceKHR vkCreateAndroidSurfaceKHR; +#endif // VK_USE_PLATFORM_ANDROID_KHR +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_WIN32_KHR + PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR vkGetPhysicalDeviceWin32PresentationSupportKHR; +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_MACOS_MVK + PFN_vkCreateMacOSSurfaceMVK vkCreateMacOSSurfaceMVK; +#endif // VK_USE_PLATFORM_MACOS_MVK +#ifdef VK_USE_PLATFORM_METAL_EXT + PFN_vkCreateMetalSurfaceEXT vkCreateMetalSurfaceEXT; +#endif // VK_USE_PLATFORM_METAL_EXT + void InitializeDispatchPointers() { + Load(vkCreateInstance, "vkCreateInstance"); + Load(vkDestroyInstance, "vkDestroyInstance"); + Load(vkEnumeratePhysicalDevices, "vkEnumeratePhysicalDevices"); + Load(vkGetPhysicalDeviceFeatures, "vkGetPhysicalDeviceFeatures"); + Load(vkGetPhysicalDeviceFormatProperties, "vkGetPhysicalDeviceFormatProperties"); + Load(vkGetPhysicalDeviceImageFormatProperties, "vkGetPhysicalDeviceImageFormatProperties"); + Load(vkGetPhysicalDeviceProperties, "vkGetPhysicalDeviceProperties"); + Load(vkGetPhysicalDeviceQueueFamilyProperties, "vkGetPhysicalDeviceQueueFamilyProperties"); + Load(vkGetPhysicalDeviceMemoryProperties, "vkGetPhysicalDeviceMemoryProperties"); + Load(vkGetInstanceProcAddr, "vkGetInstanceProcAddr"); + Load(vkGetDeviceProcAddr, "vkGetDeviceProcAddr"); + Load(vkCreateDevice, "vkCreateDevice"); + Load(vkDestroyDevice, "vkDestroyDevice"); + Load(vkEnumerateInstanceExtensionProperties, "vkEnumerateInstanceExtensionProperties"); + Load(vkEnumerateDeviceExtensionProperties, "vkEnumerateDeviceExtensionProperties"); + Load(vkEnumerateInstanceLayerProperties, "vkEnumerateInstanceLayerProperties"); + Load(vkGetDeviceQueue, "vkGetDeviceQueue"); + Load(vkCreateImage, "vkCreateImage"); + Load(vkDestroyImage, "vkDestroyImage"); + Load(vkGetBufferMemoryRequirements, "vkGetBufferMemoryRequirements"); + Load(vkGetImageMemoryRequirements, "vkGetImageMemoryRequirements"); + Load(vkGetImageSparseMemoryRequirements, "vkGetImageSparseMemoryRequirements"); + Load(vkEnumerateInstanceVersion, "vkEnumerateInstanceVersion"); + Load(vkEnumeratePhysicalDeviceGroups, "vkEnumeratePhysicalDeviceGroups"); + Load(vkGetPhysicalDeviceFeatures2, "vkGetPhysicalDeviceFeatures2"); + Load(vkGetPhysicalDeviceProperties2, "vkGetPhysicalDeviceProperties2"); + Load(vkGetPhysicalDeviceFormatProperties2, "vkGetPhysicalDeviceFormatProperties2"); + Load(vkGetPhysicalDeviceQueueFamilyProperties2, "vkGetPhysicalDeviceQueueFamilyProperties2"); + Load(vkGetPhysicalDeviceMemoryProperties2, "vkGetPhysicalDeviceMemoryProperties2"); + Load(vkDestroySurfaceKHR, "vkDestroySurfaceKHR"); + +#ifdef VK_USE_PLATFORM_XLIB_KHR + Load(vkCreateXlibSurfaceKHR, "vkCreateXlibSurfaceKHR"); +#endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_XLIB_KHR + Load(vkGetPhysicalDeviceXlibPresentationSupportKHR, "vkGetPhysicalDeviceXlibPresentationSupportKHR"); +#endif // VK_USE_PLATFORM_XLIB_KHR +#ifdef VK_USE_PLATFORM_XCB_KHR + Load(vkCreateXcbSurfaceKHR, "vkCreateXcbSurfaceKHR"); +#endif // VK_USE_PLATFORM_XCB_KHR +#ifdef VK_USE_PLATFORM_XCB_KHR + Load(vkGetPhysicalDeviceXcbPresentationSupportKHR, "vkGetPhysicalDeviceXcbPresentationSupportKHR"); +#endif // VK_USE_PLATFORM_XCB_KHR +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + Load(vkCreateWaylandSurfaceKHR, "vkCreateWaylandSurfaceKHR"); +#endif // VK_USE_PLATFORM_WAYLAND_KHR +#ifdef VK_USE_PLATFORM_WAYLAND_KHR + Load(vkGetPhysicalDeviceWaylandPresentationSupportKHR, "vkGetPhysicalDeviceWaylandPresentationSupportKHR"); +#endif // VK_USE_PLATFORM_WAYLAND_KHR +#ifdef VK_USE_PLATFORM_ANDROID_KHR + Load(vkCreateAndroidSurfaceKHR, "vkCreateAndroidSurfaceKHR"); +#endif // VK_USE_PLATFORM_ANDROID_KHR +#ifdef VK_USE_PLATFORM_WIN32_KHR + Load(vkCreateWin32SurfaceKHR, "vkCreateWin32SurfaceKHR"); +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_WIN32_KHR + Load(vkGetPhysicalDeviceWin32PresentationSupportKHR, "vkGetPhysicalDeviceWin32PresentationSupportKHR"); +#endif // VK_USE_PLATFORM_WIN32_KHR +#ifdef VK_USE_PLATFORM_MACOS_MVK + Load(vkCreateMacOSSurfaceMVK, "vkCreateMacOSSurfaceMVK"); +#endif // VK_USE_PLATFORM_MACOS_MVK +#ifdef VK_USE_PLATFORM_METAL_EXT + Load(vkCreateMetalSurfaceEXT, "vkCreateMetalSurfaceEXT"); +#endif // VK_USE_PLATFORM_METAL_EXT + } + private: + template + void Load(T &func_dest, const char *func_name) { +#if defined(__linux__) || defined(__APPLE__) + func_dest = reinterpret_cast(dlsym(library, func_name)); +#elif defined(_WIN32) + func_dest = reinterpret_cast(GetProcAddress(library, func_name)); +#endif + } +#if defined(__linux__) || defined(__APPLE__) + void *library; +#elif defined(_WIN32) + HMODULE library; +#endif +}; + +struct ExtensionFunctions { + // Extension pointers, loaded after instance is created + PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; + PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; + PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR; + PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR; + PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; + PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR; + PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR; + PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; + PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR; + PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT; + PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR; + PFN_vkGetPhysicalDeviceToolPropertiesEXT vkGetPhysicalDeviceToolPropertiesEXT; + + void LoadInstanceExtensionDispatchPointers(PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr, VkInstance instance) { + this->instance = instance; + this->vkGetInstanceProcAddr = vkGetInstanceProcAddr; + Load(vkGetPhysicalDeviceSurfaceSupportKHR, "vkGetPhysicalDeviceSurfaceSupportKHR"); + Load(vkGetPhysicalDeviceSurfaceCapabilitiesKHR, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR"); + Load(vkGetPhysicalDeviceSurfaceFormatsKHR, "vkGetPhysicalDeviceSurfaceFormatsKHR"); + Load(vkGetPhysicalDeviceSurfaceFormats2KHR, "vkGetPhysicalDeviceSurfaceFormats2KHR"); + Load(vkGetPhysicalDeviceSurfacePresentModesKHR, "vkGetPhysicalDeviceSurfacePresentModesKHR"); + Load(vkGetDeviceGroupPresentCapabilitiesKHR, "vkGetDeviceGroupPresentCapabilitiesKHR"); + Load(vkGetPhysicalDeviceProperties2KHR, "vkGetPhysicalDeviceProperties2KHR"); + Load(vkGetPhysicalDeviceFormatProperties2KHR, "vkGetPhysicalDeviceFormatProperties2KHR"); + Load(vkGetPhysicalDeviceQueueFamilyProperties2KHR, "vkGetPhysicalDeviceQueueFamilyProperties2KHR"); + Load(vkGetPhysicalDeviceFeatures2KHR, "vkGetPhysicalDeviceFeatures2KHR"); + Load(vkGetPhysicalDeviceMemoryProperties2KHR, "vkGetPhysicalDeviceMemoryProperties2KHR"); + Load(vkGetPhysicalDeviceSurfaceCapabilities2KHR, "vkGetPhysicalDeviceSurfaceCapabilities2KHR"); + Load(vkGetPhysicalDeviceSurfaceCapabilities2EXT, "vkGetPhysicalDeviceSurfaceCapabilities2EXT"); + Load(vkEnumeratePhysicalDeviceGroupsKHR, "vkEnumeratePhysicalDeviceGroupsKHR"); + Load(vkGetPhysicalDeviceToolPropertiesEXT, "vkGetPhysicalDeviceToolPropertiesEXT"); + } + + private: + PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; + VkInstance instance; + template + void Load(T &dest, const char *name) { + dest = reinterpret_cast(vkGetInstanceProcAddr(instance, name)); + } +}; struct VkStructureHeader { VkStructureType sType; VkStructureHeader *pNext; @@ -295,31 +518,20 @@ struct VulkanVersion { }; struct AppInstance { + VkDll dll; + VkInstance instance; uint32_t instance_version; VulkanVersion vk_version; + ExtensionFunctions ext_funcs; + std::vector global_layers; std::vector global_extensions; // Instance Extensions std::vector inst_extensions; - // Functions from vkGetInstanceProcAddress - PFN_vkGetPhysicalDeviceSurfaceSupportKHR vkGetPhysicalDeviceSurfaceSupportKHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR vkGetPhysicalDeviceSurfaceCapabilitiesKHR; - PFN_vkGetPhysicalDeviceSurfaceFormatsKHR vkGetPhysicalDeviceSurfaceFormatsKHR; - PFN_vkGetPhysicalDeviceSurfaceFormats2KHR vkGetPhysicalDeviceSurfaceFormats2KHR; - PFN_vkGetPhysicalDeviceSurfacePresentModesKHR vkGetPhysicalDeviceSurfacePresentModesKHR; - PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR; - PFN_vkGetPhysicalDeviceFormatProperties2KHR vkGetPhysicalDeviceFormatProperties2KHR; - PFN_vkGetPhysicalDeviceQueueFamilyProperties2KHR vkGetPhysicalDeviceQueueFamilyProperties2KHR; - PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR; - PFN_vkGetPhysicalDeviceMemoryProperties2KHR vkGetPhysicalDeviceMemoryProperties2KHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR vkGetPhysicalDeviceSurfaceCapabilities2KHR; - PFN_vkGetPhysicalDeviceSurfaceCapabilities2EXT vkGetPhysicalDeviceSurfaceCapabilities2EXT; - PFN_vkGetPhysicalDeviceToolPropertiesEXT vkGetPhysicalDeviceToolPropertiesEXT; - std::vector surface_extensions; int width = 256, height = 256; @@ -353,13 +565,17 @@ struct AppInstance { ANativeWindow *window; #endif AppInstance() { - PFN_vkEnumerateInstanceVersion enumerate_instance_version = - reinterpret_cast(vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion")); + if (dll.Initialize() != VK_SUCCESS) { + std::cerr << "Failed to initialize: Vulkan loader is not installed, not found, or failed to load.\n"; + WAIT_FOR_CONSOLE_DESTROY; + exit(1); + } + dll.InitializeDispatchPointers(); - if (!enumerate_instance_version) { + if (!dll.vkEnumerateInstanceVersion) { instance_version = VK_API_VERSION_1_0; } else { - const VkResult err = enumerate_instance_version(&instance_version); + const VkResult err = dll.vkEnumerateInstanceVersion(&instance_version); if (err) ERR_EXIT(err); } @@ -385,7 +601,7 @@ struct AppInstance { const VkInstanceCreateInfo inst_info = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, &dbg_info, 0, &app_info, 0, nullptr, static_cast(inst_exts.size()), inst_exts.data()}; - VkResult err = vkCreateInstance(&inst_info, nullptr, &instance); + VkResult err = dll.vkCreateInstance(&inst_info, nullptr, &instance); if (err == VK_ERROR_INCOMPATIBLE_DRIVER) { std::cerr << "Cannot create Vulkan instance.\n"; std::cerr << "This problem is often caused by a faulty installation of the Vulkan driver or attempting to use a GPU " @@ -394,11 +610,13 @@ struct AppInstance { } else if (err) { ERR_EXIT(err); } - - AppLoadInstanceCommands(); + ext_funcs.LoadInstanceExtensionDispatchPointers(dll.vkGetInstanceProcAddr, instance); } - ~AppInstance() { vkDestroyInstance(instance, nullptr); } + ~AppInstance() { + if (dll.vkDestroyInstance) dll.vkDestroyInstance(instance, nullptr); + dll.Close(); + } AppInstance(const AppInstance &) = delete; const AppInstance &operator=(const AppInstance &) = delete; @@ -415,7 +633,7 @@ struct AppInstance { /* Gets a list of layer and instance extensions */ void AppGetInstanceExtensions() { /* Scan layers */ - auto global_layer_properties = GetVector(vkEnumerateInstanceLayerProperties); + auto global_layer_properties = GetVector(dll.vkEnumerateInstanceLayerProperties); global_layers.resize(global_layer_properties.size()); for (size_t i = 0; i < global_layer_properties.size(); i++) { @@ -434,34 +652,15 @@ struct AppInstance { inst_extensions.push_back(ext.extensionName); } } - void AppLoadInstanceCommands() { -#define LOAD_INSTANCE_VK_CMD(cmd) cmd = reinterpret_cast(vkGetInstanceProcAddr(instance, #cmd)) - - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceSupportKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormatsKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceFormats2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfacePresentModesKHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFormatProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceQueueFamilyProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceFeatures2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceMemoryProperties2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2KHR); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceSurfaceCapabilities2EXT); - LOAD_INSTANCE_VK_CMD(vkGetPhysicalDeviceToolPropertiesEXT); - -#undef LOAD_INSTANCE_VK_CMD - } void AddSurfaceExtension(SurfaceExtension ext) { surface_extensions.push_back(ext); } - static std::vector AppGetGlobalLayerExtensions(char *layer_name) { - return GetVector(vkEnumerateInstanceExtensionProperties, layer_name); + std::vector AppGetGlobalLayerExtensions(char *layer_name) { + return GetVector(dll.vkEnumerateInstanceExtensionProperties, layer_name); } std::vector FindPhysicalDevices() { - return GetVector(vkEnumeratePhysicalDevices, instance); + return GetVector(dll.vkEnumeratePhysicalDevices, instance); } }; @@ -531,7 +730,7 @@ static VkSurfaceKHR AppCreateWin32Surface(AppInstance &inst) { createInfo.hwnd = inst.h_wnd; VkSurfaceKHR surface; - VkResult err = vkCreateWin32SurfaceKHR(inst.instance, &createInfo, nullptr, &surface); + VkResult err = inst.dll.vkCreateWin32SurfaceKHR(inst.instance, &createInfo, nullptr, &surface); if (err) ERR_EXIT(err); return surface; } @@ -544,7 +743,7 @@ static void AppDestroyWin32Window(AppInstance &inst) { CALL_PFN(DestroyWindow)(i defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT) || defined(VK_USE_PLATFORM_WAYLAND_KHR) || \ defined(VK_USE_PLATFORM_ANDROID_KHR) static void AppDestroySurface(AppInstance &inst, VkSurfaceKHR surface) { // same for all platforms - vkDestroySurfaceKHR(inst.instance, surface, nullptr); + inst.dll.vkDestroySurfaceKHR(inst.instance, surface, nullptr); } #endif @@ -599,7 +798,7 @@ static VkSurfaceKHR AppCreateXcbSurface(AppInstance &inst) { xcb_createInfo.window = inst.xcb_window; VkSurfaceKHR surface; - VkResult err = vkCreateXcbSurfaceKHR(inst.instance, &xcb_createInfo, nullptr, &surface); + VkResult err = inst.dll.vkCreateXcbSurfaceKHR(inst.instance, &xcb_createInfo, nullptr, &surface); if (err) ERR_EXIT(err); return surface; } @@ -646,7 +845,7 @@ static VkSurfaceKHR AppCreateXlibSurface(AppInstance &inst) { createInfo.window = inst.xlib_window; VkSurfaceKHR surface; - VkResult err = vkCreateXlibSurfaceKHR(inst.instance, &createInfo, nullptr, &surface); + VkResult err = inst.dll.vkCreateXlibSurfaceKHR(inst.instance, &createInfo, nullptr, &surface); if (err) ERR_EXIT(err); return surface; } @@ -676,7 +875,7 @@ static VkSurfaceKHR AppCreateMacOSSurface(AppInstance &inst) { createInfo.pView = inst.macos_window; VkSurfaceKHR surface; - VkResult err = vkCreateMacOSSurfaceMVK(inst.instance, &createInfo, nullptr, &surface); + VkResult err = inst.dll.vkCreateMacOSSurfaceMVK(inst.instance, &createInfo, nullptr, &surface); if (err) ERR_EXIT(err); return surface; } @@ -703,7 +902,7 @@ static VkSurfaceKHR AppCreateMetalSurface(AppInstance &inst) { createInfo.pLayer = static_cast(GetCAMetalLayerFromMetalView(inst.metal_window)); VkSurfaceKHR surface; - VkResult err = vkCreateMetalSurfaceEXT(inst.instance, &createInfo, nullptr, &surface); + VkResult err = inst.dll.vkCreateMetalSurfaceEXT(inst.instance, &createInfo, nullptr, &surface); if (err) ERR_EXIT(err); return surface; } @@ -742,7 +941,7 @@ static VkSurfaceKHR AppCreateWaylandSurface(AppInstance &inst) { createInfo.surface = inst.wayland_surface; VkSurfaceKHR surface; - VkResult err = vkCreateWaylandSurfaceKHR(inst.instance, &createInfo, nullptr, &surface); + VkResult err = inst.dll.vkCreateWaylandSurfaceKHR(inst.instance, &createInfo, nullptr, &surface); if (err) ERR_EXIT(err); return surface; } @@ -761,7 +960,7 @@ static VkSurfaceKHR AppCreateAndroidSurface(AppInstance &inst) { createInfo.flags = 0; createInfo.window = (struct ANativeWindow *)(inst.window); - err = vkCreateAndroidSurfaceKHR(inst.inst, &createInfo, NULL, &inst.surface); + err = inst.dll.vkCreateAndroidSurfaceKHR(inst.inst, &createInfo, NULL, &inst.surface); EXIT_ERR(err); } static VkSurfaceKHR AppDestroyAndroidSurface(AppInstance &inst) {} @@ -901,8 +1100,8 @@ class AppSurface { : inst(inst), phys_device(phys_device), surface_extension(surface_extension), - surf_present_modes( - GetVector(inst.vkGetPhysicalDeviceSurfacePresentModesKHR, phys_device, surface_extension.surface)) { + surf_present_modes(GetVector(inst.ext_funcs.vkGetPhysicalDeviceSurfacePresentModesKHR, phys_device, + surface_extension.surface)) { const VkPhysicalDeviceSurfaceInfo2KHR surface_info2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface_extension.surface}; @@ -910,16 +1109,16 @@ class AppSurface { VkSurfaceFormat2KHR init; init.sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR; init.pNext = nullptr; - surf_formats2 = - GetVectorInit(inst.vkGetPhysicalDeviceSurfaceFormats2KHR, init, phys_device, &surface_info2); + surf_formats2 = GetVectorInit(inst.ext_funcs.vkGetPhysicalDeviceSurfaceFormats2KHR, init, + phys_device, &surface_info2); } else { - surf_formats = - GetVector(inst.vkGetPhysicalDeviceSurfaceFormatsKHR, phys_device, surface_extension.surface); + surf_formats = GetVector(inst.ext_funcs.vkGetPhysicalDeviceSurfaceFormatsKHR, phys_device, + surface_extension.surface); } if (inst.CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME)) { - VkResult err = - inst.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_device, surface_extension.surface, &surface_capabilities); + VkResult err = inst.ext_funcs.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_device, surface_extension.surface, + &surface_capabilities); if (err) ERR_EXIT(err); } @@ -932,15 +1131,16 @@ class AppSurface { surface_info.pNext = nullptr; surface_info.surface = surface_extension.surface; - VkResult err = inst.vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_device, &surface_info, &surface_capabilities2_khr); + VkResult err = + inst.ext_funcs.vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_device, &surface_info, &surface_capabilities2_khr); if (err) ERR_EXIT(err); } if (inst.CheckExtensionEnabled(VK_EXT_DISPLAY_SURFACE_COUNTER_EXTENSION_NAME)) { surface_capabilities2_ext.sType = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT; surface_capabilities2_ext.pNext = nullptr; - VkResult err = - inst.vkGetPhysicalDeviceSurfaceCapabilities2EXT(phys_device, surface_extension.surface, &surface_capabilities2_ext); + VkResult err = inst.ext_funcs.vkGetPhysicalDeviceSurfaceCapabilities2EXT(phys_device, surface_extension.surface, + &surface_capabilities2_ext); if (err) ERR_EXIT(err); } } @@ -959,19 +1159,16 @@ class AppSurface { std::vector GetGroups(AppInstance &inst) { if (inst.CheckExtensionEnabled(VK_KHR_DEVICE_GROUP_CREATION_EXTENSION_NAME)) { - PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR = - reinterpret_cast( - vkGetInstanceProcAddr(inst.instance, "vkEnumeratePhysicalDeviceGroupsKHR")); - return GetVector(vkEnumeratePhysicalDeviceGroupsKHR, inst.instance); + return GetVector(inst.ext_funcs.vkEnumeratePhysicalDeviceGroupsKHR, inst.instance); } return {}; } -std::vector GetGroupProps(VkPhysicalDeviceGroupProperties group) { +std::vector GetGroupProps(AppInstance &inst, VkPhysicalDeviceGroupProperties group) { std::vector props(group.physicalDeviceCount); for (uint32_t i = 0; i < group.physicalDeviceCount; ++i) { - vkGetPhysicalDeviceProperties(group.physicalDevices[i], &props[i]); + inst.dll.vkGetPhysicalDeviceProperties(group.physicalDevices[i], &props[i]); } return props; @@ -995,12 +1192,12 @@ std::pair GetGroupCapabilities(AppIns VkDevice logical_device = VK_NULL_HANDLE; - VkResult err = vkCreateDevice(group.physicalDevices[0], &device_ci, nullptr, &logical_device); + VkResult err = inst.dll.vkCreateDevice(group.physicalDevices[0], &device_ci, nullptr, &logical_device); if (err != VK_SUCCESS && err != VK_ERROR_EXTENSION_NOT_PRESENT) ERR_EXIT(err); if (err == VK_ERROR_EXTENSION_NOT_PRESENT) { VkDeviceGroupPresentCapabilitiesKHR group_capabilities = {VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR, nullptr}; - vkDestroyDevice(logical_device, nullptr); + inst.dll.vkDestroyDevice(logical_device, nullptr); return std::pair(false, group_capabilities); } @@ -1008,13 +1205,10 @@ std::pair GetGroupCapabilities(AppIns // If the KHR_device_group extension is present, write the capabilities of the logical device into a struct for later // output to user. - PFN_vkGetDeviceGroupPresentCapabilitiesKHR vkGetDeviceGroupPresentCapabilitiesKHR = - reinterpret_cast( - vkGetInstanceProcAddr(inst.instance, "vkGetDeviceGroupPresentCapabilitiesKHR")); - err = vkGetDeviceGroupPresentCapabilitiesKHR(logical_device, &group_capabilities); + err = inst.ext_funcs.vkGetDeviceGroupPresentCapabilitiesKHR(logical_device, &group_capabilities); if (err) ERR_EXIT(err); - vkDestroyDevice(logical_device, nullptr); + inst.dll.vkDestroyDevice(logical_device, nullptr); return std::pair(true, group_capabilities); } @@ -1087,7 +1281,7 @@ struct AppGpu { AppGpu(AppInstance &inst, uint32_t id, VkPhysicalDevice phys_device, pNextChainInfos chainInfos) : inst(inst), id(id), phys_device(phys_device) { - vkGetPhysicalDeviceProperties(phys_device, &props); + inst.dll.vkGetPhysicalDeviceProperties(phys_device, &props); // needs to find the minimum of the instance and device version, and use that to print the device info uint32_t gpu_version = props.apiVersion < inst.instance_version ? props.apiVersion : inst.instance_version; @@ -1097,15 +1291,15 @@ struct AppGpu { props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; buildpNextChain((VkStructureHeader *)&props2, chainInfos.phys_device_props2); - inst.vkGetPhysicalDeviceProperties2KHR(phys_device, &props2); + inst.ext_funcs.vkGetPhysicalDeviceProperties2KHR(phys_device, &props2); } /* get queue count */ - vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, nullptr); + inst.dll.vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, nullptr); queue_props.resize(queue_count); - vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, queue_props.data()); + inst.dll.vkGetPhysicalDeviceQueueFamilyProperties(phys_device, &queue_count, queue_props.data()); if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { queue_props2.resize(queue_count); @@ -1115,23 +1309,23 @@ struct AppGpu { queue_props2[i].pNext = nullptr; } - inst.vkGetPhysicalDeviceQueueFamilyProperties2KHR(phys_device, &queue_count, queue_props2.data()); + inst.ext_funcs.vkGetPhysicalDeviceQueueFamilyProperties2KHR(phys_device, &queue_count, queue_props2.data()); } - vkGetPhysicalDeviceMemoryProperties(phys_device, &memory_props); + inst.dll.vkGetPhysicalDeviceMemoryProperties(phys_device, &memory_props); - vkGetPhysicalDeviceFeatures(phys_device, &features); + inst.dll.vkGetPhysicalDeviceFeatures(phys_device, &features); if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { memory_props2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR; buildpNextChain((VkStructureHeader *)&memory_props2, chainInfos.phys_device_mem_props2); - inst.vkGetPhysicalDeviceMemoryProperties2KHR(phys_device, &memory_props2); + inst.ext_funcs.vkGetPhysicalDeviceMemoryProperties2KHR(phys_device, &memory_props2); features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; buildpNextChain((VkStructureHeader *)&features2, chainInfos.phys_device_features2); - inst.vkGetPhysicalDeviceFeatures2KHR(phys_device, &features2); + inst.ext_funcs.vkGetPhysicalDeviceFeatures2KHR(phys_device, &features2); } device_extensions = AppGetPhysicalDeviceLayerExtensions(nullptr); @@ -1147,7 +1341,7 @@ struct AppGpu { const VkDeviceCreateInfo device_ci = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, nullptr, 0, 1, &q_ci, 0, nullptr, 0, nullptr, &enabled_features}; - VkResult err = vkCreateDevice(phys_device, &device_ci, nullptr, &dev); + VkResult err = inst.dll.vkCreateDevice(phys_device, &device_ci, nullptr, &dev); if (err) ERR_EXIT(err); const VkFormat color_format = VK_FORMAT_R8G8B8A8_UNORM; @@ -1167,7 +1361,7 @@ struct AppGpu { mem_type_res_support.image[tiling][fmt_i].transient_supported = true; VkFormatProperties fmt_props; - vkGetPhysicalDeviceFormatProperties(phys_device, formats[fmt_i], &fmt_props); + inst.dll.vkGetPhysicalDeviceFormatProperties(phys_device, formats[fmt_i], &fmt_props); if ((tiling == VK_IMAGE_TILING_OPTIMAL && fmt_props.optimalTilingFeatures == 0) || (tiling == VK_IMAGE_TILING_LINEAR && fmt_props.linearTilingFeatures == 0)) { mem_type_res_support.image[tiling][fmt_i].regular_supported = false; @@ -1212,8 +1406,9 @@ struct AppGpu { } VkImageFormatProperties img_props; - err = vkGetPhysicalDeviceImageFormatProperties(phys_device, image_ci.format, image_ci.imageType, - image_ci.tiling, image_ci.usage, image_ci.flags, &img_props); + err = inst.dll.vkGetPhysicalDeviceImageFormatProperties(phys_device, image_ci.format, image_ci.imageType, + image_ci.tiling, image_ci.usage, image_ci.flags, + &img_props); uint32_t *memtypes; bool *support; @@ -1239,14 +1434,14 @@ struct AppGpu { if (err) ERR_EXIT(err); VkImage dummy_img; - err = vkCreateImage(dev, &image_ci, nullptr, &dummy_img); + err = inst.dll.vkCreateImage(dev, &image_ci, nullptr, &dummy_img); if (err) ERR_EXIT(err); VkMemoryRequirements mem_req; - vkGetImageMemoryRequirements(dev, dummy_img, &mem_req); + inst.dll.vkGetImageMemoryRequirements(dev, dummy_img, &mem_req); *memtypes = mem_req.memoryTypeBits; - vkDestroyImage(dev, dummy_img, nullptr); + inst.dll.vkDestroyImage(dev, dummy_img, nullptr); } } } @@ -1306,7 +1501,7 @@ struct AppGpu { }; } ~AppGpu() { - vkDestroyDevice(dev, nullptr); + inst.dll.vkDestroyDevice(dev, nullptr); if (inst.CheckExtensionEnabled(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) { freepNextChain(static_cast(features2.pNext)); @@ -1328,7 +1523,7 @@ struct AppGpu { } std::vector AppGetPhysicalDeviceLayerExtensions(char *layer_name) { - return GetVector(vkEnumerateDeviceExtensionProperties, phys_device, layer_name); + return GetVector(inst.dll.vkEnumerateDeviceExtensionProperties, phys_device, layer_name); } // Helper function to determine whether a format range is currently supported. @@ -1370,8 +1565,8 @@ struct AppQueueFamilyProperties { } for (auto &surface_ext : gpu.inst.surface_extensions) { - VkResult err = vkGetPhysicalDeviceSurfaceSupportKHR(gpu.phys_device, queue_index, surface_ext.surface, - &surface_ext.supports_present); + VkResult err = gpu.inst.ext_funcs.vkGetPhysicalDeviceSurfaceSupportKHR( + gpu.phys_device, queue_index, surface_ext.surface, &surface_ext.supports_present); if (err) ERR_EXIT(err); const bool first = (surface_ext == gpu.inst.surface_extensions.at(0)); @@ -1385,8 +1580,8 @@ struct AppQueueFamilyProperties { }; std::vector GetToolingInfo(AppGpu &gpu) { - if (gpu.inst.vkGetPhysicalDeviceToolPropertiesEXT == nullptr) return {}; - return GetVector(gpu.inst.vkGetPhysicalDeviceToolPropertiesEXT, gpu.phys_device); + if (gpu.inst.ext_funcs.vkGetPhysicalDeviceToolPropertiesEXT == nullptr) return {}; + return GetVector(gpu.inst.ext_funcs.vkGetPhysicalDeviceToolPropertiesEXT, gpu.phys_device); } // --------- Format Properties ----------// @@ -1412,12 +1607,12 @@ struct hash { } // namespace std // Used to sort the formats into buckets by their properties. -std::unordered_map> FormatPropMap(AppGpu &gpu) { - std::unordered_map> map; +std::unordered_map > FormatPropMap(AppGpu &gpu) { + std::unordered_map > map; for (auto fmtRange : gpu.supported_format_ranges) { for (int32_t fmt = fmtRange.first_format; fmt <= fmtRange.last_format; ++fmt) { VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(gpu.phys_device, static_cast(fmt), &props); + gpu.inst.dll.vkGetPhysicalDeviceFormatProperties(gpu.phys_device, static_cast(fmt), &props); PropFlags pf = {props.linearTilingFeatures, props.optimalTilingFeatures, props.bufferFeatures}; @@ -1432,6 +1627,6 @@ VkFormatProperties2 GetFormatProperties2(AppGpu &gpu, VkFormat format, pNextChai props.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2; buildpNextChain((VkStructureHeader *)&props, chainInfos.format_properties2); - gpu.inst.vkGetPhysicalDeviceFormatProperties2KHR(gpu.phys_device, format, &props); + gpu.inst.ext_funcs.vkGetPhysicalDeviceFormatProperties2KHR(gpu.phys_device, format, &props); return props; } -- 2.7.4