mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-24 21:50:12 +01:00
venus: re-implement sync_fd external fence
Instead of waiting for signal before importing, we are able to retain the imported sync file and handle the fence related commands on the driver side. 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
db9fa4be04
commit
4da0ac54cf
4 changed files with 43 additions and 14 deletions
|
|
@ -17,7 +17,6 @@
|
|||
#include <vulkan/vk_icd.h>
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
#include "util/libsync.h"
|
||||
#include "util/os_file.h"
|
||||
|
||||
#include "vn_buffer.h"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "util/bitscan.h"
|
||||
#include "util/bitset.h"
|
||||
#include "util/compiler.h"
|
||||
#include "util/libsync.h"
|
||||
#include "util/list.h"
|
||||
#include "util/macros.h"
|
||||
#include "util/os_time.h"
|
||||
|
|
|
|||
|
|
@ -513,9 +513,12 @@ vn_QueueWaitIdle(VkQueue _queue)
|
|||
/* fence commands */
|
||||
|
||||
static void
|
||||
vn_sync_payload_release(struct vn_device *dev,
|
||||
vn_sync_payload_release(UNUSED struct vn_device *dev,
|
||||
struct vn_sync_payload *payload)
|
||||
{
|
||||
if (payload->type == VN_SYNC_TYPE_IMPORTED_SYNC_FD && payload->fd >= 0)
|
||||
close(payload->fd);
|
||||
|
||||
payload->type = VN_SYNC_TYPE_INVALID;
|
||||
}
|
||||
|
||||
|
|
@ -538,7 +541,8 @@ vn_fence_signal_wsi(struct vn_device *dev, struct vn_fence *fence)
|
|||
struct vn_sync_payload *temp = &fence->temporary;
|
||||
|
||||
vn_sync_payload_release(dev, temp);
|
||||
temp->type = VN_SYNC_TYPE_WSI_SIGNALED;
|
||||
temp->type = VN_SYNC_TYPE_IMPORTED_SYNC_FD;
|
||||
temp->fd = -1;
|
||||
fence->payload = temp;
|
||||
}
|
||||
|
||||
|
|
@ -751,8 +755,11 @@ vn_GetFenceStatus(VkDevice device, VkFence _fence)
|
|||
result = vn_call_vkGetFenceStatus(dev->instance, device, _fence);
|
||||
}
|
||||
break;
|
||||
case VN_SYNC_TYPE_WSI_SIGNALED:
|
||||
result = VK_SUCCESS;
|
||||
case VN_SYNC_TYPE_IMPORTED_SYNC_FD:
|
||||
if (payload->fd < 0 || sync_wait(payload->fd, 0) == 0)
|
||||
result = VK_SUCCESS;
|
||||
else
|
||||
result = errno == ETIME ? VK_NOT_READY : VK_ERROR_DEVICE_LOST;
|
||||
break;
|
||||
default:
|
||||
unreachable("unexpected fence payload type");
|
||||
|
|
@ -884,6 +891,15 @@ vn_create_sync_file(struct vn_device *dev, int *out_fd)
|
|||
return *out_fd >= 0 ? VK_SUCCESS : VK_ERROR_TOO_MANY_OBJECTS;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
vn_sync_valid_fd(int fd)
|
||||
{
|
||||
/* the special value -1 for fd is treated like a valid sync file descriptor
|
||||
* referring to an object that has already signaled
|
||||
*/
|
||||
return (fd >= 0 && sync_valid_fd(fd)) || fd == -1;
|
||||
}
|
||||
|
||||
VkResult
|
||||
vn_ImportFenceFdKHR(VkDevice device,
|
||||
const VkImportFenceFdInfoKHR *pImportFenceFdInfo)
|
||||
|
|
@ -897,15 +913,15 @@ vn_ImportFenceFdKHR(VkDevice device,
|
|||
|
||||
assert(dev->instance->experimental.globalFencing);
|
||||
assert(sync_file);
|
||||
if (fd >= 0) {
|
||||
if (sync_wait(fd, -1))
|
||||
return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
if (!vn_sync_valid_fd(fd))
|
||||
return vn_error(dev->instance, VK_ERROR_INVALID_EXTERNAL_HANDLE);
|
||||
|
||||
/* abuse VN_SYNC_TYPE_WSI_SIGNALED */
|
||||
vn_fence_signal_wsi(dev, fence);
|
||||
struct vn_sync_payload *temp = &fence->temporary;
|
||||
vn_sync_payload_release(dev, temp);
|
||||
temp->type = VN_SYNC_TYPE_IMPORTED_SYNC_FD;
|
||||
temp->fd = fd;
|
||||
fence->payload = temp;
|
||||
|
||||
return VK_SUCCESS;
|
||||
}
|
||||
|
|
@ -941,12 +957,19 @@ vn_GetFenceFdKHR(VkDevice device,
|
|||
vn_sync_payload_release(dev, &fence->temporary);
|
||||
fence->payload = &fence->permanent;
|
||||
} else {
|
||||
assert(payload->type == VN_SYNC_TYPE_WSI_SIGNALED);
|
||||
assert(payload->type == VN_SYNC_TYPE_IMPORTED_SYNC_FD);
|
||||
|
||||
/* transfer ownership of imported sync fd to save a dup */
|
||||
fd = payload->fd;
|
||||
payload->fd = -1;
|
||||
|
||||
/* reset host fence in case in signaled state before import */
|
||||
result = vn_ResetFences(device, 1, &pGetFdInfo->fence);
|
||||
if (result != VK_SUCCESS)
|
||||
if (result != VK_SUCCESS) {
|
||||
/* transfer sync fd ownership back on error */
|
||||
payload->fd = fd;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
*pFd = fd;
|
||||
|
|
|
|||
|
|
@ -40,10 +40,16 @@ enum vn_sync_type {
|
|||
|
||||
/* already signaled by WSI */
|
||||
VN_SYNC_TYPE_WSI_SIGNALED,
|
||||
|
||||
/* payload is an imported sync file */
|
||||
VN_SYNC_TYPE_IMPORTED_SYNC_FD,
|
||||
};
|
||||
|
||||
struct vn_sync_payload {
|
||||
enum vn_sync_type type;
|
||||
|
||||
/* If type is VN_SYNC_TYPE_IMPORTED_SYNC_FD, fd is a sync file. */
|
||||
int fd;
|
||||
};
|
||||
|
||||
struct vn_fence {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue