anv: only resort to sync fds internally with no syncobj support
We can rely on only one kind of synchronization object (drm-syncobj) when it is available. This reduces the number of file descriptors we use in our implementation. This will be required later for timeline semaphores implementation, at this point we won't ever want to use anything else but syncobjs. v2: Only use has_syncobj for semaphores (Jason) v3: Only has_syncobj in assert on semaphores in QueueSubmit (Jason) Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
@@ -1594,6 +1594,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
VkFence _fence)
|
VkFence _fence)
|
||||||
{
|
{
|
||||||
ANV_FROM_HANDLE(anv_fence, fence, _fence);
|
ANV_FROM_HANDLE(anv_fence, fence, _fence);
|
||||||
|
UNUSED struct anv_physical_device *pdevice = &device->instance->physicalDevice;
|
||||||
|
|
||||||
struct anv_execbuf execbuf;
|
struct anv_execbuf execbuf;
|
||||||
anv_execbuf_init(&execbuf);
|
anv_execbuf_init(&execbuf);
|
||||||
@@ -1608,6 +1609,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
|
|
||||||
switch (impl->type) {
|
switch (impl->type) {
|
||||||
case ANV_SEMAPHORE_TYPE_BO:
|
case ANV_SEMAPHORE_TYPE_BO:
|
||||||
|
assert(!pdevice->has_syncobj);
|
||||||
result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL,
|
result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL,
|
||||||
0, &device->alloc);
|
0, &device->alloc);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
@@ -1615,6 +1617,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ANV_SEMAPHORE_TYPE_SYNC_FILE:
|
case ANV_SEMAPHORE_TYPE_SYNC_FILE:
|
||||||
|
assert(!pdevice->has_syncobj);
|
||||||
if (in_fence == -1) {
|
if (in_fence == -1) {
|
||||||
in_fence = impl->fd;
|
in_fence = impl->fd;
|
||||||
} else {
|
} else {
|
||||||
@@ -1664,6 +1667,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
|
|
||||||
switch (impl->type) {
|
switch (impl->type) {
|
||||||
case ANV_SEMAPHORE_TYPE_BO:
|
case ANV_SEMAPHORE_TYPE_BO:
|
||||||
|
assert(!pdevice->has_syncobj);
|
||||||
result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL,
|
result = anv_execbuf_add_bo(&execbuf, impl->bo, NULL,
|
||||||
EXEC_OBJECT_WRITE, &device->alloc);
|
EXEC_OBJECT_WRITE, &device->alloc);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
@@ -1671,6 +1675,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ANV_SEMAPHORE_TYPE_SYNC_FILE:
|
case ANV_SEMAPHORE_TYPE_SYNC_FILE:
|
||||||
|
assert(!pdevice->has_syncobj);
|
||||||
need_out_fence = true;
|
need_out_fence = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1705,6 +1710,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
|
|
||||||
switch (impl->type) {
|
switch (impl->type) {
|
||||||
case ANV_FENCE_TYPE_BO:
|
case ANV_FENCE_TYPE_BO:
|
||||||
|
assert(!pdevice->has_syncobj_wait);
|
||||||
result = anv_execbuf_add_bo(&execbuf, &impl->bo.bo, NULL,
|
result = anv_execbuf_add_bo(&execbuf, &impl->bo.bo, NULL,
|
||||||
EXEC_OBJECT_WRITE, &device->alloc);
|
EXEC_OBJECT_WRITE, &device->alloc);
|
||||||
if (result != VK_SUCCESS)
|
if (result != VK_SUCCESS)
|
||||||
@@ -1778,6 +1784,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fence && fence->permanent.type == ANV_FENCE_TYPE_BO) {
|
if (fence && fence->permanent.type == ANV_FENCE_TYPE_BO) {
|
||||||
|
assert(!pdevice->has_syncobj_wait);
|
||||||
/* BO fences can't be shared, so they can't be temporary. */
|
/* BO fences can't be shared, so they can't be temporary. */
|
||||||
assert(fence->temporary.type == ANV_FENCE_TYPE_NONE);
|
assert(fence->temporary.type == ANV_FENCE_TYPE_NONE);
|
||||||
|
|
||||||
@@ -1795,6 +1802,7 @@ anv_cmd_buffer_execbuf(struct anv_device *device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == VK_SUCCESS && need_out_fence) {
|
if (result == VK_SUCCESS && need_out_fence) {
|
||||||
|
assert(!pdevice->has_syncobj_wait);
|
||||||
int out_fence = execbuf.execbuf.rsvd2 >> 32;
|
int out_fence = execbuf.execbuf.rsvd2 >> 32;
|
||||||
for (uint32_t i = 0; i < num_out_semaphores; i++) {
|
for (uint32_t i = 0; i < num_out_semaphores; i++) {
|
||||||
ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]);
|
ANV_FROM_HANDLE(anv_semaphore, semaphore, out_semaphores[i]);
|
||||||
|
@@ -967,9 +967,13 @@ VkResult anv_CreateSemaphore(
|
|||||||
}
|
}
|
||||||
} else if (handleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
|
} else if (handleTypes & VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT) {
|
||||||
assert(handleTypes == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
|
assert(handleTypes == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
|
||||||
|
if (device->instance->physicalDevice.has_syncobj) {
|
||||||
|
semaphore->permanent.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ;
|
||||||
|
semaphore->permanent.syncobj = anv_gem_syncobj_create(device, 0);
|
||||||
|
} else {
|
||||||
semaphore->permanent.type = ANV_SEMAPHORE_TYPE_SYNC_FILE;
|
semaphore->permanent.type = ANV_SEMAPHORE_TYPE_SYNC_FILE;
|
||||||
semaphore->permanent.fd = -1;
|
semaphore->permanent.fd = -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(!"Unknown handle type");
|
assert(!"Unknown handle type");
|
||||||
vk_free2(&device->alloc, pAllocator, semaphore);
|
vk_free2(&device->alloc, pAllocator, semaphore);
|
||||||
@@ -1132,10 +1136,30 @@ VkResult anv_ImportSemaphoreFdKHR(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
|
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT:
|
||||||
|
if (device->instance->physicalDevice.has_syncobj) {
|
||||||
|
new_impl = (struct anv_semaphore_impl) {
|
||||||
|
.type = ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ,
|
||||||
|
.syncobj = anv_gem_syncobj_create(device, 0),
|
||||||
|
};
|
||||||
|
if (!new_impl.syncobj)
|
||||||
|
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||||
|
if (anv_gem_syncobj_import_sync_file(device, new_impl.syncobj, fd)) {
|
||||||
|
anv_gem_syncobj_destroy(device, new_impl.syncobj);
|
||||||
|
return vk_errorf(device->instance, NULL,
|
||||||
|
VK_ERROR_INVALID_EXTERNAL_HANDLE,
|
||||||
|
"syncobj sync file import failed: %m");
|
||||||
|
}
|
||||||
|
/* Ownership of the FD is transfered to Anv. Since we don't need it
|
||||||
|
* anymore because the associated fence has been put into a syncobj,
|
||||||
|
* we must close the FD.
|
||||||
|
*/
|
||||||
|
close(fd);
|
||||||
|
} else {
|
||||||
new_impl = (struct anv_semaphore_impl) {
|
new_impl = (struct anv_semaphore_impl) {
|
||||||
.type = ANV_SEMAPHORE_TYPE_SYNC_FILE,
|
.type = ANV_SEMAPHORE_TYPE_SYNC_FILE,
|
||||||
.fd = fd,
|
.fd = fd,
|
||||||
};
|
};
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1205,7 +1229,12 @@ VkResult anv_GetSemaphoreFdKHR(
|
|||||||
return VK_SUCCESS;
|
return VK_SUCCESS;
|
||||||
|
|
||||||
case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ:
|
case ANV_SEMAPHORE_TYPE_DRM_SYNCOBJ:
|
||||||
|
if (pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT)
|
||||||
|
fd = anv_gem_syncobj_export_sync_file(device, impl->syncobj);
|
||||||
|
else {
|
||||||
|
assert(pGetFdInfo->handleType == VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT);
|
||||||
fd = anv_gem_syncobj_handle_to_fd(device, impl->syncobj);
|
fd = anv_gem_syncobj_handle_to_fd(device, impl->syncobj);
|
||||||
|
}
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return vk_error(VK_ERROR_TOO_MANY_OBJECTS);
|
return vk_error(VK_ERROR_TOO_MANY_OBJECTS);
|
||||||
*pFd = fd;
|
*pFd = fd;
|
||||||
|
Reference in New Issue
Block a user