diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2020-03-27 05:33:21 +0100 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2020-04-11 03:49:02 +0200 |
commit | 2905142f47163d0f409c31910cdc234e8797286c (patch) | |
tree | 7d5bf00d6b68f58b868e64a0683afd8c09e7f971 /src/video_core/renderer_vulkan/renderer_vulkan.cpp | |
parent | Merge pull request #3594 from ReinUsesLisp/vk-instance (diff) | |
download | yuzu-2905142f47163d0f409c31910cdc234e8797286c.tar yuzu-2905142f47163d0f409c31910cdc234e8797286c.tar.gz yuzu-2905142f47163d0f409c31910cdc234e8797286c.tar.bz2 yuzu-2905142f47163d0f409c31910cdc234e8797286c.tar.lz yuzu-2905142f47163d0f409c31910cdc234e8797286c.tar.xz yuzu-2905142f47163d0f409c31910cdc234e8797286c.tar.zst yuzu-2905142f47163d0f409c31910cdc234e8797286c.zip |
Diffstat (limited to 'src/video_core/renderer_vulkan/renderer_vulkan.cpp')
-rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 157 |
1 files changed, 67 insertions, 90 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 9cdb4b627..dd590c38b 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -24,7 +24,6 @@ #include "core/settings.h" #include "core/telemetry_session.h" #include "video_core/gpu.h" -#include "video_core/renderer_vulkan/declarations.h" #include "video_core/renderer_vulkan/renderer_vulkan.h" #include "video_core/renderer_vulkan/vk_blit_screen.h" #include "video_core/renderer_vulkan/vk_device.h" @@ -34,8 +33,9 @@ #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/renderer_vulkan/vk_state_tracker.h" #include "video_core/renderer_vulkan/vk_swapchain.h" +#include "video_core/renderer_vulkan/wrapper.h" -// Include these late to avoid changing Vulkan-Hpp's dynamic dispatcher size +// Include these late to avoid polluting previous headers #ifdef _WIN32 #include <windows.h> // ensure include order @@ -54,20 +54,19 @@ namespace { using Core::Frontend::WindowSystemType; -VkBool32 DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity_, +VkBool32 DebugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type, const VkDebugUtilsMessengerCallbackDataEXT* data, [[maybe_unused]] void* user_data) { - const auto severity{static_cast<vk::DebugUtilsMessageSeverityFlagBitsEXT>(severity_)}; const char* message{data->pMessage}; - if (severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eError) { + if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) { LOG_CRITICAL(Render_Vulkan, "{}", message); - } else if (severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) { + } else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) { LOG_WARNING(Render_Vulkan, "{}", message); - } else if (severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo) { + } else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) { LOG_INFO(Render_Vulkan, "{}", message); - } else if (severity & vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose) { + } else if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) { LOG_DEBUG(Render_Vulkan, "{}", message); } return VK_FALSE; @@ -94,22 +93,24 @@ Common::DynamicLibrary OpenVulkanLibrary() { return library; } -UniqueInstance CreateInstance(Common::DynamicLibrary& library, vk::DispatchLoaderDynamic& dld, - WindowSystemType window_type = WindowSystemType::Headless, - bool enable_layers = false) { +vk::Instance CreateInstance(Common::DynamicLibrary& library, vk::InstanceDispatch& dld, + WindowSystemType window_type = WindowSystemType::Headless, + bool enable_layers = false) { if (!library.IsOpen()) { LOG_ERROR(Render_Vulkan, "Vulkan library not available"); - return UniqueInstance{}; + return {}; } - PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr; - if (!library.GetSymbol("vkGetInstanceProcAddr", &vkGetInstanceProcAddr)) { + if (!library.GetSymbol("vkGetInstanceProcAddr", &dld.vkGetInstanceProcAddr)) { LOG_ERROR(Render_Vulkan, "vkGetInstanceProcAddr not present in Vulkan"); - return UniqueInstance{}; + return {}; + } + if (!vk::Load(dld)) { + LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers"); + return {}; } - dld.init(vkGetInstanceProcAddr); std::vector<const char*> extensions; - extensions.reserve(4); + extensions.reserve(6); switch (window_type) { case Core::Frontend::WindowSystemType::Headless: break; @@ -136,45 +137,39 @@ UniqueInstance CreateInstance(Common::DynamicLibrary& library, vk::DispatchLoade if (enable_layers) { extensions.push_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); } + extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - u32 num_properties; - if (vk::enumerateInstanceExtensionProperties(nullptr, &num_properties, nullptr, dld) != - vk::Result::eSuccess) { - LOG_ERROR(Render_Vulkan, "Failed to query number of extension properties"); - return UniqueInstance{}; - } - std::vector<vk::ExtensionProperties> properties(num_properties); - if (vk::enumerateInstanceExtensionProperties(nullptr, &num_properties, properties.data(), - dld) != vk::Result::eSuccess) { + const std::optional properties = vk::EnumerateInstanceExtensionProperties(dld); + if (!properties) { LOG_ERROR(Render_Vulkan, "Failed to query extension properties"); - return UniqueInstance{}; + return {}; } for (const char* extension : extensions) { const auto it = - std::find_if(properties.begin(), properties.end(), [extension](const auto& prop) { + std::find_if(properties->begin(), properties->end(), [extension](const auto& prop) { return !std::strcmp(extension, prop.extensionName); }); - if (it == properties.end()) { + if (it == properties->end()) { LOG_ERROR(Render_Vulkan, "Required instance extension {} is not available", extension); - return UniqueInstance{}; + return {}; } } - const vk::ApplicationInfo application_info("yuzu Emulator", VK_MAKE_VERSION(0, 1, 0), - "yuzu Emulator", VK_MAKE_VERSION(0, 1, 0), - VK_API_VERSION_1_1); - const std::array layers = {"VK_LAYER_LUNARG_standard_validation"}; - const vk::InstanceCreateInfo instance_ci( - {}, &application_info, enable_layers ? static_cast<u32>(layers.size()) : 0, layers.data(), - static_cast<u32>(extensions.size()), extensions.data()); - vk::Instance unsafe_instance; - if (vk::createInstance(&instance_ci, nullptr, &unsafe_instance, dld) != vk::Result::eSuccess) { + static constexpr std::array layers_data{"VK_LAYER_LUNARG_standard_validation"}; + vk::Span<const char*> layers = layers_data; + if (!enable_layers) { + layers = {}; + } + vk::Instance instance = vk::Instance::Create(layers, extensions, dld); + if (!instance) { LOG_ERROR(Render_Vulkan, "Failed to create Vulkan instance"); - return UniqueInstance{}; + return {}; + } + if (!vk::Load(*instance, dld)) { + LOG_ERROR(Render_Vulkan, "Failed to load Vulkan instance function pointers"); } - dld.init(unsafe_instance); - return UniqueInstance(unsafe_instance, {nullptr, dld}); + return instance; } std::string GetReadableVersion(u32 version) { @@ -187,14 +182,14 @@ std::string GetDriverVersion(const VKDevice& device) { // https://github.com/SaschaWillems/vulkan.gpuinfo.org/blob/5dddea46ea1120b0df14eef8f15ff8e318e35462/functions.php#L308-L314 const u32 version = device.GetDriverVersion(); - if (device.GetDriverID() == vk::DriverIdKHR::eNvidiaProprietary) { + if (device.GetDriverID() == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { const u32 major = (version >> 22) & 0x3ff; const u32 minor = (version >> 14) & 0x0ff; const u32 secondary = (version >> 6) & 0x0ff; const u32 tertiary = version & 0x003f; return fmt::format("{}.{}.{}.{}", major, minor, secondary, tertiary); } - if (device.GetDriverID() == vk::DriverIdKHR::eIntelProprietaryWindows) { + if (device.GetDriverID() == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR) { const u32 major = version >> 14; const u32 minor = version & 0x3fff; return fmt::format("{}.{}", major, minor); @@ -307,10 +302,8 @@ void RendererVulkan::ShutDown() { if (!device) { return; } - const auto dev = device->GetLogical(); - const auto& dld = device->GetDispatchLoader(); - if (dev && dld.vkDeviceWaitIdle) { - dev.waitIdle(dld); + if (const auto& dev = device->GetLogical()) { + dev.WaitIdle(); } rasterizer.reset(); @@ -326,23 +319,11 @@ bool RendererVulkan::CreateDebugCallback() { if (!Settings::values.renderer_debug) { return true; } - const vk::DebugUtilsMessengerCreateInfoEXT callback_ci( - {}, - vk::DebugUtilsMessageSeverityFlagBitsEXT::eError | - vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning | - vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo | - vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose, - vk::DebugUtilsMessageTypeFlagBitsEXT::eGeneral | - vk::DebugUtilsMessageTypeFlagBitsEXT::eValidation | - vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance, - &DebugCallback, nullptr); - vk::DebugUtilsMessengerEXT unsafe_callback; - if (instance->createDebugUtilsMessengerEXT(&callback_ci, nullptr, &unsafe_callback, dld) != - vk::Result::eSuccess) { + debug_callback = instance.TryCreateDebugCallback(DebugCallback); + if (!debug_callback) { LOG_ERROR(Render_Vulkan, "Failed to create debug callback"); return false; } - debug_callback = UniqueDebugUtilsMessengerEXT(unsafe_callback, {*instance, nullptr, dld}); return true; } @@ -357,8 +338,8 @@ bool RendererVulkan::CreateSurface() { nullptr, 0, nullptr, hWnd}; const auto vkCreateWin32SurfaceKHR = reinterpret_cast<PFN_vkCreateWin32SurfaceKHR>( dld.vkGetInstanceProcAddr(*instance, "vkCreateWin32SurfaceKHR")); - if (!vkCreateWin32SurfaceKHR || vkCreateWin32SurfaceKHR(instance.get(), &win32_ci, nullptr, - &unsafe_surface) != VK_SUCCESS) { + if (!vkCreateWin32SurfaceKHR || + vkCreateWin32SurfaceKHR(*instance, &win32_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { LOG_ERROR(Render_Vulkan, "Failed to initialize Win32 surface"); return false; } @@ -372,8 +353,8 @@ bool RendererVulkan::CreateSurface() { reinterpret_cast<Window>(window_info.render_surface)}; const auto vkCreateXlibSurfaceKHR = reinterpret_cast<PFN_vkCreateXlibSurfaceKHR>( dld.vkGetInstanceProcAddr(*instance, "vkCreateXlibSurfaceKHR")); - if (!vkCreateXlibSurfaceKHR || vkCreateXlibSurfaceKHR(instance.get(), &xlib_ci, nullptr, - &unsafe_surface) != VK_SUCCESS) { + if (!vkCreateXlibSurfaceKHR || + vkCreateXlibSurfaceKHR(*instance, &xlib_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { LOG_ERROR(Render_Vulkan, "Failed to initialize Xlib surface"); return false; } @@ -386,7 +367,7 @@ bool RendererVulkan::CreateSurface() { const auto vkCreateWaylandSurfaceKHR = reinterpret_cast<PFN_vkCreateWaylandSurfaceKHR>( dld.vkGetInstanceProcAddr(*instance, "vkCreateWaylandSurfaceKHR")); if (!vkCreateWaylandSurfaceKHR || - vkCreateWaylandSurfaceKHR(instance.get(), &wayland_ci, nullptr, &unsafe_surface) != + vkCreateWaylandSurfaceKHR(*instance, &wayland_ci, nullptr, &unsafe_surface) != VK_SUCCESS) { LOG_ERROR(Render_Vulkan, "Failed to initialize Wayland surface"); return false; @@ -398,26 +379,30 @@ bool RendererVulkan::CreateSurface() { return false; } - surface = UniqueSurfaceKHR(unsafe_surface, {*instance, nullptr, dld}); + surface = vk::SurfaceKHR(unsafe_surface, *instance, dld); return true; } bool RendererVulkan::PickDevices() { - const auto devices = instance->enumeratePhysicalDevices(dld); + const auto devices = instance.EnumeratePhysicalDevices(); + if (!devices) { + LOG_ERROR(Render_Vulkan, "Failed to enumerate physical devices"); + return false; + } const s32 device_index = Settings::values.vulkan_device; - if (device_index < 0 || device_index >= static_cast<s32>(devices.size())) { + if (device_index < 0 || device_index >= static_cast<s32>(devices->size())) { LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index); return false; } - const vk::PhysicalDevice physical_device = devices[static_cast<std::size_t>(device_index)]; - - if (!VKDevice::IsSuitable(physical_device, *surface, dld)) { + const vk::PhysicalDevice physical_device((*devices)[static_cast<std::size_t>(device_index)], + dld); + if (!VKDevice::IsSuitable(physical_device, *surface)) { return false; } - device = std::make_unique<VKDevice>(dld, physical_device, *surface); - return device->Create(*instance); + device = std::make_unique<VKDevice>(*instance, physical_device, *surface, dld); + return device->Create(); } void RendererVulkan::Report() const { @@ -444,30 +429,22 @@ void RendererVulkan::Report() const { } std::vector<std::string> RendererVulkan::EnumerateDevices() { - // Avoid putting DispatchLoaderDynamic, it's too large - auto dld_memory = std::make_unique<vk::DispatchLoaderDynamic>(); - auto& dld = *dld_memory; - + vk::InstanceDispatch dld; Common::DynamicLibrary library = OpenVulkanLibrary(); - UniqueInstance instance = CreateInstance(library, dld); + vk::Instance 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) { + const std::optional physical_devices = instance.EnumeratePhysicalDevices(); + if (!physical_devices) { return {}; } std::vector<std::string> names; - names.reserve(num_devices); - for (auto& device : devices) { - names.push_back(device.getProperties(dld).deviceName); + names.reserve(physical_devices->size()); + for (const auto& device : *physical_devices) { + names.push_back(vk::PhysicalDevice(device, dld).GetProperties().deviceName); } return names; } |