android: native: Add support for custom Vulkan driver loading.

This commit is contained in:
bunnei 2023-02-18 23:42:07 -08:00
parent ae099d583c
commit 4c38220a64
14 changed files with 146 additions and 76 deletions

View file

@ -84,8 +84,8 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_,
Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_,
std::unique_ptr<Core::Frontend::GraphicsContext> context_) try
: RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_),
cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary()),
instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary(context.get())),
instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type,
Settings::values.renderer_debug.GetValue())),
debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr),
surface(CreateSurface(instance, render_window.GetWindowInfo())),

View file

@ -63,7 +63,7 @@ private:
Core::Memory::Memory& cpu_memory;
Tegra::GPU& gpu;
Common::DynamicLibrary library;
std::shared_ptr<Common::DynamicLibrary> library;
vk::InstanceDispatch dld;
vk::Instance instance;

View file

@ -314,10 +314,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
const bool is_intel_anv = driver_id == VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA;
const bool is_nvidia = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY;
const bool is_mvk = driver_id == VK_DRIVER_ID_MOLTENVK;
const bool is_adreno = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY;
const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
const bool is_qualcomm = driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY;
const bool is_turnip = driver_id == VK_DRIVER_ID_MESA_TURNIP;
if ((is_mvk || is_adreno) && !is_suitable) {
if ((is_mvk || is_qualcomm || is_turnip) && !is_suitable) {
LOG_WARNING(Render_Vulkan, "Unsuitable driver is MoltenVK, continuing anyway");
} else if (!is_suitable) {
throw vk::Exception(VK_ERROR_INCOMPATIBLE_DRIVER);
@ -362,14 +362,15 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
CollectToolingInfo();
#ifdef ANDROID
if (is_adreno) {
if (is_qualcomm) {
must_emulate_scaled_formats = true;
LOG_WARNING(Render_Vulkan, "Adreno drivers have broken VK_EXT_extended_dynamic_state");
extensions.extended_dynamic_state = false;
loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME);
LOG_WARNING(Render_Vulkan, "Adreno drivers have a slow VK_KHR_push_descriptor implementation");
LOG_WARNING(Render_Vulkan,
"Adreno drivers have a slow VK_KHR_push_descriptor implementation");
extensions.push_descriptor = false;
loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME);
@ -392,6 +393,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
}
}
const bool is_arm = driver_id == VK_DRIVER_ID_ARM_PROPRIETARY;
if (is_arm) {
must_emulate_scaled_formats = true;
@ -513,7 +515,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
LOG_WARNING(Render_Vulkan, "Intel proprietary drivers do not support MSAA image blits");
cant_blit_msaa = true;
}
if (is_intel_anv || is_adreno) {
if (is_intel_anv || is_qualcomm) {
LOG_WARNING(Render_Vulkan, "Driver does not support native BGR format");
must_emulate_bgr565 = true;
}

View file

@ -10,29 +10,35 @@
namespace Vulkan {
Common::DynamicLibrary OpenLibrary() {
std::shared_ptr<Common::DynamicLibrary> OpenLibrary(
[[maybe_unused]] Core::Frontend::GraphicsContext* context) {
LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library");
Common::DynamicLibrary library;
#ifdef ANDROID
// Android manages its Vulkan driver from the frontend.
return context->GetDriverLibrary();
#else
auto library = std::make_shared<Common::DynamicLibrary>();
#ifdef __APPLE__
// Check if a path to a specific Vulkan library has been specified.
char* const libvulkan_env = std::getenv("LIBVULKAN_PATH");
if (!libvulkan_env || !library.Open(libvulkan_env)) {
if (!libvulkan_env || !library->Open(libvulkan_env)) {
// Use the libvulkan.dylib from the application bundle.
const auto filename =
Common::FS::GetBundleDirectory() / "Contents/Frameworks/libvulkan.dylib";
void(library.Open(Common::FS::PathToUTF8String(filename).c_str()));
void(library->Open(Common::FS::PathToUTF8String(filename).c_str()));
}
#else
std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
LOG_DEBUG(Render_Vulkan, "Trying Vulkan library: {}", filename);
if (!library.Open(filename.c_str())) {
if (!library->Open(filename.c_str())) {
// Android devices may not have libvulkan.so.1, only libvulkan.so.
filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
LOG_DEBUG(Render_Vulkan, "Trying Vulkan library (second attempt): {}", filename);
void(library.Open(filename.c_str()));
void(library->Open(filename.c_str()));
}
#endif
return library;
#endif
}
} // namespace Vulkan

View file

@ -3,10 +3,14 @@
#pragma once
#include <memory>
#include "common/dynamic_library.h"
#include "core/frontend/graphics_context.h"
namespace Vulkan {
Common::DynamicLibrary OpenLibrary();
std::shared_ptr<Common::DynamicLibrary> OpenLibrary(
[[maybe_unused]] Core::Frontend::GraphicsContext* context = nullptr);
} // namespace Vulkan