libretro Vulkan: an instance of the version the loader has

The application info the core hands the frontend for its instance asks
for the highest version the Vulkan loader has, up to 1.2, instead of
1.0. The backend calls the 1.1 queries (vkGetPhysicalDeviceProperties2
and Features2) where the device has them; on a 1.0 instance those were
invalid, and the loader answered them by emulation that drops the
structures chained to them, so no extension feature could be queried.
The memory allocator is told the lower of the instance's and the
device's versions.
This commit is contained in:
LibretroAdmin authored and libretroadmin committed 2026-11-07 00:42:44 +01:00
1 parent 2dd80c5c2e
commit 2a77d9ced6
3 files changed
+23 -3

No files matched your search

+12 -2
View File
@@ -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");
@@ -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> 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)
@@ -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);