mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
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@chromium.org> Reviewed-by: Chia-I Wu <olvaffe@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11342>
This commit is contained in:
parent
c7b405b39d
commit
04e28356b4
2 changed files with 61 additions and 28 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue