renderer_vulkan: Query device names from the backend
This commit is contained in:
parent
7104e01bb3
commit
bc1b4b85b0
4 changed files with 79 additions and 35 deletions
|
@ -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>;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue