summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-03-17 01:39:38 -0300
committerGravatar ReinUsesLisp2020-04-07 02:23:23 -0300
commitbc1b4b85b01aee30a14c234143e72ef3435f9660 (patch)
tree2ed6568512ce8c93114ada1a3c9e32178f1e5dd2
parentcommon/dynamic_library: Import and adapt helper from Dolphin (diff)
downloadyuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar.gz
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.tar.xz
yuzu-bc1b4b85b01aee30a14c234143e72ef3435f9660.zip
renderer_vulkan: Query device names from the backend
Diffstat (limited to '')
-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>;
39using UniqueFramebuffer = UniqueHandle<vk::Framebuffer>; 39using UniqueFramebuffer = UniqueHandle<vk::Framebuffer>;
40using UniqueImage = UniqueHandle<vk::Image>; 40using UniqueImage = UniqueHandle<vk::Image>;
41using UniqueImageView = UniqueHandle<vk::ImageView>; 41using UniqueImageView = UniqueHandle<vk::ImageView>;
42using UniqueInstance = UniqueHandle<vk::Instance>;
42using UniqueIndirectCommandsLayoutNVX = UniqueHandle<vk::IndirectCommandsLayoutNVX>; 43using UniqueIndirectCommandsLayoutNVX = UniqueHandle<vk::IndirectCommandsLayoutNVX>;
43using UniqueObjectTableNVX = UniqueHandle<vk::ObjectTableNVX>; 44using UniqueObjectTableNVX = UniqueHandle<vk::ObjectTableNVX>;
44using UniquePipeline = UniqueHandle<vk::Pipeline>; 45using 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 @@
9#include <fmt/format.h> 9#include <fmt/format.h>
10 10
11#include "common/assert.h" 11#include "common/assert.h"
12#include "common/dynamic_library.h"
12#include "common/logging/log.h" 13#include "common/logging/log.h"
13#include "common/telemetry.h" 14#include "common/telemetry.h"
14#include "core/core.h" 15#include "core/core.h"
@@ -53,6 +54,45 @@ VkBool32 DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity_,
53 return VK_FALSE; 54 return VK_FALSE;
54} 55}
55 56
57Common::DynamicLibrary OpenVulkanLibrary() {
58 Common::DynamicLibrary library;
59#ifdef __APPLE__
60 // Check if a path to a specific Vulkan library has been specified.
61 char* libvulkan_env = getenv("LIBVULKAN_PATH");
62 if (!libvulkan_env || !library.Open(libvulkan_env)) {
63 // Use the libvulkan.dylib from the application bundle.
64 std::string filename = File::GetBundleDirectory() + "/Contents/Frameworks/libvulkan.dylib";
65 library.Open(filename.c_str());
66 }
67#else
68 std::string filename = Common::DynamicLibrary::GetVersionedFilename("vulkan", 1);
69 if (!library.Open(filename.c_str())) {
70 // Android devices may not have libvulkan.so.1, only libvulkan.so.
71 filename = Common::DynamicLibrary::GetVersionedFilename("vulkan");
72 library.Open(filename.c_str());
73 }
74#endif
75 return library;
76}
77
78UniqueInstance CreateInstance(Common::DynamicLibrary& library, vk::DispatchLoaderDynamic& dld) {
79 PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr;
80 if (!library.GetSymbol("vkGetInstanceProcAddr", &vkGetInstanceProcAddr)) {
81 return UniqueInstance{};
82 }
83 dld.init(vkGetInstanceProcAddr);
84
85 const vk::ApplicationInfo application_info("yuzu", VK_MAKE_VERSION(0, 1, 0), "yuzu",
86 VK_MAKE_VERSION(0, 1, 0), VK_API_VERSION_1_1);
87 const vk::InstanceCreateInfo instance_ci({}, &application_info, 0, nullptr, 0, nullptr);
88 vk::Instance unsafe_instance;
89 if (vk::createInstance(&instance_ci, nullptr, &unsafe_instance, dld) != vk::Result::eSuccess) {
90 return UniqueInstance{};
91 }
92 dld.init(unsafe_instance, vkGetInstanceProcAddr);
93 return UniqueInstance(unsafe_instance, {nullptr, dld});
94}
95
56std::string GetReadableVersion(u32 version) { 96std::string GetReadableVersion(u32 version) {
57 return fmt::format("{}.{}.{}", VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version), 97 return fmt::format("{}.{}.{}", VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version),
58 VK_VERSION_PATCH(version)); 98 VK_VERSION_PATCH(version));
@@ -276,4 +316,33 @@ void RendererVulkan::Report() const {
276 telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions); 316 telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions);
277} 317}
278 318
319std::vector<std::string> RendererVulkan::EnumerateDevices() {
320 Common::DynamicLibrary library = OpenVulkanLibrary();
321 if (!library.IsOpen()) {
322 return {};
323 }
324 vk::DispatchLoaderDynamic dld;
325 UniqueInstance instance = CreateInstance(library, dld);
326 if (!instance) {
327 return {};
328 }
329
330 u32 num_devices;
331 if (instance->enumeratePhysicalDevices(&num_devices, nullptr, dld) != vk::Result::eSuccess) {
332 return {};
333 }
334 std::vector<vk::PhysicalDevice> devices(num_devices);
335 if (instance->enumeratePhysicalDevices(&num_devices, devices.data(), dld) !=
336 vk::Result::eSuccess) {
337 return {};
338 }
339
340 std::vector<std::string> names;
341 names.reserve(num_devices);
342 for (auto& device : devices) {
343 names.push_back(device.getProperties(dld).deviceName);
344 }
345 return names;
346}
347
279} // namespace Vulkan 348} // 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 @@
6 6
7#include <memory> 7#include <memory>
8#include <optional> 8#include <optional>
9#include <string>
9#include <vector> 10#include <vector>
10 11
11#include "video_core/renderer_base.h" 12#include "video_core/renderer_base.h"
@@ -44,6 +45,8 @@ public:
44 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override; 45 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
45 bool TryPresent(int timeout_ms) override; 46 bool TryPresent(int timeout_ms) override;
46 47
48 static std::vector<std::string> EnumerateDevices();
49
47private: 50private:
48 std::optional<vk::DebugUtilsMessengerEXT> CreateDebugCallback( 51 std::optional<vk::DebugUtilsMessengerEXT> CreateDebugCallback(
49 const vk::DispatchLoaderDynamic& dldi); 52 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 @@
14#include "core/settings.h" 14#include "core/settings.h"
15#include "ui_configure_graphics.h" 15#include "ui_configure_graphics.h"
16#include "yuzu/configuration/configure_graphics.h" 16#include "yuzu/configuration/configure_graphics.h"
17#ifdef HAS_VULKAN
18#include "video_core/renderer_vulkan/renderer_vulkan.h"
19#endif
17 20
18namespace { 21namespace {
19enum class Resolution : int { 22enum class Resolution : int {
@@ -165,41 +168,9 @@ void ConfigureGraphics::UpdateDeviceComboBox() {
165 168
166void ConfigureGraphics::RetrieveVulkanDevices() { 169void ConfigureGraphics::RetrieveVulkanDevices() {
167#ifdef HAS_VULKAN 170#ifdef HAS_VULKAN
168 QVulkanInstance instance; 171 vulkan_devices.clear();
169 instance.setApiVersion(QVersionNumber(1, 1, 0)); 172 for (auto& name : Vulkan::RendererVulkan::EnumerateDevices()) {
170 if (!instance.create()) { 173 vulkan_devices.push_back(QString::fromStdString(name));
171 LOG_INFO(Frontend, "Vulkan 1.1 not available");
172 return;
173 }
174 const auto vkEnumeratePhysicalDevices{reinterpret_cast<PFN_vkEnumeratePhysicalDevices>(
175 instance.getInstanceProcAddr("vkEnumeratePhysicalDevices"))};
176 if (vkEnumeratePhysicalDevices == nullptr) {
177 LOG_INFO(Frontend, "Failed to get pointer to vkEnumeratePhysicalDevices");
178 return;
179 }
180 u32 physical_device_count;
181 if (vkEnumeratePhysicalDevices(instance.vkInstance(), &physical_device_count, nullptr) !=
182 VK_SUCCESS) {
183 LOG_INFO(Frontend, "Failed to get physical devices count");
184 return;
185 }
186 std::vector<VkPhysicalDevice> physical_devices(physical_device_count);
187 if (vkEnumeratePhysicalDevices(instance.vkInstance(), &physical_device_count,
188 physical_devices.data()) != VK_SUCCESS) {
189 LOG_INFO(Frontend, "Failed to get physical devices");
190 return;
191 }
192
193 const auto vkGetPhysicalDeviceProperties{reinterpret_cast<PFN_vkGetPhysicalDeviceProperties>(
194 instance.getInstanceProcAddr("vkGetPhysicalDeviceProperties"))};
195 if (vkGetPhysicalDeviceProperties == nullptr) {
196 LOG_INFO(Frontend, "Failed to get pointer to vkGetPhysicalDeviceProperties");
197 return;
198 }
199 for (const auto physical_device : physical_devices) {
200 VkPhysicalDeviceProperties properties;
201 vkGetPhysicalDeviceProperties(physical_device, &properties);
202 vulkan_devices.push_back(QString::fromUtf8(properties.deviceName));
203 } 174 }
204#endif 175#endif
205} 176}