From a6bb06174f6e571be10b3a436e9cb9bd9e7a408f Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 29 Mar 2019 23:35:01 +1000 Subject: [PATCH 1/2] Vulkan: Fix library load failure on Android --- .../VideoBackends/Vulkan/VulkanLoader.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp b/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp index bfc8b5673e..cb1c8d6571 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanLoader.cpp @@ -37,32 +37,32 @@ static void ResetVulkanLibraryFunctionPointers() static Common::DynamicLibrary s_vulkan_module; -static std::string GetVulkanLibraryFilename() +static bool OpenVulkanLibrary() { #ifdef __APPLE__ // Check if a path to a specific Vulkan library has been specified. char* libvulkan_env = getenv("LIBVULKAN_PATH"); - if (libvulkan_env) - return std::string(libvulkan_env); + if (libvulkan_env && s_vulkan_module.Open(libvulkan_env)) + return true; // Use the libvulkan.dylib from the application bundle. - return File::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib"; + std::string filename = File::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib"; + return s_vulkan_module.Open(filename.c_str()); #else - return Common::DynamicLibrary::GetVersionedFilename("vulkan", 1); + std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1); + if (s_vulkan_module.Open(filename.c_str())) + return true; + + // Android devices may not have libvulkan.so.1, only libvulkan.so. + filename = Common::DynamicLibrary::GetVersionedFilename("vulkan"); + return s_vulkan_module.Open(filename.c_str()); #endif } bool LoadVulkanLibrary() { - if (!s_vulkan_module.IsOpen()) - { - const std::string filename = GetVulkanLibraryFilename(); - if (!s_vulkan_module.Open(filename.c_str())) - { - ERROR_LOG(VIDEO, "Failed to load %s", filename.c_str()); - return false; - } - } + if (!s_vulkan_module.IsOpen() && !OpenVulkanLibrary()) + return false; #define VULKAN_MODULE_ENTRY_POINT(name, required) \ if (!s_vulkan_module.GetSymbol(#name, &name) && required) \ From b685a66753c980f2c6e69aa277d33b20e9490d15 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 30 Mar 2019 00:18:26 +1000 Subject: [PATCH 2/2] Vulkan: Fix crash when checking subgroup support on Mesa --- .../VideoBackends/Vulkan/VulkanContext.cpp | 21 +++++++++++++++++-- .../Vulkan/VulkanEntryPoints.inl | 1 + 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index 52038e39dc..72f3cf79b0 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -100,6 +100,19 @@ VkInstance VulkanContext::CreateVulkanInstance(WindowSystemType wstype, bool ena app_info.engineVersion = VK_MAKE_VERSION(5, 0, 0); app_info.apiVersion = VK_MAKE_VERSION(1, 0, 0); + // Try for Vulkan 1.1 if the loader supports it. + if (vkEnumerateInstanceVersion) + { + u32 supported_api_version = 0; + VkResult res = vkEnumerateInstanceVersion(&supported_api_version); + if (res == VK_SUCCESS && (VK_VERSION_MAJOR(supported_api_version) > 1 || + VK_VERSION_MINOR(supported_api_version) >= 1)) + { + // The device itself may not support 1.1, so we check that before using any 1.1 functionality. + app_info.apiVersion = VK_MAKE_VERSION(1, 1, 0); + } + } + VkInstanceCreateInfo instance_create_info = {}; instance_create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; instance_create_info.pNext = nullptr; @@ -868,9 +881,13 @@ void VulkanContext::InitDriverDetails() void VulkanContext::PopulateShaderSubgroupSupport() { - // If this function isn't available, we don't support Vulkan 1.1. - if (!vkGetPhysicalDeviceProperties2) + // Vulkan 1.1 support is required for vkGetPhysicalDeviceProperties2(), but we can't rely on the + // function pointer alone. + if (!vkGetPhysicalDeviceProperties2 || (VK_VERSION_MAJOR(m_device_properties.apiVersion) == 1 && + VK_VERSION_MINOR(m_device_properties.apiVersion) < 1)) + { return; + } VkPhysicalDeviceProperties2 device_properties_2 = {}; device_properties_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; diff --git a/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl b/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl index 2a4c4bda24..874cdf9a48 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl +++ b/Source/Core/VideoBackends/Vulkan/VulkanEntryPoints.inl @@ -15,6 +15,7 @@ VULKAN_MODULE_ENTRY_POINT(vkGetInstanceProcAddr, true) VULKAN_MODULE_ENTRY_POINT(vkGetDeviceProcAddr, true) VULKAN_MODULE_ENTRY_POINT(vkEnumerateInstanceExtensionProperties, true) VULKAN_MODULE_ENTRY_POINT(vkEnumerateInstanceLayerProperties, true) +VULKAN_MODULE_ENTRY_POINT(vkEnumerateInstanceVersion, false) #endif // VULKAN_MODULE_ENTRY_POINT