diff options
Diffstat (limited to 'src/video_core')
-rw-r--r-- | src/video_core/renderer_vulkan/declarations.h | 1 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 69 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 3 |
3 files changed, 73 insertions, 0 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); |