diff --git a/src/xrt/compositor/util/comp_vulkan.c b/src/xrt/compositor/util/comp_vulkan.c index 42c612f38..42347f7d2 100644 --- a/src/xrt/compositor/util/comp_vulkan.c +++ b/src/xrt/compositor/util/comp_vulkan.c @@ -13,6 +13,8 @@ #include "os/os_time.h" +#include + #include "util/u_handles.h" #include "util/u_trace_marker.h" @@ -30,7 +32,7 @@ #define UUID_STR_SIZE (XRT_UUID_SIZE * 3 + 1) static void -snprint_luid(char *str, size_t size, xrt_luid_t *luid) +snprint_luid(char *str, size_t size, const xrt_luid_t *luid) { for (size_t i = 0, offset = 0; i < ARRAY_SIZE(luid->data) && offset < size; i++, offset += 3) { snprintf(str + offset, size - offset, "%02x ", luid->data[i]); @@ -38,7 +40,7 @@ snprint_luid(char *str, size_t size, xrt_luid_t *luid) } static void -snprint_uuid(char *str, size_t size, xrt_uuid_t *uuid) +snprint_uuid(char *str, size_t size, const xrt_uuid_t *uuid) { for (size_t i = 0, offset = 0; i < ARRAY_SIZE(uuid->data) && offset < size; i++, offset += 3) { snprintf(str + offset, size - offset, "%02x ", uuid->data[i]); @@ -99,6 +101,65 @@ get_device_uuid(struct vk_bundle *vk, int gpu_index, xrt_uuid_t *uuid) return true; } +static VkResult +resolve_selected_gpu_index(struct vk_bundle *vk, const struct comp_vulkan_arguments *vk_args, int *out_index) +{ + if (!vk_args->lookup_with_uuid) { + *out_index = vk_args->selected_gpu_index; + return VK_SUCCESS; + } + + VkPhysicalDevice *phys = NULL; + uint32_t gpu_count = 0; + VkResult ret; + + ret = vk_enumerate_physical_devices( // + vk, // vk_bundle + &gpu_count, // out_physical_device_count + &phys); // out_physical_devices + if (ret != VK_SUCCESS) { + VK_ERROR_RET(vk, "vk_enumerate_physical_devices", "Failed to enumerate physical devices.", ret); + return ret; + } + if (gpu_count == 0) { + VK_ERROR(vk, "vk_enumerate_physical_devices: Returned zero physical devices!"); + free(phys); + return VK_ERROR_DEVICE_LOST; + } + + for (uint32_t i = 0; i < gpu_count; i++) { + VkPhysicalDeviceIDProperties pdidp = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES, + }; + + VkPhysicalDeviceProperties2 pdp2 = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, + .pNext = &pdidp, + }; + + vk->vkGetPhysicalDeviceProperties2(phys[i], &pdp2); + + if (memcmp(pdidp.deviceUUID, vk_args->selected_gpu_uuid.data, XRT_UUID_SIZE) == 0) { + char uuid_str[UUID_STR_SIZE] = {0}; + snprint_uuid(uuid_str, ARRAY_SIZE(uuid_str), &vk_args->selected_gpu_uuid); + + VK_DEBUG(vk, "Matched Vulkan device %u with uuid: %s", i, uuid_str); + *out_index = (int)i; + free(phys); + return VK_SUCCESS; + } + } + + { + char uuid_str[UUID_STR_SIZE] = {0}; + snprint_uuid(uuid_str, ARRAY_SIZE(uuid_str), &vk_args->selected_gpu_uuid); + VK_ERROR(vk, "No Vulkan device found matching uuid: %s", uuid_str); + } + + free(phys); + return VK_ERROR_DEVICE_LOST; +} + static bool get_device_luid(struct vk_bundle *vk, int gpu_index, xrt_luid_t *luid) { @@ -268,6 +329,12 @@ create_device(struct vk_bundle *vk, const struct comp_vulkan_arguments *vk_args) }; const bool only_compute_queue = vk_args->only_compute_queue; + int gpu_index = -1; + + ret = resolve_selected_gpu_index(vk, vk_args, &gpu_index); + if (ret != VK_SUCCESS) { + return ret; + } struct vk_device_features device_features = { .shader_image_gather_extended = true, @@ -293,7 +360,7 @@ create_device(struct vk_bundle *vk, const struct comp_vulkan_arguments *vk_args) for (size_t i = 0; i < ARRAY_SIZE(prios); i++) { ret = vk_create_device( // vk, // - vk_args->selected_gpu_index, // + gpu_index, // only_compute_queue, // compute_only prios[i], // global_priority vk_args->required_device_extensions, // diff --git a/src/xrt/compositor/util/comp_vulkan.h b/src/xrt/compositor/util/comp_vulkan.h index 6dad09b95..1b49a20f4 100644 --- a/src/xrt/compositor/util/comp_vulkan.h +++ b/src/xrt/compositor/util/comp_vulkan.h @@ -59,6 +59,12 @@ struct comp_vulkan_arguments //! Vulkan physical device to be selected, -1 for auto. int selected_gpu_index; + //! When true, select the physical device whose UUID matches @ref selected_gpu_uuid. + bool lookup_with_uuid; + + //! Vulkan physical device UUID to select when @ref lookup_with_uuid is true. + xrt_uuid_t selected_gpu_uuid; + //! Vulkan physical device index for clients to use, -1 for auto. int client_gpu_index; }; diff --git a/tests/tests_comp_client_vulkan.cpp b/tests/tests_comp_client_vulkan.cpp index 7b0b046a5..d8280a0df 100644 --- a/tests/tests_comp_client_vulkan.cpp +++ b/tests/tests_comp_client_vulkan.cpp @@ -117,17 +117,21 @@ TEST_CASE("client_compositor", "[.][needgpu]") unique_string_list optional_device_extension_list{u_extension_list_create()}; - comp_vulkan_arguments args{VK_MAKE_VERSION(1, 0, 0), - vkGetInstanceProcAddr, - required_instance_ext_list.get(), - optional_instance_ext_list.get(), - required_device_extension_list.get(), - optional_device_extension_list.get(), - U_LOGGING_TRACE, - false /* only_compute_queue */, - true /*timeline_semaphore*/, - -1, - -1}; + comp_vulkan_arguments args{ + VK_MAKE_VERSION(1, 0, 0), + vkGetInstanceProcAddr, + required_instance_ext_list.get(), + optional_instance_ext_list.get(), + required_device_extension_list.get(), + optional_device_extension_list.get(), + U_LOGGING_TRACE, + false /* only_compute_queue */, + true /*timeline_semaphore*/, + -1, + false, + xrt_uuid_t{}, + -1, + }; vk_bundle vk_bundle_storage{}; vk_bundle *vk = &vk_bundle_storage; comp_vulkan_results results{}; diff --git a/tests/tests_render_pipeline_cache.cpp b/tests/tests_render_pipeline_cache.cpp index fb82399bf..1e7f7b23a 100644 --- a/tests/tests_render_pipeline_cache.cpp +++ b/tests/tests_render_pipeline_cache.cpp @@ -97,6 +97,8 @@ struct MinimalVulkanContext .only_compute_queue = false, .timeline_semaphore = false, .selected_gpu_index = -1, + .lookup_with_uuid = false, + .selected_gpu_uuid = {}, .client_gpu_index = -1, }; diff --git a/tests/vktest_init_bundle.hpp b/tests/vktest_init_bundle.hpp index eb0f26a53..1b7a0ed74 100644 --- a/tests/vktest_init_bundle.hpp +++ b/tests/vktest_init_bundle.hpp @@ -131,17 +131,22 @@ vktest_init_bundle(struct vk_bundle *vk) u_extension_list_create_from_array(optional_device_extensions, ARRAY_SIZE(optional_device_extensions))}; U_ZERO(vk); - comp_vulkan_arguments args{VK_MAKE_VERSION(1, 0, 0), - vkGetInstanceProcAddr, - required_instance_ext_list.get(), - optional_instance_ext_list.get(), - required_device_extension_list.get(), - optional_device_extension_list.get(), - U_LOGGING_TRACE, - false /* only_compute_queue */, - true /*timeline_semaphore*/, - -1, - -1}; + comp_vulkan_arguments args{ + VK_MAKE_VERSION(1, 0, 0), + vkGetInstanceProcAddr, + required_instance_ext_list.get(), + optional_instance_ext_list.get(), + required_device_extension_list.get(), + optional_device_extension_list.get(), + U_LOGGING_TRACE, + false /* only_compute_queue */, + true /*timeline_semaphore*/, + -1, + false, + xrt_uuid_t{}, + -1, + }; + comp_vulkan_results results{}; bool success = comp_vulkan_init_bundle(vk, &args, &results);