|
@@ -9,6 +9,7 @@
|
|
|
#include <fmt/format.h>
|
|
#include <fmt/format.h>
|
|
|
|
|
|
|
|
#include "common/assert.h"
|
|
#include "common/assert.h"
|
|
|
|
|
+#include "common/dynamic_library.h"
|
|
|
#include "common/logging/log.h"
|
|
#include "common/logging/log.h"
|
|
|
#include "common/telemetry.h"
|
|
#include "common/telemetry.h"
|
|
|
#include "core/core.h"
|
|
#include "core/core.h"
|
|
@@ -53,6 +54,45 @@ VkBool32 DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity_,
|
|
|
return VK_FALSE;
|
|
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) {
|
|
std::string GetReadableVersion(u32 version) {
|
|
|
return fmt::format("{}.{}.{}", VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version),
|
|
return fmt::format("{}.{}.{}", VK_VERSION_MAJOR(version), VK_VERSION_MINOR(version),
|
|
|
VK_VERSION_PATCH(version));
|
|
VK_VERSION_PATCH(version));
|
|
@@ -276,4 +316,33 @@ void RendererVulkan::Report() const {
|
|
|
telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions);
|
|
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
|
|
} // namespace Vulkan
|