mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 23:50:11 +01:00
venus: use a separate sync fence for Android wsi
Also refactors the codes a bit. Signed-off-by: Yiwei Zhang <zzyiwei@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17975>
This commit is contained in:
parent
5457f4c0a4
commit
d85d29b731
3 changed files with 48 additions and 13 deletions
|
|
@ -796,17 +796,38 @@ vn_AcquireImageANDROID(VkDevice device,
|
|||
return vn_result(dev->instance, result);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
vn_android_sync_fence_create(struct vn_queue *queue)
|
||||
{
|
||||
struct vn_device *dev = queue->device;
|
||||
|
||||
const VkExportFenceCreateInfo export_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
|
||||
.pNext = NULL,
|
||||
.handleTypes = VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
};
|
||||
const VkFenceCreateInfo create_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||
.pNext =
|
||||
dev->instance->experimental.globalFencing ? &export_info : NULL,
|
||||
.flags = 0,
|
||||
};
|
||||
return vn_CreateFence(vn_device_to_handle(dev), &create_info, NULL,
|
||||
&queue->sync_fence);
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_QueueSignalReleaseImageANDROID(VkQueue queue,
|
||||
vn_QueueSignalReleaseImageANDROID(VkQueue _queue,
|
||||
uint32_t waitSemaphoreCount,
|
||||
const VkSemaphore *pWaitSemaphores,
|
||||
VkImage image,
|
||||
int *pNativeFenceFd)
|
||||
{
|
||||
VN_TRACE_FUNC();
|
||||
struct vn_queue *que = vn_queue_from_handle(queue);
|
||||
struct vn_device *dev = que->device;
|
||||
struct vn_queue *queue = vn_queue_from_handle(_queue);
|
||||
struct vn_device *dev = queue->device;
|
||||
const VkAllocationCallbacks *alloc = &dev->base.base.alloc;
|
||||
const bool has_global_fencing = dev->instance->experimental.globalFencing;
|
||||
VkDevice device = vn_device_to_handle(dev);
|
||||
VkPipelineStageFlags local_stage_masks[8];
|
||||
VkPipelineStageFlags *stage_masks = local_stage_masks;
|
||||
|
|
@ -818,6 +839,13 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
|
|||
return VK_SUCCESS;
|
||||
}
|
||||
|
||||
/* lazily create sync fence for Android wsi */
|
||||
if (queue->sync_fence == VK_NULL_HANDLE) {
|
||||
result = vn_android_sync_fence_create(queue);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
}
|
||||
|
||||
if (waitSemaphoreCount > ARRAY_SIZE(local_stage_masks)) {
|
||||
stage_masks =
|
||||
vk_alloc(alloc, sizeof(*stage_masks) * waitSemaphoreCount,
|
||||
|
|
@ -844,10 +872,9 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
|
|||
* 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);
|
||||
result =
|
||||
vn_QueueSubmit(_queue, 1, &submit_info,
|
||||
has_global_fencing ? VK_NULL_HANDLE : queue->sync_fence);
|
||||
|
||||
if (stage_masks != local_stage_masks)
|
||||
vk_free(alloc, stage_masks);
|
||||
|
|
@ -855,7 +882,7 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
|
|||
if (result != VK_SUCCESS)
|
||||
return vn_error(dev->instance, result);
|
||||
|
||||
if (dev->instance->experimental.globalFencing == VK_TRUE) {
|
||||
if (has_global_fencing) {
|
||||
/* With globalFencing, the external queue fence was not passed in the
|
||||
* above vn_QueueSubmit to hint it to be synchronous. So we need to wait
|
||||
* for the ring here before vn_GetFenceFdKHR which is pure kernel ops.
|
||||
|
|
@ -867,17 +894,17 @@ vn_QueueSignalReleaseImageANDROID(VkQueue queue,
|
|||
const VkFenceGetFdInfoKHR fd_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR,
|
||||
.pNext = NULL,
|
||||
.fence = que->wait_fence,
|
||||
.fence = queue->sync_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);
|
||||
vn_WaitForFences(device, 1, &queue->sync_fence, VK_TRUE, UINT64_MAX);
|
||||
if (result != VK_SUCCESS)
|
||||
return vn_error(dev->instance, result);
|
||||
|
||||
result = vn_ResetFences(device, 1, &que->wait_fence);
|
||||
result = vn_ResetFences(device, 1, &queue->sync_fence);
|
||||
}
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
|
|
|
|||
|
|
@ -22,9 +22,13 @@
|
|||
static void
|
||||
vn_queue_fini(struct vn_queue *queue)
|
||||
{
|
||||
VkDevice dev_handle = vn_device_to_handle(queue->device);
|
||||
|
||||
if (queue->wait_fence != VK_NULL_HANDLE) {
|
||||
vn_DestroyFence(vn_device_to_handle(queue->device), queue->wait_fence,
|
||||
NULL);
|
||||
vn_DestroyFence(dev_handle, queue->wait_fence, NULL);
|
||||
}
|
||||
if (queue->sync_fence != VK_NULL_HANDLE) {
|
||||
vn_DestroyFence(dev_handle, queue->sync_fence, NULL);
|
||||
}
|
||||
vn_object_base_fini(&queue->base);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,11 @@ struct vn_queue {
|
|||
uint32_t index;
|
||||
uint32_t flags;
|
||||
|
||||
/* wait fence used for vn_QueueWaitIdle */
|
||||
VkFence wait_fence;
|
||||
|
||||
/* sync fence used for Android wsi */
|
||||
VkFence sync_fence;
|
||||
};
|
||||
VK_DEFINE_HANDLE_CASTS(vn_queue, base.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue