summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReinUsesLisp <reinuseslisp@airmail.cc>2020-03-17 05:39:38 +0100
committerReinUsesLisp <reinuseslisp@airmail.cc>2020-04-07 07:23:23 +0200
commitbc1b4b85b01aee30a14c234143e72ef3435f9660 (patch)
tree2ed6568512ce8c93114ada1a3c9e32178f1e5dd2
parentcommon/dynamic_library: Import and adapt helper from Dolphin (diff)
downloadyuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar.gz
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar.bz2
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar.lz
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar.xz
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar.zst
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.zip
-rw-r--r--src/video_core/renderer_vulkan/declarations.h1
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.cpp69
-rw-r--r--src/video_core/renderer_vulkan/renderer_vulkan.h3
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp41
4 files changed, 79 insertions, 35 deletions
diff --git a/src/video_core/renderer_vulkan/declarations.h b/src/video_core/renderer_vulkan/declarations.h
index 323bf6b39..d2a1140c1 100644
--- a/src/video_core/renderer_vulkan/declarations.h
+++ b/src/video_core/renderer_vulkan/declarations.h
@@ -39,6 +39,7 @@ using UniqueFence = UniqueHandle<vk::Fence>;
using UniqueFramebuffer = UniqueHandle<vk::Framebuffer>;
using UniqueImage = UniqueHandle<vk::Image>;
using UniqueImageView = UniqueHandle<vk::ImageView>;
+using UniqueInstance = UniqueHandle<vk::Instance>;
using UniqueIndirectCommandsLayoutNVX = UniqueHandle<vk::IndirectCommandsLayoutNVX>;
using UniqueObjectTableNVX = UniqueHandle<vk::ObjectTableNVX>;
using UniquePipeline = UniqueHandle<vk::Pipeline>;
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 6953aaafe..9c323a1aa 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -9,6 +9,7 @@
#include <fmt/format.h>
#include "common/assert.h"
+#include "common/dynamic_library.h"
#include "common/logging/log.h"
#include "common/telemetry.h"
#include "core/core.h"
@@ -53,6 +54,45 @@ VkBool32 DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity_,
return VK_FALSE;
}
+Common::DynamicLibrary OpenVulkanLibrary() {
+ Common::DynamicLibrary library;
+#ifdef __APPLE__
+ // Check if a path to a specific Vulkan library has been specified.
+ char* libvulkan_env = getenv("LIBVULKAN_PATH");
+ if (!libvulkan_env || !library.Open(libvulkan_env)) {
+ // Use the libvulkan.dylib from the application bundle.
+ std::string filename = File::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib";
+ library.Open(filename.c_str());
+ }
+#else
+ std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
+ if (!library.Open(filename.c_str())) {
+ // Android devices may not have libvulkan.so.1, only libvulkan.so.
+ filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
+ library.Open(filename.c_str());
+ }
+#endif
+ return library;
+}
+
+UniqueInstance CreateInstance(Common::DynamicLibrary& library, vk::DispatchLoaderDynamic& dld) {
+ PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
+ if (!library.GetSymbol("vkGetInstanceProcAddr", &vkGetInstanceProcAddr)) {
+ return UniqueInstance{};
+ }
+ dld.init(vkGetInstanceProcAddr);
+
+ const vk::ApplicationInfo application_info("yuzu", VK_MAKE_VERSION(0, 1, 0), "yuzu",
+ VK_MAKE_VERSION(0, 1, 0), VK_API_VERSION_1_1);
+ const vk::InstanceCreateInfo instance_ci({}, &application_info, 0, nullptr, 0, nullptr);
+ vk::Instance unsafe_instance;
+ if (vk::createInstance(&instance_ci, nullptr, &unsafe_instance, dld) != vk::Result::eSuccess) {
+ return UniqueInstance{};
+ }
+ dld.init(unsafe_instance, vkGetInstanceProcAddr);
+ return UniqueInstance(unsafe_instance, {nullptr, dld});
+}
+
std::string GetReadableVersion(u32 version) {
return fmt::format("{}.{}.{}", VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version),
VK_VERSION_PATCH(version));
@@ -276,4 +316,33 @@ void RendererVulkan::Report() const {
telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions);
}
+std::vector<std::string> RendererVulkan::EnumerateDevices() {
+ Common::DynamicLibrary library = OpenVulkanLibrary();
+ if (!library.IsOpen()) {
+ return {};
+ }
+ vk::DispatchLoaderDynamic dld;
+ UniqueInstance instance = CreateInstance(library, dld);
+ if (!instance) {
+ return {};
+ }
+
+ u32 num_devices;
+ if (instance->enumeratePhysicalDevices(&num_devices, nullptr, dld) != vk::Result::eSuccess) {
+ return {};
+ }
+ std::vector<vk::PhysicalDevice> devices(num_devices);
+ if (instance->enumeratePhysicalDevices(&num_devices, devices.data(), dld) !=
+ vk::Result::eSuccess) {
+ return {};
+ }
+
+ std::vector<std::string> names;
+ names.reserve(num_devices);
+ for (auto& device : devices) {
+ names.push_back(device.getProperties(dld).deviceName);
+ }
+ return names;
+}
+
} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h
index d14384e79..7a17c546d 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.h
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.h
@@ -6,6 +6,7 @@
#include <memory>
#include <optional>
+#include <string>
#include <vector>
#include "video_core/renderer_base.h"
@@ -44,6 +45,8 @@ public:
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
bool TryPresent(int timeout_ms) override;
+ static std::vector<std::string> EnumerateDevices();
+
private:
std::optional<vk::DebugUtilsMessengerEXT> CreateDebugCallback(
const vk::DispatchLoaderDynamic& dldi);
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index a821c7b3c..d29332033 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -14,6 +14,9 @@
#include "core/settings.h"
#include "ui_configure_graphics.h"
#include "yuzu/configuration/configure_graphics.h"
+#ifdef HAS_VULKAN
+#include "video_core/renderer_vulkan/renderer_vulkan.h"
+#endif
namespace {
enum class Resolution : int {
@@ -165,41 +168,9 @@ void ConfigureGraphics::UpdateDeviceComboBox() {
void ConfigureGraphics::RetrieveVulkanDevices() {
#ifdef HAS_VULKAN
- QVulkanInstance instance;
- instance.setApiVersion(QVersionNumber(1, 1, 0));
- if (!instance.create()) {
- LOG_INFO(Frontend, "Vulkan 1.1 not available");
- return;
- }
- const auto vkEnumeratePhysicalDevices{reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(
- instance.getInstanceProcAddr("vkEnumeratePhysicalDevices"))};
- if (vkEnumeratePhysicalDevices == nullptr) {
- LOG_INFO(Frontend, "Failed to get pointer to vkEnumeratePhysicalDevices");
- return;
- }
- u32 physical_device_count;
- if (vkEnumeratePhysicalDevices(instance.vkInstance(), &physical_device_count, nullptr) !=
- VK_SUCCESS) {
- LOG_INFO(Frontend, "Failed to get physical devices count");
- return;
- }
- std::vector<VkPhysicalDevice> physical_devices(physical_device_count);
- if (vkEnumeratePhysicalDevices(instance.vkInstance(), &physical_device_count,
- physical_devices.data()) != VK_SUCCESS) {
- LOG_INFO(Frontend, "Failed to get physical devices");
- return;
- }
-
- const auto vkGetPhysicalDeviceProperties{reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
- instance.getInstanceProcAddr("vkGetPhysicalDeviceProperties"))};
- if (vkGetPhysicalDeviceProperties == nullptr) {
- LOG_INFO(Frontend, "Failed to get pointer to vkGetPhysicalDeviceProperties");
- return;
- }
- for (const auto physical_device : physical_devices) {
- VkPhysicalDeviceProperties properties;
- vkGetPhysicalDeviceProperties(physical_device, &properties);
- vulkan_devices.push_back(QString::fromUtf8(properties.deviceName));
+ vulkan_devices.clear();
+ for (auto& name : Vulkan::RendererVulkan::EnumerateDevices()) {
+ vulkan_devices.push_back(QString::fromStdString(name));
}
#endif
}