diff --git a/Source/Core/DolphinLibretro/Video.cpp b/Source/Core/DolphinLibretro/Video.cpp index dcefba80ea..50b8ebb57b 100644 --- a/Source/Core/DolphinLibretro/Video.cpp +++ b/Source/Core/DolphinLibretro/Video.cpp @@ -719,6 +719,13 @@ void ContextDestroy(void) #ifdef HAS_VULKAN namespace Vk { +/* The instance the frontend makes for the core: the version the loader + * has, up to 1.2, as the backend calls the 1.1 functions (the Properties2 + * and Features2 queries and the feature chain they fill) where the device + * has them, which a 1.0 instance leaves the loader emulating without the + * chain. */ +static u32 s_instance_api_version = VK_API_VERSION_1_0; + const VkApplicationInfo* GetApplicationInfo(void) { static VkApplicationInfo app_info{VK_STRUCTURE_TYPE_APPLICATION_INFO}; @@ -726,7 +733,10 @@ const VkApplicationInfo* GetApplicationInfo(void) app_info.applicationVersion = 5; // TODO: extract from Common::scm_desc_str app_info.pEngineName = "Dolphin-Emu"; app_info.engineVersion = 2; - app_info.apiVersion = VK_API_VERSION_1_0; + s_instance_api_version = Vulkan::LoadVulkanLibrary() ? + Vulkan::VulkanContext::GetInstanceAPIVersion() : + VK_API_VERSION_1_0; + app_info.apiVersion = s_instance_api_version; return &app_info; } @@ -803,7 +813,7 @@ static bool CreateDeviceInternal( if (gpu == VK_NULL_HANDLE) gpu = gpu_list[0]; Vulkan::g_vulkan_context = - Vulkan::VulkanContext::Create(instance, gpu, surface, false, false, VK_API_VERSION_1_0); + Vulkan::VulkanContext::Create(instance, gpu, surface, false, false, s_instance_api_version); if (!Vulkan::g_vulkan_context) { ERROR_LOG_FMT(VIDEO, "Failed to create Vulkan device"); diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index 83b380ff14..7a207f6178 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -222,6 +222,11 @@ static u32 getAPIVersion() return used_version; } +u32 VulkanContext::GetInstanceAPIVersion() +{ + return getAPIVersion(); +} + VkInstance VulkanContext::CreateVulkanInstance(WindowSystemType wstype, bool enable_debug_utils, bool enable_validation_layer, u32* out_vk_api_version) @@ -596,7 +601,9 @@ std::unique_ptr VulkanContext::Create(VkInstance instance, VkPhys // Attempt to create the device. if (!context->CreateDevice(surface, enable_validation_layer) || - !context->CreateAllocator(vk_api_version)) + !context->CreateAllocator(std::min( + vk_api_version, VK_MAKE_API_VERSION(0, VK_API_VERSION_MAJOR(context->m_device_info.apiVersion), + VK_API_VERSION_MINOR(context->m_device_info.apiVersion), 0)))) { // Since we are destroying the instance, we're also responsible for destroying the surface. if (surface != VK_NULL_HANDLE) diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.h b/Source/Core/VideoBackends/Vulkan/VulkanContext.h index 4d033fe58d..32f1f4e3e5 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.h +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.h @@ -62,6 +62,9 @@ public: // Determines if the Vulkan validation layer is available on the system. static bool CheckValidationLayerAvailablility(); + // The instance version to ask for: the highest up to 1.2 the loader has (the library loaded). + static u32 GetInstanceAPIVersion(); + // Helper method to create a Vulkan instance. static VkInstance CreateVulkanInstance(WindowSystemType wstype, bool enable_debug_utils, bool enable_validation_layer, u32* out_vk_api_version);