diff --git a/src/vulkan/runtime/vk_android.c b/src/vulkan/runtime/vk_android.c index 2bf97760241..677e278404f 100644 --- a/src/vulkan/runtime/vk_android.c +++ b/src/vulkan/runtime/vk_android.c @@ -301,6 +301,24 @@ vk_common_AcquireImageANDROID(VkDevice _device, return result; } +static VkResult +vk_anb_semaphore_init_once(struct vk_queue *queue, struct vk_device *device) +{ + if (queue->anb_semaphore != VK_NULL_HANDLE) + return VK_SUCCESS; + + const VkExportSemaphoreCreateInfo export_info = { + .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO, + .handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, + }; + const VkSemaphoreCreateInfo create_info = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = &export_info, + }; + return device->dispatch_table.CreateSemaphore(vk_device_to_handle(device), + &create_info, NULL, + &queue->anb_semaphore); +} VKAPI_ATTR VkResult VKAPI_CALL vk_common_QueueSignalReleaseImageANDROID(VkQueue _queue, @@ -313,43 +331,32 @@ vk_common_QueueSignalReleaseImageANDROID(VkQueue _queue, struct vk_device *device = queue->base.device; VkResult result = VK_SUCCESS; - if (waitSemaphoreCount == 0) { - if (pNativeFenceFd) - *pNativeFenceFd = -1; - return VK_SUCCESS; - } + STACK_ARRAY(VkPipelineStageFlags, stage_flags, MAX2(1, waitSemaphoreCount)); + for (uint32_t i = 0; i < MAX2(1, waitSemaphoreCount); i++) + stage_flags[i] = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; - int fd = -1; + result = vk_anb_semaphore_init_once(queue, device); + if (result != VK_SUCCESS) + return result; - for (uint32_t i = 0; i < waitSemaphoreCount; ++i) { - const VkSemaphoreGetFdInfoKHR get_fd = { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, - .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, - .semaphore = pWaitSemaphores[i], - }; - int tmp_fd; - result = device->dispatch_table.GetSemaphoreFdKHR(vk_device_to_handle(device), - &get_fd, &tmp_fd); - if (result != VK_SUCCESS) { - if (fd >= 0) - close(fd); - return result; - } + const VkSubmitInfo submit_info = { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .waitSemaphoreCount = waitSemaphoreCount, + .pWaitSemaphores = pWaitSemaphores, + .pWaitDstStageMask = stage_flags, + .signalSemaphoreCount = 1, + .pSignalSemaphores = &queue->anb_semaphore, + }; + result = device->dispatch_table.QueueSubmit(_queue, 1, &submit_info, + VK_NULL_HANDLE); + if (result != VK_SUCCESS) + return result; - if (fd < 0) { - fd = tmp_fd; - } else if (tmp_fd >= 0) { - sync_accumulate("vulkan", &fd, tmp_fd); - close(tmp_fd); - } - } - - if (pNativeFenceFd) { - *pNativeFenceFd = fd; - } else if (fd >= 0) { - close(fd); - /* We still need to do the exports, to reset the semaphores, but - * otherwise we don't wait on them. */ - } - return VK_SUCCESS; + const VkSemaphoreGetFdInfoKHR get_fd = { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR, + .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, + .semaphore = queue->anb_semaphore, + }; + return device->dispatch_table.GetSemaphoreFdKHR(vk_device_to_handle(device), + &get_fd, pNativeFenceFd); } diff --git a/src/vulkan/runtime/vk_queue.c b/src/vulkan/runtime/vk_queue.c index a315c6f5431..9e38299ed05 100644 --- a/src/vulkan/runtime/vk_queue.c +++ b/src/vulkan/runtime/vk_queue.c @@ -1124,6 +1124,14 @@ vk_queue_finish(struct vk_queue *queue) vk_queue_submit_destroy(queue, submit); } +#ifdef ANDROID + if (queue->anb_semaphore != VK_NULL_HANDLE) { + struct vk_device *device = queue->base.device; + device->dispatch_table.DestroySemaphore(vk_device_to_handle(device), + queue->anb_semaphore, NULL); + } +#endif + cnd_destroy(&queue->submit.pop); cnd_destroy(&queue->submit.push); mtx_destroy(&queue->submit.mutex); diff --git a/src/vulkan/runtime/vk_queue.h b/src/vulkan/runtime/vk_queue.h index 0e2f34c3bd5..1308632bcc4 100644 --- a/src/vulkan/runtime/vk_queue.h +++ b/src/vulkan/runtime/vk_queue.h @@ -145,6 +145,24 @@ struct vk_queue { */ struct util_dynarray labels; bool region_begin; + +#ifdef ANDROID + /** SYNC_FD signal semaphore for vkQueueSignalReleaseImageANDROID + * + * VK_ANDROID_native_buffer enforces explicit fencing on the present api + * boundary. To avoid assuming all waitSemaphores exportable to sync file + * and to capture pending cmds in the queue, we do a simple submission and + * signal a SYNC_FD handle type external sempahore for native fence export. + * + * This plays the same role as wsi_swapchain::dma_buf_semaphore for WSI. + * The VK_ANDROID_native_buffer spec hides the swapchain object from the + * icd, so we have to cache the semaphore in common vk_queue. + * + * This also makes it easier to add additional cmds to prepare the wsi + * image for implementations requiring such (e.g. for layout transition). + */ + VkSemaphore anb_semaphore; +#endif }; VK_DEFINE_HANDLE_CASTS(vk_queue, base, VkQueue, VK_OBJECT_TYPE_QUEUE)