The open source OpenXR runtime

xrt: refactor vk queue mutex into mutex per queue

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2594>

+218 -93
+99 -30
src/xrt/auxiliary/vk/vk_bundle_init.c
··· 230 */ 231 232 static void 233 - fill_in_device_features(struct vk_bundle *vk) 234 { 235 /* 236 * Device properties. ··· 252 uint32_t count = 0; 253 vk->vkGetPhysicalDeviceQueueFamilyProperties(vk->physical_device, &count, NULL); 254 assert(count != 0); 255 - assert(count > vk->main_queue.family_index); 256 257 VkQueueFamilyProperties *props = U_TYPED_ARRAY_CALLOC(VkQueueFamilyProperties, count); 258 vk->vkGetPhysicalDeviceQueueFamilyProperties(vk->physical_device, &count, props); 259 260 - vk->features.timestamp_valid_bits = props[vk->main_queue.family_index].timestampValidBits; 261 free(props); 262 } 263 ··· 1237 device_features->video_maintenance_1); // 1238 } 1239 1240 1241 /* 1242 * ··· 1296 return VK_ERROR_NOT_PERMITTED_EXT; 1297 } 1298 1299 - vk->main_queue = VK_BUNDLE_NULL_QUEUE; 1300 if (only_compute) { 1301 - ret = find_queue_family(vk, VK_QUEUE_COMPUTE_BIT, &vk->main_queue.family_index); 1302 } else { 1303 - ret = find_graphics_queue_family(vk, &vk->main_queue.family_index); 1304 } 1305 1306 if (ret != VK_SUCCESS) { ··· 1318 uint32_t queue_create_info_count = 1; 1319 1320 // Compute or Graphics queue 1321 - vk->main_queue.index = 0; 1322 queue_create_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 1323 queue_create_info[0].pNext = NULL; 1324 queue_create_info[0].queueCount = 1; 1325 - queue_create_info[0].queueFamilyIndex = vk->main_queue.family_index; 1326 queue_create_info[0].pQueuePriorities = &queue_priority; 1327 1328 #ifdef VK_KHR_video_encode_queue 1329 // Video encode queue 1330 - vk->encode_queue = VK_BUNDLE_NULL_QUEUE; 1331 if (u_string_list_contains(device_ext_list, VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME)) { 1332 - ret = find_queue_family(vk, VK_QUEUE_VIDEO_ENCODE_BIT_KHR, &vk->encode_queue.family_index); 1333 if (ret == VK_SUCCESS) { 1334 - vk->encode_queue.index = 0; 1335 queue_create_info[queue_create_info_count].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 1336 queue_create_info[queue_create_info_count].pNext = NULL; 1337 queue_create_info[queue_create_info_count].queueCount = 1; 1338 - queue_create_info[queue_create_info_count].queueFamilyIndex = vk->encode_queue.family_index; 1339 queue_create_info[queue_create_info_count].pQueuePriorities = &queue_priority; 1340 queue_create_info_count++; 1341 - VK_DEBUG(vk, "Creating video encode queue, family index %d", vk->encode_queue.family_index); 1342 } 1343 } 1344 #endif ··· 1503 } 1504 1505 // Fill in the device features we are interested in. 1506 - fill_in_device_features(vk); 1507 1508 // We fill in these here as we want to be sure we have selected the physical device fully. 1509 fill_in_external_object_properties(vk); ··· 1513 if (ret != VK_SUCCESS) { 1514 goto err_destroy; 1515 } 1516 - vk->vkGetDeviceQueue(vk->device, vk->main_queue.family_index, vk->main_queue.index, &vk->main_queue.queue); 1517 #if defined(VK_KHR_video_encode_queue) 1518 - if (vk->encode_queue.family_index != VK_QUEUE_FAMILY_IGNORED) { 1519 - vk->vkGetDeviceQueue(vk->device, vk->encode_queue.family_index, vk->encode_queue.index, 1520 - &vk->encode_queue.queue); 1521 - } 1522 #endif 1523 1524 // Need to do this after functions have been gotten. ··· 1537 VkResult 1538 vk_init_mutex(struct vk_bundle *vk) 1539 { 1540 - if (os_mutex_init(&vk->queue_mutex) < 0) { 1541 - return VK_ERROR_INITIALIZATION_FAILED; 1542 } 1543 return VK_SUCCESS; 1544 } ··· 1546 VkResult 1547 vk_deinit_mutex(struct vk_bundle *vk) 1548 { 1549 - os_mutex_destroy(&vk->queue_mutex); 1550 return VK_SUCCESS; 1551 } 1552 - 1553 1554 /* 1555 * ··· 1578 U_ZERO(vk); 1579 vk->log_level = log_level; 1580 1581 ret = vk_get_loader_functions(vk, vkGetInstanceProcAddr); 1582 if (ret != VK_SUCCESS) { 1583 goto err_memset; ··· 1586 vk->instance = instance; 1587 vk->physical_device = physical_device; 1588 vk->device = device; 1589 - vk->main_queue.family_index = queue_family_index; 1590 - vk->main_queue.index = queue_index; 1591 - #ifdef VK_KHR_video_encode_queue 1592 - vk->encode_queue = VK_BUNDLE_NULL_QUEUE; 1593 - #endif 1594 1595 // Fill in all instance functions. 1596 ret = vk_get_instance_functions(vk); ··· 1628 } 1629 #endif 1630 1631 // Fill in the device features we are interested in. 1632 - fill_in_device_features(vk); 1633 1634 // Fill in external object properties. 1635 fill_in_external_object_properties(vk); ··· 1640 goto err_memset; 1641 } 1642 1643 - vk->vkGetDeviceQueue(vk->device, vk->main_queue.family_index, vk->main_queue.index, &vk->main_queue.queue); 1644 1645 vk->has_EXT_debug_utils = false; 1646 if (debug_utils_enabled) {
··· 230 */ 231 232 static void 233 + fill_in_device_features(struct vk_bundle *vk, const uint32_t queue_family_index) 234 { 235 /* 236 * Device properties. ··· 252 uint32_t count = 0; 253 vk->vkGetPhysicalDeviceQueueFamilyProperties(vk->physical_device, &count, NULL); 254 assert(count != 0); 255 + assert(count > queue_family_index); 256 257 VkQueueFamilyProperties *props = U_TYPED_ARRAY_CALLOC(VkQueueFamilyProperties, count); 258 vk->vkGetPhysicalDeviceQueueFamilyProperties(vk->physical_device, &count, props); 259 260 + vk->features.timestamp_valid_bits = props[queue_family_index].timestampValidBits; 261 free(props); 262 } 263 ··· 1237 device_features->video_maintenance_1); // 1238 } 1239 1240 + static inline void 1241 + vk_reset_queues(struct vk_bundle *vk) 1242 + { 1243 + const struct vk_queue_pair null_queue_pair = VK_NULL_QUEUE_PAIR; 1244 + 1245 + for (uint32_t i = 0; i < ARRAY_SIZE(vk->queues); ++i) { 1246 + struct vk_bundle_queue *q = &vk->queues[i]; 1247 + q->queue = VK_NULL_HANDLE; 1248 + q->index = null_queue_pair.index; 1249 + q->family_index = null_queue_pair.family_index; 1250 + } 1251 + } 1252 + 1253 + static struct vk_bundle_queue * 1254 + vk_insert_get_queue(struct vk_bundle *vk, const struct vk_queue_pair *new_queue) 1255 + { 1256 + if (vk == NULL || // 1257 + new_queue == NULL || // 1258 + new_queue->index == (uint32_t)-1 || // 1259 + new_queue->family_index == VK_QUEUE_FAMILY_IGNORED) { 1260 + return NULL; 1261 + } 1262 + 1263 + /* 1264 + * The same queue can be used for different uses, but we need to have 1265 + * one mutex per queue, so look up if the queue has already been added. 1266 + */ 1267 + for (uint32_t i = 0; i < VK_BUNDLE_MAX_QUEUES; ++i) { 1268 + struct vk_bundle_queue *q = &vk->queues[i]; 1269 + if (q->queue != VK_NULL_HANDLE && // 1270 + new_queue->index == q->index && // 1271 + new_queue->family_index == q->family_index) { 1272 + return q; 1273 + } 1274 + } 1275 + 1276 + // Find the first unused queue bundle. 1277 + for (uint32_t i = 0; i < VK_BUNDLE_MAX_QUEUES; ++i) { 1278 + struct vk_bundle_queue *q = &vk->queues[i]; 1279 + if (q->queue != VK_NULL_HANDLE) { 1280 + continue; 1281 + } 1282 + 1283 + q->index = new_queue->index; 1284 + q->family_index = new_queue->family_index; 1285 + 1286 + vk->vkGetDeviceQueue(vk->device, q->family_index, q->index, &q->queue); 1287 + return q; 1288 + } 1289 + 1290 + VK_ERROR(vk, "failed to find a free queue, max queues reached"); 1291 + return NULL; 1292 + } 1293 + 1294 1295 /* 1296 * ··· 1350 return VK_ERROR_NOT_PERMITTED_EXT; 1351 } 1352 1353 + vk_reset_queues(vk); 1354 + 1355 + struct vk_queue_pair main_queue = VK_NULL_QUEUE_PAIR; 1356 if (only_compute) { 1357 + ret = find_queue_family(vk, VK_QUEUE_COMPUTE_BIT, &main_queue.family_index); 1358 } else { 1359 + ret = find_graphics_queue_family(vk, &main_queue.family_index); 1360 } 1361 1362 if (ret != VK_SUCCESS) { ··· 1374 uint32_t queue_create_info_count = 1; 1375 1376 // Compute or Graphics queue 1377 + main_queue.index = 0; 1378 queue_create_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 1379 queue_create_info[0].pNext = NULL; 1380 queue_create_info[0].queueCount = 1; 1381 + queue_create_info[0].queueFamilyIndex = main_queue.family_index; 1382 queue_create_info[0].pQueuePriorities = &queue_priority; 1383 1384 #ifdef VK_KHR_video_encode_queue 1385 // Video encode queue 1386 + struct vk_queue_pair encode_queue = VK_NULL_QUEUE_PAIR; 1387 if (u_string_list_contains(device_ext_list, VK_KHR_VIDEO_ENCODE_QUEUE_EXTENSION_NAME)) { 1388 + ret = find_queue_family(vk, VK_QUEUE_VIDEO_ENCODE_BIT_KHR, &encode_queue.family_index); 1389 if (ret == VK_SUCCESS) { 1390 + encode_queue.index = 0; 1391 queue_create_info[queue_create_info_count].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 1392 queue_create_info[queue_create_info_count].pNext = NULL; 1393 queue_create_info[queue_create_info_count].queueCount = 1; 1394 + queue_create_info[queue_create_info_count].queueFamilyIndex = encode_queue.family_index; 1395 queue_create_info[queue_create_info_count].pQueuePriorities = &queue_priority; 1396 queue_create_info_count++; 1397 + VK_DEBUG(vk, "Creating video encode queue, family index %d", encode_queue.family_index); 1398 } 1399 } 1400 #endif ··· 1559 } 1560 1561 // Fill in the device features we are interested in. 1562 + fill_in_device_features(vk, main_queue.family_index); 1563 1564 // We fill in these here as we want to be sure we have selected the physical device fully. 1565 fill_in_external_object_properties(vk); ··· 1569 if (ret != VK_SUCCESS) { 1570 goto err_destroy; 1571 } 1572 + 1573 + vk->main_queue = vk_insert_get_queue(vk, &main_queue); 1574 + assert(vk->main_queue != NULL); 1575 #if defined(VK_KHR_video_encode_queue) 1576 + vk->encode_queue = vk_insert_get_queue(vk, &encode_queue); 1577 #endif 1578 1579 // Need to do this after functions have been gotten. ··· 1592 VkResult 1593 vk_init_mutex(struct vk_bundle *vk) 1594 { 1595 + assert(vk != NULL); 1596 + 1597 + for (uint32_t i = 0; i < ARRAY_SIZE(vk->queues); ++i) { 1598 + struct vk_bundle_queue *q = &vk->queues[i]; 1599 + 1600 + if (os_mutex_init(&q->mutex) < 0) { 1601 + VK_ERROR(vk, "failed to initialize queue mutex"); 1602 + return VK_ERROR_INITIALIZATION_FAILED; 1603 + } 1604 } 1605 return VK_SUCCESS; 1606 } ··· 1608 VkResult 1609 vk_deinit_mutex(struct vk_bundle *vk) 1610 { 1611 + assert(vk != NULL); 1612 + 1613 + for (uint32_t i = 0; i < ARRAY_SIZE(vk->queues); ++i) { 1614 + struct vk_bundle_queue *q = &vk->queues[i]; 1615 + os_mutex_destroy(&q->mutex); 1616 + q->mutex = (struct os_mutex){0}; 1617 + } 1618 return VK_SUCCESS; 1619 } 1620 1621 /* 1622 * ··· 1645 U_ZERO(vk); 1646 vk->log_level = log_level; 1647 1648 + vk_reset_queues(vk); 1649 + 1650 ret = vk_get_loader_functions(vk, vkGetInstanceProcAddr); 1651 if (ret != VK_SUCCESS) { 1652 goto err_memset; ··· 1655 vk->instance = instance; 1656 vk->physical_device = physical_device; 1657 vk->device = device; 1658 1659 // Fill in all instance functions. 1660 ret = vk_get_instance_functions(vk); ··· 1692 } 1693 #endif 1694 1695 + const struct vk_queue_pair main_queue = { 1696 + .family_index = queue_family_index, 1697 + .index = queue_index, 1698 + }; 1699 // Fill in the device features we are interested in. 1700 + fill_in_device_features(vk, main_queue.family_index); 1701 1702 // Fill in external object properties. 1703 fill_in_external_object_properties(vk); ··· 1708 goto err_memset; 1709 } 1710 1711 + vk->main_queue = vk_insert_get_queue(vk, &main_queue); 1712 + assert(vk->main_queue != NULL); 1713 1714 vk->has_EXT_debug_utils = false; 1715 if (debug_utils_enabled) {
+2 -2
src/xrt/auxiliary/vk/vk_cmd.c
··· 83 { 84 VkResult ret; 85 86 - os_mutex_lock(&vk->queue_mutex); 87 ret = vk->vkQueueSubmit(queue->queue, count, infos, fence); 88 - os_mutex_unlock(&vk->queue_mutex); 89 90 if (ret != VK_SUCCESS) { 91 VK_ERROR(vk, "vkQueueSubmit: %s", vk_result_string(ret));
··· 83 { 84 VkResult ret; 85 86 + vk_queue_lock(queue); 87 ret = vk->vkQueueSubmit(queue->queue, count, infos, fence); 88 + vk_queue_unlock(queue); 89 90 if (ret != VK_SUCCESS) { 91 VK_ERROR(vk, "vkQueueSubmit: %s", vk_result_string(ret));
+1 -1
src/xrt/auxiliary/vk/vk_cmd_pool.h
··· 72 static inline XRT_CHECK_RESULT VkResult 73 vk_cmd_pool_init(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandPoolCreateFlags flags) 74 { 75 - return vk_cmd_pool_init_for_queue(vk, pool, flags, &vk->main_queue); 76 } 77 78 /*!
··· 72 static inline XRT_CHECK_RESULT VkResult 73 vk_cmd_pool_init(struct vk_bundle *vk, struct vk_cmd_pool *pool, VkCommandPoolCreateFlags flags) 74 { 75 + return vk_cmd_pool_init_for_queue(vk, pool, flags, vk->main_queue); 76 } 77 78 /*!
+51 -10
src/xrt/auxiliary/vk/vk_helpers.h
··· 33 extern "C" { 34 #endif 35 36 37 /* 38 * ··· 40 * 41 */ 42 43 - struct vk_bundle_queue 44 { 45 - //! The Vulkan queue handle 46 - VkQueue queue; 47 //! The queue family index 48 uint32_t family_index; 49 //! The queue (instance) index 50 uint32_t index; 51 }; 52 53 - #define VK_BUNDLE_NULL_QUEUE \ 54 - XRT_C11_COMPOUND(struct vk_bundle_queue) \ 55 { \ 56 - .queue = VK_NULL_HANDLE, .family_index = VK_QUEUE_FAMILY_IGNORED, .index = (uint32_t)-1, \ 57 } 58 59 /*! 60 * A bundle of Vulkan functions and objects, used by both @ref comp and @ref 61 * comp_client. Note that they both have different instances of the object, and ··· 72 VkPhysicalDevice physical_device; 73 int physical_device_index; 74 VkDevice device; 75 - struct vk_bundle_queue main_queue; 76 #if defined(VK_KHR_video_encode_queue) 77 - struct vk_bundle_queue encode_queue; 78 #endif 79 - 80 - struct os_mutex queue_mutex; 81 82 struct 83 { ··· 1086 */ 1087 VkResult 1088 vk_deinit_mutex(struct vk_bundle *vk); 1089 1090 /*! 1091 * Initialize a bundle with objects given to us by client code,
··· 33 extern "C" { 34 #endif 35 36 + #define VK_BUNDLE_MAX_QUEUES 2 37 38 /* 39 * ··· 41 * 42 */ 43 44 + struct vk_queue_pair 45 { 46 //! The queue family index 47 uint32_t family_index; 48 //! The queue (instance) index 49 uint32_t index; 50 }; 51 52 + #define VK_NULL_QUEUE_PAIR \ 53 + XRT_C11_COMPOUND(struct vk_queue_pair) \ 54 { \ 55 + .family_index = VK_QUEUE_FAMILY_IGNORED, .index = (uint32_t)-1, \ 56 } 57 58 + struct vk_bundle_queue 59 + { 60 + //! The Vulkan queue handle 61 + VkQueue queue; 62 + //! The queue family index 63 + uint32_t family_index; 64 + //! The queue (instance) index 65 + uint32_t index; 66 + //! The queue mutex - @see vk_queue_lock, vk_queue_unlock 67 + struct os_mutex mutex; 68 + }; 69 + 70 /*! 71 * A bundle of Vulkan functions and objects, used by both @ref comp and @ref 72 * comp_client. Note that they both have different instances of the object, and ··· 83 VkPhysicalDevice physical_device; 84 int physical_device_index; 85 VkDevice device; 86 + 87 + /*! 88 + * @brief queues - a free list of **unique** queues 89 + * 90 + * One per uniquely identifiable vk queue (family x instance index), 91 + * duplicate entries must not be stored. 92 + * 93 + * Should not be used directly, @see main_queue, encode_queue 94 + */ 95 + struct vk_bundle_queue queues[VK_BUNDLE_MAX_QUEUES]; 96 + 97 + struct vk_bundle_queue *main_queue; 98 #if defined(VK_KHR_video_encode_queue) 99 + struct vk_bundle_queue *encode_queue; 100 #endif 101 102 struct 103 { ··· 1106 */ 1107 VkResult 1108 vk_deinit_mutex(struct vk_bundle *vk); 1109 + 1110 + static inline void 1111 + vk_queue_lock(struct vk_bundle_queue *q) 1112 + { 1113 + assert(q != NULL); 1114 + os_mutex_lock(&q->mutex); 1115 + } 1116 + 1117 + static inline int 1118 + vk_queue_trylock(struct vk_bundle_queue *q) 1119 + { 1120 + assert(q != NULL); 1121 + return os_mutex_trylock(&q->mutex); 1122 + } 1123 + 1124 + static inline void 1125 + vk_queue_unlock(struct vk_bundle_queue *q) 1126 + { 1127 + assert(q != NULL); 1128 + os_mutex_unlock(&q->mutex); 1129 + } 1130 1131 /*! 1132 * Initialize a bundle with objects given to us by client code,
+23 -8
src/xrt/auxiliary/vk/vk_print.c
··· 39 } while (false) 40 41 static inline void 42 - print_queue(u_pp_delegate_t dg, const char *prefix, const struct vk_bundle_queue *queue) 43 { 44 PNT("%squeue.queue: %p", prefix, (const void *)queue->queue); 45 PNT("%squeue.index: %d", prefix, (int32_t)queue->index); 46 PNT("%squeue.family_index: %d", prefix, (int32_t)queue->family_index); 47 } 48 49 /* ··· 288 void 289 vk_print_queues_info(const struct vk_bundle *vk, enum u_logging_level log_level) 290 { 291 - struct vk_bundle_queue encode_queue = VK_BUNDLE_NULL_QUEUE; 292 - #if defined(VK_KHR_video_encode_queue) 293 - encode_queue = vk->encode_queue; 294 - #endif 295 - 296 struct u_pp_sink_stack_only sink; 297 u_pp_delegate_t dg = u_pp_sink_stack_only_init(&sink); 298 299 P("Selected Queues/Families:"); 300 - print_queue(dg, "main_", &vk->main_queue); 301 - print_queue(dg, "encode_", &encode_queue); 302 303 U_LOG_IFL(log_level, vk->log_level, "%s", sink.buffer); 304 }
··· 39 } while (false) 40 41 static inline void 42 + print_queue_non_null(u_pp_delegate_t dg, const char *prefix, const struct vk_bundle_queue *queue) 43 { 44 + assert(queue != NULL); 45 PNT("%squeue.queue: %p", prefix, (const void *)queue->queue); 46 PNT("%squeue.index: %d", prefix, (int32_t)queue->index); 47 PNT("%squeue.family_index: %d", prefix, (int32_t)queue->family_index); 48 + } 49 + 50 + static inline void 51 + print_queue(u_pp_delegate_t dg, const char *prefix, const struct vk_bundle_queue *queue) 52 + { 53 + if (queue != NULL) { 54 + print_queue_non_null(dg, prefix, queue); 55 + } else { 56 + const struct vk_queue_pair null_queue_pair = VK_NULL_QUEUE_PAIR; 57 + 58 + struct vk_bundle_queue null_queue = { 59 + .queue = VK_NULL_HANDLE, 60 + .family_index = null_queue_pair.family_index, 61 + .index = null_queue_pair.index, 62 + }; 63 + print_queue_non_null(dg, prefix, &null_queue); 64 + } 65 } 66 67 /* ··· 306 void 307 vk_print_queues_info(const struct vk_bundle *vk, enum u_logging_level log_level) 308 { 309 struct u_pp_sink_stack_only sink; 310 u_pp_delegate_t dg = u_pp_sink_stack_only_init(&sink); 311 312 P("Selected Queues/Families:"); 313 + print_queue(dg, "main_", vk->main_queue); 314 + #if defined(VK_KHR_video_encode_queue) 315 + print_queue(dg, "encode_", vk->encode_queue); 316 + #endif 317 318 U_LOG_IFL(log_level, vk->log_level, "%s", sink.buffer); 319 }
+7 -7
src/xrt/auxiliary/vk/vk_sync_objects.c
··· 142 * Submit fence. 143 */ 144 145 - os_mutex_lock(&vk->queue_mutex); 146 147 - ret = vk->vkQueueSubmit( // 148 - vk->main_queue.queue, // queue 149 - 0, // submitCount 150 - NULL, // pSubmits 151 - fence); // fence 152 153 - os_mutex_unlock(&vk->queue_mutex); 154 155 if (ret != VK_SUCCESS) { 156 VK_ERROR(vk, "vkQueueSubmit: %s", vk_result_string(ret));
··· 142 * Submit fence. 143 */ 144 145 + vk_queue_lock(vk->main_queue); 146 147 + ret = vk->vkQueueSubmit( // 148 + vk->main_queue->queue, // queue 149 + 0, // submitCount 150 + NULL, // pSubmits 151 + fence); // fence 152 153 + vk_queue_unlock(vk->main_queue); 154 155 if (ret != VK_SUCCESS) { 156 VK_ERROR(vk, "vkQueueSubmit: %s", vk_result_string(ret));
+9 -9
src/xrt/compositor/client/comp_vk_client.c
··· 178 .pSignalSemaphores = semaphores, 179 }; 180 181 - ret = vk->vkQueueSubmit( // 182 - vk->main_queue.queue, // queue 183 - 1, // submitCount 184 - &submit_info, // pSubmits 185 - VK_NULL_HANDLE); // fence 186 if (ret != VK_SUCCESS) { 187 VK_ERROR(vk, "vkQueueSubmit: %s", vk_result_string(ret)); 188 *out_xret = XRT_ERROR_VULKAN; ··· 245 COMP_TRACE_IDENT(device_wait_idle); 246 247 // Last course of action fallback. 248 - os_mutex_lock(&vk->queue_mutex); 249 - vk->vkQueueWaitIdle(vk->main_queue.queue); 250 - os_mutex_unlock(&vk->queue_mutex); 251 } 252 253 *out_xret = xrt_comp_layer_commit(&c->xcn->base, XRT_GRAPHICS_SYNC_HANDLE_INVALID); ··· 738 .dstAccessMask = 0, 739 .oldLayout = barrier_optimal_layout, 740 .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 741 - .srcQueueFamilyIndex = vk->main_queue.family_index, 742 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL, 743 .image = sc->base.images[i], 744 .subresourceRange = subresource_range,
··· 178 .pSignalSemaphores = semaphores, 179 }; 180 181 + ret = vk->vkQueueSubmit( // 182 + vk->main_queue->queue, // queue 183 + 1, // submitCount 184 + &submit_info, // pSubmits 185 + VK_NULL_HANDLE); // fence 186 if (ret != VK_SUCCESS) { 187 VK_ERROR(vk, "vkQueueSubmit: %s", vk_result_string(ret)); 188 *out_xret = XRT_ERROR_VULKAN; ··· 245 COMP_TRACE_IDENT(device_wait_idle); 246 247 // Last course of action fallback. 248 + vk_queue_lock(vk->main_queue); 249 + vk->vkQueueWaitIdle(vk->main_queue->queue); 250 + vk_queue_unlock(vk->main_queue); 251 } 252 253 *out_xret = xrt_comp_layer_commit(&c->xcn->base, XRT_GRAPHICS_SYNC_HANDLE_INVALID); ··· 738 .dstAccessMask = 0, 739 .oldLayout = barrier_optimal_layout, 740 .newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 741 + .srcQueueFamilyIndex = vk->main_queue->family_index, 742 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_EXTERNAL, 743 .image = sc->base.images[i], 744 .subresourceRange = subresource_range,
+11 -11
src/xrt/compositor/main/comp_renderer.c
··· 159 COMP_TRACE_MARKER(); 160 struct vk_bundle *vk = &r->c->base.vk; 161 162 - os_mutex_lock(&vk->queue_mutex); 163 - vk->vkQueueWaitIdle(vk->main_queue.queue); 164 - os_mutex_unlock(&vk->queue_mutex); 165 } 166 167 static void ··· 665 * us avoid taking a lot of locks. The queue lock will be taken by 666 * @ref vk_cmd_submit_locked tho. 667 */ 668 - ret = vk_cmd_submit_locked(vk, &vk->main_queue, 1, &comp_submit_info, r->fences[r->acquired_buffer]); 669 670 // We have now completed the submit, even if we failed. 671 comp_target_mark_submit_end(ct, frame_id, os_monotonic_get_ns()); ··· 741 assert(!comp_frame_is_invalid_locked(&r->c->frame.rendering)); 742 uint64_t render_complete_signal_value = (uint64_t)r->c->frame.rendering.id; 743 744 - ret = comp_target_present( // 745 - r->c->target, // 746 - r->c->base.vk.main_queue.queue, // 747 - r->acquired_buffer, // 748 - render_complete_signal_value, // 749 - desired_present_time_ns, // 750 - present_slop_ns); // 751 r->acquired_buffer = -1; 752 753 if (ret == VK_ERROR_OUT_OF_DATE_KHR || ret == VK_SUBOPTIMAL_KHR) {
··· 159 COMP_TRACE_MARKER(); 160 struct vk_bundle *vk = &r->c->base.vk; 161 162 + vk_queue_lock(vk->main_queue); 163 + vk->vkQueueWaitIdle(vk->main_queue->queue); 164 + vk_queue_unlock(vk->main_queue); 165 } 166 167 static void ··· 665 * us avoid taking a lot of locks. The queue lock will be taken by 666 * @ref vk_cmd_submit_locked tho. 667 */ 668 + ret = vk_cmd_submit_locked(vk, vk->main_queue, 1, &comp_submit_info, r->fences[r->acquired_buffer]); 669 670 // We have now completed the submit, even if we failed. 671 comp_target_mark_submit_end(ct, frame_id, os_monotonic_get_ns()); ··· 741 assert(!comp_frame_is_invalid_locked(&r->c->frame.rendering)); 742 uint64_t render_complete_signal_value = (uint64_t)r->c->frame.rendering.id; 743 744 + ret = comp_target_present( // 745 + r->c->target, // 746 + r->c->base.vk.main_queue->queue, // 747 + r->acquired_buffer, // 748 + render_complete_signal_value, // 749 + desired_present_time_ns, // 750 + present_slop_ns); // 751 r->acquired_buffer = -1; 752 753 if (ret == VK_ERROR_OUT_OF_DATE_KHR || ret == VK_SUBOPTIMAL_KHR) {
+3 -3
src/xrt/compositor/main/comp_target_swapchain.c
··· 682 // Can we create swapchains from the surface on this device and queue. 683 ret = vk->vkGetPhysicalDeviceSurfaceSupportKHR( // 684 vk->physical_device, // physicalDevice 685 - vk->main_queue.family_index, // queueFamilyIndex 686 cts->surface.handle, // surface 687 &supported); // pSupported 688 if (ret != VK_SUCCESS) { ··· 923 924 925 // Need to take the queue lock for present. 926 - os_mutex_lock(&vk->queue_mutex); 927 VkResult ret = vk->vkQueuePresentKHR(queue, &present_info); 928 - os_mutex_unlock(&vk->queue_mutex); 929 930 931 #ifdef VK_EXT_display_control
··· 682 // Can we create swapchains from the surface on this device and queue. 683 ret = vk->vkGetPhysicalDeviceSurfaceSupportKHR( // 684 vk->physical_device, // physicalDevice 685 + vk->main_queue->family_index, // queueFamilyIndex 686 cts->surface.handle, // surface 687 &supported); // pSupported 688 if (ret != VK_SUCCESS) { ··· 923 924 925 // Need to take the queue lock for present. 926 + vk_queue_lock(vk->main_queue); 927 VkResult ret = vk->vkQueuePresentKHR(queue, &present_info); 928 + vk_queue_unlock(vk->main_queue); 929 930 931 #ifdef VK_EXT_display_control
+6 -6
src/xrt/compositor/main/comp_window_peek.c
··· 266 267 struct vk_bundle *vk = get_vk(w); 268 269 - os_mutex_lock(&vk->queue_mutex); 270 vk->vkDeviceWaitIdle(vk->device); 271 - os_mutex_unlock(&vk->queue_mutex); 272 273 vk_cmd_pool_lock(&w->pool); 274 vk->vkFreeCommandBuffers(vk->device, w->pool.pool, 1, &w->cmd); ··· 434 }; 435 436 // Done writing commands, submit to queue. 437 - ret = vk_cmd_submit_locked(vk, &vk->main_queue, 1, &submit, VK_NULL_HANDLE); 438 439 // Done submitting commands, unlock pool. 440 vk_cmd_pool_unlock(&w->pool); ··· 456 .pResults = NULL, 457 }; 458 459 - os_mutex_lock(&vk->queue_mutex); 460 - ret = vk->vkQueuePresentKHR(vk->main_queue.queue, &present); 461 - os_mutex_unlock(&vk->queue_mutex); 462 463 if (ret != VK_SUCCESS) { 464 VK_ERROR(vk, "Error: could not present to queue.\n");
··· 266 267 struct vk_bundle *vk = get_vk(w); 268 269 + vk_queue_lock(vk->main_queue); 270 vk->vkDeviceWaitIdle(vk->device); 271 + vk_queue_unlock(vk->main_queue); 272 273 vk_cmd_pool_lock(&w->pool); 274 vk->vkFreeCommandBuffers(vk->device, w->pool.pool, 1, &w->cmd); ··· 434 }; 435 436 // Done writing commands, submit to queue. 437 + ret = vk_cmd_submit_locked(vk, vk->main_queue, 1, &submit, VK_NULL_HANDLE); 438 439 // Done submitting commands, unlock pool. 440 vk_cmd_pool_unlock(&w->pool); ··· 456 .pResults = NULL, 457 }; 458 459 + vk_queue_lock(vk->main_queue); 460 + ret = vk->vkQueuePresentKHR(vk->main_queue->queue, &present); 461 + vk_queue_unlock(vk->main_queue); 462 463 if (ret != VK_SUCCESS) { 464 VK_ERROR(vk, "Error: could not present to queue.\n");
+2 -2
src/xrt/compositor/render/render_resources.c
··· 595 VkCommandPoolCreateInfo command_pool_info = { 596 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 597 .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 598 - .queueFamilyIndex = vk->main_queue.family_index, 599 }; 600 601 ret = vk->vkCreateCommandPool(vk->device, &command_pool_info, NULL, &r->cmd_pool); ··· 657 r->mock.color.image); // dst 658 VK_CHK_WITH_RET(ret, "prepare_mock_image_locked", false); 659 660 - ret = vk_cmd_end_submit_wait_and_free_cmd_buffer_locked(vk, &vk->main_queue, r->cmd_pool, cmd); 661 VK_CHK_WITH_RET(ret, "vk_cmd_end_submit_wait_and_free_cmd_buffer_locked", false); 662 663 // No need to wait, submit waits on the fence.
··· 595 VkCommandPoolCreateInfo command_pool_info = { 596 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 597 .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 598 + .queueFamilyIndex = vk->main_queue->family_index, 599 }; 600 601 ret = vk->vkCreateCommandPool(vk->device, &command_pool_info, NULL, &r->cmd_pool); ··· 657 r->mock.color.image); // dst 658 VK_CHK_WITH_RET(ret, "prepare_mock_image_locked", false); 659 660 + ret = vk_cmd_end_submit_wait_and_free_cmd_buffer_locked(vk, vk->main_queue, r->cmd_pool, cmd); 661 VK_CHK_WITH_RET(ret, "vk_cmd_end_submit_wait_and_free_cmd_buffer_locked", false); 662 663 // No need to wait, submit waits on the fence.
+2 -2
src/xrt/compositor/util/comp_swapchain.c
··· 283 * validation doesn't complain. This is done during image destruction so 284 * isn't time critical. 285 */ 286 - os_mutex_lock(&vk->queue_mutex); 287 vk->vkDeviceWaitIdle(vk->device); 288 - os_mutex_unlock(&vk->queue_mutex); 289 290 // The field array_size is shared, only reset once both are freed. 291 image_view_array_cleanup(vk, image->array_size, &image->views.alpha);
··· 283 * validation doesn't complain. This is done during image destruction so 284 * isn't time critical. 285 */ 286 + vk_queue_lock(vk->main_queue); 287 vk->vkDeviceWaitIdle(vk->device); 288 + vk_queue_unlock(vk->main_queue); 289 290 // The field array_size is shared, only reset once both are freed. 291 image_view_array_cleanup(vk, image->array_size, &image->views.alpha);
+2 -2
tests/tests_comp_client_vulkan.cpp
··· 152 vk->has_KHR_image_format_list, // image_format_list_enabled 153 false, // debug_utils_enabled 154 false, // renderdoc_enabled 155 - vk->main_queue.family_index, // 156 - vk->main_queue.index); 157 struct xrt_compositor *xc = &xcvk->base; 158 159 SECTION("CreateSwapchain calls native create")
··· 152 vk->has_KHR_image_format_list, // image_format_list_enabled 153 false, // debug_utils_enabled 154 false, // renderdoc_enabled 155 + vk->main_queue->family_index, // 156 + vk->main_queue->index); 157 struct xrt_compositor *xc = &xcvk->base; 158 159 SECTION("CreateSwapchain calls native create")