From fede9a05fba44452121a831d79f34f0dcc9c4f49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 30 May 2017 10:38:17 +0200 Subject: [PATCH] Only show the Vulkan setting if Vulkan might be available. --- Common/Vulkan/VulkanLoader.cpp | 35 +++++++++++++++++++++++++--------- Common/Vulkan/VulkanLoader.h | 3 +++ UI/GameSettingsScreen.cpp | 9 +++++---- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/Common/Vulkan/VulkanLoader.cpp b/Common/Vulkan/VulkanLoader.cpp index 97ea7d4fa7..18df0c070b 100644 --- a/Common/Vulkan/VulkanLoader.cpp +++ b/Common/Vulkan/VulkanLoader.cpp @@ -195,16 +195,34 @@ static void *vulkanLibrary; #define LOAD_DEVICE_FUNC(instance, x) x = (PFN_ ## x)vkGetDeviceProcAddr(instance, #x); if (!x) {ILOG("Missing (device): %s", #x);} #define LOAD_GLOBAL_FUNC(x) x = (PFN_ ## x)dlsym(vulkanLibrary, #x); if (!x) {ILOG("Missing (global): %s", #x);} - -bool VulkanLoad() { +bool VulkanMayBeAvailable() { + if (vulkanLibrary) + return true; + bool available = false; #ifndef _WIN32 - vulkanLibrary = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL); + void *lib = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL); + available = lib != nullptr; + dlclose(lib); #else // LoadLibrary etc - vulkanLibrary = LoadLibrary(L"vulkan-1.dll"); + HINSTANCE lib = LoadLibrary(L"vulkan-1.dll"); + available = lib != 0; + FreeLibrary(lib); #endif + return available; +} + +bool VulkanLoad() { if (!vulkanLibrary) { - return false; +#ifndef _WIN32 + vulkanLibrary = dlopen("libvulkan.so", RTLD_NOW | RTLD_LOCAL); +#else + // LoadLibrary etc + vulkanLibrary = LoadLibrary(L"vulkan-1.dll"); +#endif + if (!vulkanLibrary) { + return false; + } } LOAD_GLOBAL_FUNC(vkCreateInstance); @@ -391,13 +409,12 @@ void VulkanLoadDeviceFunctions(VkDevice device) { } void VulkanFree() { + if (vulkanLibrary) { #ifdef _WIN32 - if (vulkanLibrary) { FreeLibrary(vulkanLibrary); - } #else - if (vulkanLibrary) { dlclose(vulkanLibrary); - } #endif + vulkanLibrary = nullptr; + } } diff --git a/Common/Vulkan/VulkanLoader.h b/Common/Vulkan/VulkanLoader.h index b6f8beaccf..67042c0c0c 100644 --- a/Common/Vulkan/VulkanLoader.h +++ b/Common/Vulkan/VulkanLoader.h @@ -191,6 +191,9 @@ extern PFN_vkQueuePresentKHR vkQueuePresentKHR; extern PFN_vkCreateDebugReportCallbackEXT vkCreateDebugReportCallbackEXT; extern PFN_vkDestroyDebugReportCallbackEXT vkDestroyDebugReportCallbackEXT; +// Way to do a quick check before even attempting to load. +bool VulkanMayBeAvailable(); + bool VulkanLoad(); void VulkanLoadInstanceFunctions(VkInstance instance); void VulkanLoadDeviceFunctions(VkDevice device); diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 15902fe0b9..263c626250 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -48,6 +48,7 @@ #include "Common/KeyMap.h" #include "Common/FileUtil.h" #include "Common/OSVersion.h" +#include "Common/Vulkan/VulkanLoader.h" #include "Core/Config.h" #include "Core/Host.h" #include "Core/System.h" @@ -187,10 +188,10 @@ void GameSettingsScreen::CreateViews() { renderingBackendChoice->HideChoice(2); // D3D11 } #endif -#if !defined(_WIN32) && !PPSSPP_PLATFORM(ANDROID) - // TODO: Add dynamic runtime check for Vulkan support on Android - renderingBackendChoice->HideChoice(3); -#endif + if (!VulkanMayBeAvailable()) { + renderingBackendChoice->HideChoice(3); + } + static const char *renderingMode[] = { "Non-Buffered Rendering", "Buffered Rendering", "Read Framebuffers To Memory (CPU)", "Read Framebuffers To Memory (GPU)"}; PopupMultiChoice *renderingModeChoice = graphicsSettings->Add(new PopupMultiChoice(&g_Config.iRenderingMode, gr->T("Mode"), renderingMode, 0, ARRAY_SIZE(renderingMode), gr->GetName(), screenManager())); renderingModeChoice->OnChoice.Add([=](EventParams &e) {