From: Gurchetan Singh Date: Fri, 21 Mar 2025 15:07:20 +0000 (-0700) Subject: [PATCH] gfxstream: follow the semantics desired by distro VK loader X-Git-Tag: archive/raspbian/25.0.7-2+rpi1^2^2^2^2^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=f3f948030940b0b79914f79a810e360383a1cf41;p=mesa.git [PATCH] gfxstream: follow the semantics desired by distro VK loader - vkCreateInstance should return VK_SUCCESS absent a few specific conditions - just don't add any physical devices later Cc: mesa-stable Reviewed-by: Aaron Ruby Gbp-Pq: Name gfxstream-follow-the-semantics-desired-by-distro-VK.diff --- diff --git a/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp b/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp index ef874b9f4..abd078010 100644 --- a/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp +++ b/src/gfxstream/guest/vulkan/gfxstream_vk_device.cpp @@ -77,7 +77,7 @@ static VkResult SetupInstanceForProcess(void) { auto mgr = getConnectionManager(); if (!mgr) { mesa_logd("vulkan: Failed to get host connection\n"); - return VK_ERROR_DEVICE_LOST; + return VK_ERROR_INITIALIZATION_FAILED; } gfxstream::vk::ResourceTracker::get()->setupCaps(gNoRenderControlEnc); @@ -231,6 +231,11 @@ static void gfxstream_vk_destroy_physical_device(struct vk_physical_device* phys static VkResult gfxstream_vk_enumerate_devices(struct vk_instance* vk_instance) { VkResult result = VK_SUCCESS; gfxstream_vk_instance* gfxstream_instance = (gfxstream_vk_instance*)vk_instance; + + if (gfxstream_instance->init_failed) { + return VK_SUCCESS; + } + uint32_t deviceCount = 0; auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder(); auto resources = gfxstream::vk::ResourceTracker::get(); @@ -315,24 +320,48 @@ VkResult gfxstream_vk_CreateInstance(const VkInstanceCreateInfo* pCreateInfo, MESA_TRACE_SCOPE("vkCreateInstance"); struct gfxstream_vk_instance* instance; + VkResult result = VK_SUCCESS; pAllocator = pAllocator ?: vk_default_allocator(); - instance = (struct gfxstream_vk_instance*)vk_zalloc(pAllocator, sizeof(*instance), GFXSTREAM_DEFAULT_ALIGN, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (NULL == instance) { + instance = (struct gfxstream_vk_instance*)vk_zalloc( + pAllocator, sizeof(*instance), GFXSTREAM_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + + if (!instance) { return vk_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY); } - VkResult result = VK_SUCCESS; + instance->init_failed = (SetupInstanceForProcess() == VK_ERROR_INITIALIZATION_FAILED); + auto extensions = instance->init_failed ? &gfxstream_vk_instance_extensions_supported + : get_instance_extensions(); + struct vk_instance_dispatch_table dispatch_table; + memset(&dispatch_table, 0, sizeof(struct vk_instance_dispatch_table)); + vk_instance_dispatch_table_from_entrypoints(&dispatch_table, &gfxstream_vk_instance_entrypoints, + false); +#if !DETECT_OS_FUCHSIA + vk_instance_dispatch_table_from_entrypoints(&dispatch_table, &wsi_instance_entrypoints, false); +#endif + + result = vk_instance_init(&instance->vk, extensions, &dispatch_table, pCreateInfo, pAllocator); + + if (result != VK_SUCCESS) { + vk_free(pAllocator, instance); + return vk_error(NULL, result); + } + + // Note: Do not support try_create_for_drm. virtio_gpu DRM device opened in + // init_renderer above, which can still enumerate multiple physical devices on the host. + instance->vk.physical_devices.enumerate = gfxstream_vk_enumerate_devices; + instance->vk.physical_devices.destroy = gfxstream_vk_destroy_physical_device; + + if (instance->init_failed) { + goto out; + } + /* Encoder call */ { - result = SetupInstanceForProcess(); - if (VK_SUCCESS != result) { - vk_free(pAllocator, instance); - return vk_error(NULL, result); - } uint32_t initialEnabledExtensionCount = pCreateInfo->enabledExtensionCount; const char* const* initialPpEnabledExtensionNames = pCreateInfo->ppEnabledExtensionNames; + std::vector filteredExts = filteredInstanceExtensionNames( pCreateInfo->enabledExtensionCount, pCreateInfo->ppEnabledExtensionNames); // Temporarily modify createInfo for the encoder call @@ -352,27 +381,7 @@ VkResult gfxstream_vk_CreateInstance(const VkInstanceCreateInfo* pCreateInfo, mutableCreateInfo->ppEnabledExtensionNames = initialPpEnabledExtensionNames; } - struct vk_instance_dispatch_table dispatch_table; - memset(&dispatch_table, 0, sizeof(struct vk_instance_dispatch_table)); - vk_instance_dispatch_table_from_entrypoints(&dispatch_table, &gfxstream_vk_instance_entrypoints, - false); -#if !DETECT_OS_FUCHSIA - vk_instance_dispatch_table_from_entrypoints(&dispatch_table, &wsi_instance_entrypoints, false); -#endif - - result = vk_instance_init(&instance->vk, get_instance_extensions(), &dispatch_table, - pCreateInfo, pAllocator); - - if (result != VK_SUCCESS) { - vk_free(pAllocator, instance); - return vk_error(NULL, result); - } - - // Note: Do not support try_create_for_drm. virtio_gpu DRM device opened in - // init_renderer above, which can still enumerate multiple physical devices on the host. - instance->vk.physical_devices.enumerate = gfxstream_vk_enumerate_devices; - instance->vk.physical_devices.destroy = gfxstream_vk_destroy_physical_device; - +out: *pInstance = gfxstream_vk_instance_to_handle(instance); return VK_SUCCESS; } @@ -383,8 +392,10 @@ void gfxstream_vk_DestroyInstance(VkInstance _instance, const VkAllocationCallba VK_FROM_HANDLE(gfxstream_vk_instance, instance, _instance); - auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder(); - vkEnc->vkDestroyInstance(instance->internal_object, pAllocator, true /* do lock */); + if (!instance->init_failed) { + auto vkEnc = gfxstream::vk::ResourceTracker::getThreadLocalEncoder(); + vkEnc->vkDestroyInstance(instance->internal_object, pAllocator, true /* do lock */); + } vk_instance_finish(&instance->vk); vk_free(&instance->vk.alloc, instance); diff --git a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h index 164c227d6..b9dc22cc0 100644 --- a/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h +++ b/src/gfxstream/guest/vulkan_enc/gfxstream_vk_private.h @@ -62,6 +62,7 @@ struct gfxstream_vk_instance { struct vk_instance vk; uint32_t api_version; + bool init_failed; VkInstance internal_object; };