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