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 <aruby@qnx.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/34090>
This commit is contained in:
Gurchetan Singh 2025-03-21 08:07:20 -07:00 committed by Marge Bot
parent ef84cd928e
commit 8f003dc2e9
2 changed files with 44 additions and 34 deletions

View file

@ -80,7 +80,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);
@ -250,6 +250,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();
@ -335,23 +340,45 @@ 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);
}
// Full local copy of pCreateInfo
VkInstanceCreateInfo localCreateInfo = *pCreateInfo;
std::vector<const char*> filteredExts = filteredInstanceExtensionNames(
@ -368,27 +395,7 @@ VkResult gfxstream_vk_CreateInstance(const VkInstanceCreateInfo* pCreateInfo,
}
}
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;
}
@ -399,8 +406,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);

View file

@ -62,6 +62,7 @@
struct gfxstream_vk_instance {
struct vk_instance vk;
uint32_t api_version;
bool init_failed;
VkInstance internal_object;
};