turnip: rework ImportSemaphoreFdKHR

The behavior of OPAQUE_FD should be unchanged.

SYNC_FD case is reworked to be more like what anv does: a new temporary
syncobj is always created, with the CREATE_SIGNALED flag if necessary.

Signed-off-by: Jonathan Marek <jonathan@marek.ca>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6719>
This commit is contained in:
Jonathan Marek
2020-09-28 23:01:38 -04:00
committed by Marge Bot
parent 8343c32f5a
commit c4d5010c54

View File

@@ -487,56 +487,66 @@ tu_DestroySemaphore(VkDevice _device,
VkResult
tu_ImportSemaphoreFdKHR(VkDevice _device,
const VkImportSemaphoreFdInfoKHR *pImportSemaphoreFdInfo)
const VkImportSemaphoreFdInfoKHR *info)
{
TU_FROM_HANDLE(tu_device, device, _device);
TU_FROM_HANDLE(tu_semaphore, sem, pImportSemaphoreFdInfo->semaphore);
TU_FROM_HANDLE(tu_semaphore, sem, info->semaphore);
int ret;
uint32_t *dst = NULL;
if (pImportSemaphoreFdInfo->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT) {
dst = &sem->temporary;
} else {
dst = &sem->permanent;
}
uint32_t syncobj = *dst;
switch(pImportSemaphoreFdInfo->handleType) {
switch(info->handleType) {
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT: {
uint32_t old_syncobj = syncobj;
ret = drmSyncobjFDToHandle(device->fd, pImportSemaphoreFdInfo->fd, &syncobj);
if (ret == 0) {
close(pImportSemaphoreFdInfo->fd);
if (old_syncobj)
drmSyncobjDestroy(device->fd, old_syncobj);
uint32_t *dst;
if (info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT)
dst = &sem->temporary;
else
dst = &sem->permanent;
struct drm_syncobj_handle handle = { .fd = info->fd };
ret = ioctl(device->fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &handle);
if (ret)
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
if (*dst) {
ioctl(device->fd, DRM_IOCTL_SYNCOBJ_DESTROY,
&(struct drm_syncobj_destroy) { .handle = *dst });
}
*dst = handle.handle;
close(info->fd);
break;
}
case VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT: {
if (!syncobj) {
ret = drmSyncobjCreate(device->fd, 0, &syncobj);
if (ret)
break;
assert(info->flags & VK_SEMAPHORE_IMPORT_TEMPORARY_BIT);
struct drm_syncobj_create create = {};
if (info->fd == -1)
create.flags |= DRM_SYNCOBJ_CREATE_SIGNALED;
ret = ioctl(device->fd, DRM_IOCTL_SYNCOBJ_CREATE, &create);
if (ret)
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
if (info->fd != -1) {
ret = ioctl(device->fd, DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE, &(struct drm_syncobj_handle) {
.fd = info->fd,
.handle = create.handle,
.flags = DRM_SYNCOBJ_FD_TO_HANDLE_FLAGS_IMPORT_SYNC_FILE,
});
if (ret) {
ioctl(device->fd, DRM_IOCTL_SYNCOBJ_DESTROY,
&(struct drm_syncobj_destroy) { .handle = create.handle });
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
close(info->fd);
}
if (pImportSemaphoreFdInfo->fd == -1) {
ret = drmSyncobjSignal(device->fd, &syncobj, 1);
} else {
ret = drmSyncobjImportSyncFile(device->fd, syncobj, pImportSemaphoreFdInfo->fd);
}
if (!ret)
close(pImportSemaphoreFdInfo->fd);
semaphore_set_temporary(device, sem, create.handle);
break;
}
default:
unreachable("Unhandled semaphore handle type");
}
if (ret) {
return VK_ERROR_INVALID_EXTERNAL_HANDLE;
}
*dst = syncobj;
return VK_SUCCESS;
}