Mesa (main): venus: moves GPU rendering off CPU timeline for Android WSI
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Jun 15 20:00:09 UTC 2021
Module: Mesa
Branch: main
Commit: 04e28356b4ca20d72453aaa35545e2d7407753c9
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=04e28356b4ca20d72453aaa35545e2d7407753c9
Author: Yiwei Zhang <zzyiwei at chromium.org>
Date: Tue Jun 15 07:00:09 2021 +0000
venus: moves GPU rendering off CPU timeline for Android WSI
When globalFencing is supported, we can export a native sync fd for
presentation to move rendering off CPU timeline.
Signed-off-by: Yiwei Zhang <zzyiwei at chromium.org>
Reviewed-by: Chia-I Wu <olvaffe at gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11342>
---
src/virtio/vulkan/vn_android.c | 69 ++++++++++++++++++++++++++++--------------
src/virtio/vulkan/vn_device.c | 20 ++++++++----
2 files changed, 61 insertions(+), 28 deletions(-)
diff --git a/src/virtio/vulkan/vn_android.c b/src/virtio/vulkan/vn_android.c
index aa59b5dcd5b..61eac3a55e7 100644
--- a/src/virtio/vulkan/vn_android.c
+++ b/src/virtio/vulkan/vn_android.c
@@ -629,28 +629,26 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
VkImage image,
int *pNativeFenceFd)
{
- /* At this moment, the wait semaphores are converted to a VkFence via an
- * empty submit. The VkFence is then waited inside until signaled, and the
- * out native fence fd is set to -1.
- */
- VkResult result = VK_SUCCESS;
struct vn_queue *que = vn_queue_from_handle(queue);
- const VkAllocationCallbacks *alloc = &que->device->base.base.alloc;
- VkDevice device = vn_device_to_handle(que->device);
+ struct vn_device *dev = que->device;
+ const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
+ VkDevice device = vn_device_to_handle(dev);
VkPipelineStageFlags local_stage_masks[8];
VkPipelineStageFlags *stage_masks = local_stage_masks;
+ VkResult result = VK_SUCCESS;
+ int fd = -1;
- if (waitSemaphoreCount == 0)
- goto out;
+ if (waitSemaphoreCount == 0) {
+ *pNativeFenceFd = -1;
+ return VK_SUCCESS;
+ }
if (waitSemaphoreCount > ARRAY_SIZE(local_stage_masks)) {
stage_masks =
- vk_alloc(alloc, sizeof(VkPipelineStageFlags) * waitSemaphoreCount,
+ vk_alloc(alloc, sizeof(*stage_masks) * waitSemaphoreCount,
VN_DEFAULT_ALIGN, VK_SYSTEM_ALLOCATION_SCOPE_COMMAND);
- if (!stage_masks) {
- result = VK_ERROR_OUT_OF_HOST_MEMORY;
- goto out;
- }
+ if (!stage_masks)
+ return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
}
for (uint32_t i = 0; i < waitSemaphoreCount; i++)
@@ -667,17 +665,44 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
.signalSemaphoreCount = 0,
.pSignalSemaphores = NULL,
};
- result = vn_QueueSubmit(queue, 1, &submit_info, que->wait_fence);
+ /* XXX When globalFencing is supported, our implementation is not able to
+ * reset the fence during vn_GetFenceFdKHR currently. Thus to ensure proper
+ * host driver behavior, we pass VK_NULL_HANDLE here.
+ */
+ result = vn_QueueSubmit(
+ queue, 1, &submit_info,
+ dev->instance->experimental.globalFencing == VK_TRUE ? VK_NULL_HANDLE
+ : que->wait_fence);
+
+ if (stage_masks != local_stage_masks)
+ vk_free(alloc, stage_masks);
+
if (result != VK_SUCCESS)
- goto out;
+ return vn_error(dev->instance, result);
- result =
- vn_WaitForFences(device, 1, &que->wait_fence, VK_TRUE, UINT64_MAX);
- vn_ResetFences(device, 1, &que->wait_fence);
+ if (dev->instance->experimental.globalFencing == VK_TRUE) {
+ const VkFenceGetFdInfoKHR fd_info = {
+ .sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
+ .pNext = NULL,
+ .fence = que->wait_fence,
+ .handleType = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
+ };
+ result = vn_GetFenceFdKHR(device, &fd_info, &fd);
+ } else {
+ result =
+ vn_WaitForFences(device, 1, &que->wait_fence, VK_TRUE, UINT64_MAX);
+ if (result != VK_SUCCESS)
+ return vn_error(dev->instance, result);
-out:
- *pNativeFenceFd = -1;
- return result;
+ result = vn_ResetFences(device, 1, &que->wait_fence);
+ }
+
+ if (result != VK_SUCCESS)
+ return vn_error(dev->instance, result);
+
+ *pNativeFenceFd = fd;
+
+ return VK_SUCCESS;
}
static VkResult
diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c
index ea8a52bf1a2..58951d2983d 100644
--- a/src/virtio/vulkan/vn_device.c
+++ b/src/virtio/vulkan/vn_device.c
@@ -3102,12 +3102,20 @@ vn_queue_init(struct vn_device *dev,
queue->index = queue_index;
queue->flags = queue_info->flags;
- VkResult result =
- vn_CreateFence(vn_device_to_handle(dev),
- &(const VkFenceCreateInfo){
- .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
- },
- NULL, &queue->wait_fence);
+ const VkExportFenceCreateInfo export_fence_info = {
+ .sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
+ .pNext = NULL,
+ .handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
+ };
+ const VkFenceCreateInfo fence_info = {
+ .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
+ .pNext = dev->instance->experimental.globalFencing == VK_TRUE
+ ? &export_fence_info
+ : NULL,
+ .flags = 0,
+ };
+ VkResult result = vn_CreateFence(vn_device_to_handle(dev), &fence_info,
+ NULL, &queue->wait_fence);
if (result != VK_SUCCESS)
return result;
More information about the mesa-commit
mailing list