radv: Implement fences based on syncobjs.

Reviewed-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Bas Nieuwenhuizen
2017-11-27 23:58:35 +01:00
parent b308bb8773
commit 969421b7da
3 changed files with 109 additions and 15 deletions
+99 -14
View File
@@ -1850,12 +1850,14 @@ fail:
static VkResult radv_alloc_sem_counts(struct radv_winsys_sem_counts *counts,
int num_sems,
const VkSemaphore *sems,
VkFence _fence,
bool reset_temp)
{
int syncobj_idx = 0, sem_idx = 0;
if (num_sems == 0)
if (num_sems == 0 && _fence == VK_NULL_HANDLE)
return VK_SUCCESS;
for (uint32_t i = 0; i < num_sems; i++) {
RADV_FROM_HANDLE(radv_semaphore, sem, sems[i]);
@@ -1865,6 +1867,12 @@ static VkResult radv_alloc_sem_counts(struct radv_winsys_sem_counts *counts,
counts->sem_count++;
}
if (_fence != VK_NULL_HANDLE) {
RADV_FROM_HANDLE(radv_fence, fence, _fence);
if (fence->temp_syncobj || fence->syncobj)
counts->syncobj_count++;
}
if (counts->syncobj_count) {
counts->syncobj = (uint32_t *)malloc(sizeof(uint32_t) * counts->syncobj_count);
if (!counts->syncobj)
@@ -1893,6 +1901,14 @@ static VkResult radv_alloc_sem_counts(struct radv_winsys_sem_counts *counts,
}
}
if (_fence != VK_NULL_HANDLE) {
RADV_FROM_HANDLE(radv_fence, fence, _fence);
if (fence->temp_syncobj)
counts->syncobj[syncobj_idx++] = fence->temp_syncobj;
else if (fence->syncobj)
counts->syncobj[syncobj_idx++] = fence->syncobj;
}
return VK_SUCCESS;
}
@@ -1923,15 +1939,16 @@ VkResult radv_alloc_sem_info(struct radv_winsys_sem_info *sem_info,
int num_wait_sems,
const VkSemaphore *wait_sems,
int num_signal_sems,
const VkSemaphore *signal_sems)
const VkSemaphore *signal_sems,
VkFence fence)
{
VkResult ret;
memset(sem_info, 0, sizeof(*sem_info));
ret = radv_alloc_sem_counts(&sem_info->wait, num_wait_sems, wait_sems, true);
ret = radv_alloc_sem_counts(&sem_info->wait, num_wait_sems, wait_sems, VK_NULL_HANDLE, true);
if (ret)
return ret;
ret = radv_alloc_sem_counts(&sem_info->signal, num_signal_sems, signal_sems, false);
ret = radv_alloc_sem_counts(&sem_info->signal, num_signal_sems, signal_sems, fence, false);
if (ret)
radv_free_sem_info(sem_info);
@@ -1997,7 +2014,8 @@ VkResult radv_QueueSubmit(
pSubmits[i].waitSemaphoreCount,
pSubmits[i].pWaitSemaphores,
pSubmits[i].signalSemaphoreCount,
pSubmits[i].pSignalSemaphores);
pSubmits[i].pSignalSemaphores,
_fence);
if (result != VK_SUCCESS)
return result;
@@ -2068,11 +2086,18 @@ VkResult radv_QueueSubmit(
if (fence) {
if (!fence_emitted) {
struct radv_winsys_sem_info sem_info = {0};
struct radv_winsys_sem_info sem_info;
result = radv_alloc_sem_info(&sem_info, 0, NULL, 0, NULL,
_fence);
if (result != VK_SUCCESS)
return result;
ret = queue->device->ws->cs_submit(ctx, queue->queue_idx,
&queue->device->empty_cs[queue->queue_family_index],
1, NULL, NULL, &sem_info,
false, base_fence);
radv_free_sem_info(&sem_info);
}
fence->submitted = true;
}
@@ -2573,7 +2598,8 @@ radv_sparse_image_opaque_bind_memory(struct radv_device *device,
pBindInfo[i].waitSemaphoreCount,
pBindInfo[i].pWaitSemaphores,
pBindInfo[i].signalSemaphoreCount,
pBindInfo[i].pSignalSemaphores);
pBindInfo[i].pSignalSemaphores,
_fence);
if (result != VK_SUCCESS)
return result;
@@ -2606,6 +2632,11 @@ VkResult radv_CreateFence(
VkFence* pFence)
{
RADV_FROM_HANDLE(radv_device, device, _device);
const VkExportFenceCreateInfoKHR *export =
vk_find_struct_const(pCreateInfo->pNext, EXPORT_FENCE_CREATE_INFO_KHR);
VkExternalFenceHandleTypeFlagsKHR handleTypes =
export ? export->handleTypes : 0;
struct radv_fence *fence = vk_alloc2(&device->alloc, pAllocator,
sizeof(*fence), 8,
VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
@@ -2615,10 +2646,24 @@ VkResult radv_CreateFence(
fence->submitted = false;
fence->signalled = !!(pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT);
fence->fence = device->ws->create_fence();
if (!fence->fence) {
vk_free2(&device->alloc, pAllocator, fence);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
fence->temp_syncobj = 0;
if (handleTypes) {
int ret = device->ws->create_syncobj(device->ws, &fence->syncobj);
if (ret) {
vk_free2(&device->alloc, pAllocator, fence);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
if (pCreateInfo->flags & VK_FENCE_CREATE_SIGNALED_BIT) {
device->ws->signal_syncobj(device->ws, fence->syncobj);
}
fence->fence = NULL;
} else {
fence->fence = device->ws->create_fence();
if (!fence->fence) {
vk_free2(&device->alloc, pAllocator, fence);
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
}
fence->syncobj = 0;
}
*pFence = radv_fence_to_handle(fence);
@@ -2636,7 +2681,13 @@ void radv_DestroyFence(
if (!fence)
return;
device->ws->destroy_fence(fence->fence);
if (fence->temp_syncobj)
device->ws->destroy_syncobj(device->ws, fence->temp_syncobj);
if (fence->syncobj)
device->ws->destroy_syncobj(device->ws, fence->syncobj);
if (fence->fence)
device->ws->destroy_fence(fence->fence);
vk_free2(&device->alloc, pAllocator, fence);
}
@@ -2671,6 +2722,18 @@ VkResult radv_WaitForFences(
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
bool expired = false;
if (fence->temp_syncobj) {
if (!device->ws->wait_syncobj(device->ws, fence->temp_syncobj, timeout))
return VK_TIMEOUT;
continue;
}
if (fence->syncobj) {
if (!device->ws->wait_syncobj(device->ws, fence->syncobj, timeout))
return VK_TIMEOUT;
continue;
}
if (fence->signalled)
continue;
@@ -2687,13 +2750,26 @@ VkResult radv_WaitForFences(
return VK_SUCCESS;
}
VkResult radv_ResetFences(VkDevice device,
VkResult radv_ResetFences(VkDevice _device,
uint32_t fenceCount,
const VkFence *pFences)
{
RADV_FROM_HANDLE(radv_device, device, _device);
for (unsigned i = 0; i < fenceCount; ++i) {
RADV_FROM_HANDLE(radv_fence, fence, pFences[i]);
fence->submitted = fence->signalled = false;
/* Per spec, we first restore the permanent payload, and then reset, so
* having a temp syncobj should not skip resetting the permanent syncobj. */
if (fence->temp_syncobj) {
device->ws->destroy_syncobj(device->ws, fence->temp_syncobj);
fence->temp_syncobj = 0;
}
if (fence->syncobj) {
device->ws->reset_syncobj(device->ws, fence->syncobj);
}
}
return VK_SUCCESS;
@@ -2704,11 +2780,20 @@ VkResult radv_GetFenceStatus(VkDevice _device, VkFence _fence)
RADV_FROM_HANDLE(radv_device, device, _device);
RADV_FROM_HANDLE(radv_fence, fence, _fence);
if (fence->temp_syncobj) {
bool success = device->ws->wait_syncobj(device->ws, fence->temp_syncobj, 0);
return success ? VK_SUCCESS : VK_NOT_READY;
}
if (fence->syncobj) {
bool success = device->ws->wait_syncobj(device->ws, fence->syncobj, 0);
return success ? VK_SUCCESS : VK_NOT_READY;
}
if (fence->signalled)
return VK_SUCCESS;
if (!fence->submitted)
return VK_NOT_READY;
if (!device->ws->fence_wait(device->ws, fence->fence, false, 0))
return VK_NOT_READY;
+5 -1
View File
@@ -1558,7 +1558,8 @@ VkResult radv_alloc_sem_info(struct radv_winsys_sem_info *sem_info,
int num_wait_sems,
const VkSemaphore *wait_sems,
int num_signal_sems,
const VkSemaphore *signal_sems);
const VkSemaphore *signal_sems,
VkFence fence);
void radv_free_sem_info(struct radv_winsys_sem_info *sem_info);
void radv_set_descriptor_set(struct radv_cmd_buffer *cmd_buffer,
@@ -1597,6 +1598,9 @@ struct radv_fence {
struct radeon_winsys_fence *fence;
bool submitted;
bool signalled;
uint32_t syncobj;
uint32_t temp_syncobj;
};
struct radeon_winsys_sem;
+5
View File
@@ -214,6 +214,11 @@ VkResult radv_AcquireNextImageKHR(
if (fence && (result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR)) {
fence->submitted = true;
fence->signalled = true;
if (fence->temp_syncobj) {
device->ws->signal_syncobj(device->ws, fence->temp_syncobj);
} else if (fence->syncobj) {
device->ws->signal_syncobj(device->ws, fence->syncobj);
}
}
return result;
}