renderer_vulkan: Query device names from the backend
This commit is contained in:
		
							parent
							
								
									7104e01bb3
								
							
						
					
					
						commit
						bc1b4b85b0
					
				@ -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 New Issue
	
	Block a user