diff --git a/include/render/dmabuf.h b/include/render/dmabuf.h index 4e82a99f..3d905ce9 100644 --- a/include/render/dmabuf.h +++ b/include/render/dmabuf.h @@ -23,4 +23,13 @@ bool dmabuf_check_sync_file_import_export(void); */ bool dmabuf_import_sync_file(int dmabuf_fd, uint32_t flags, int sync_file_fd); +/** + * Export a sync_file from a DMA-BUF with DMA_BUF_IOCTL_EXPORT_SYNC_FILE. + * + * The sync_file FD is returned on success, -1 is returned on error. + * + * This can be used to make explicit sync interoperate with implicit sync. + */ +int dmabuf_export_sync_file(int dmabuf_fd, uint32_t flags); + #endif diff --git a/render/dmabuf_fallback.c b/render/dmabuf_fallback.c index 8cd31384..820d46d5 100644 --- a/render/dmabuf_fallback.c +++ b/render/dmabuf_fallback.c @@ -10,3 +10,8 @@ bool dmabuf_import_sync_file(int dmabuf_fd, uint32_t flags, int sync_file_fd) { wlr_log(WLR_ERROR, "DMA-BUF sync_file import IOCTL not available on this system"); return false; } + +int dmabuf_export_sync_file(int dmabuf_fd, uint32_t flags) { + wlr_log(WLR_ERROR, "DMA-BUF sync_file export IOCTL not available on this system"); + return false; +} diff --git a/render/dmabuf_linux.c b/render/dmabuf_linux.c index a6bf1d42..cf06229c 100644 --- a/render/dmabuf_linux.c +++ b/render/dmabuf_linux.c @@ -51,6 +51,7 @@ bool dmabuf_check_sync_file_import_export(void) { } // TODO: drop these definitions once widespread + #if !defined(DMA_BUF_IOCTL_IMPORT_SYNC_FILE) struct dma_buf_import_sync_file { @@ -62,6 +63,17 @@ struct dma_buf_import_sync_file { #endif +#if !defined(DMA_BUF_IOCTL_EXPORT_SYNC_FILE) + +struct dma_buf_export_sync_file { + __u32 flags; + __s32 fd; +}; + +#define DMA_BUF_IOCTL_EXPORT_SYNC_FILE _IOWR(DMA_BUF_BASE, 2, struct dma_buf_export_sync_file) + +#endif + bool dmabuf_import_sync_file(int dmabuf_fd, uint32_t flags, int sync_file_fd) { struct dma_buf_import_sync_file data = { .flags = flags, @@ -73,3 +85,15 @@ bool dmabuf_import_sync_file(int dmabuf_fd, uint32_t flags, int sync_file_fd) { } return true; } + +int dmabuf_export_sync_file(int dmabuf_fd, uint32_t flags) { + struct dma_buf_export_sync_file data = { + .flags = flags, + .fd = -1, + }; + if (drmIoctl(dmabuf_fd, DMA_BUF_IOCTL_EXPORT_SYNC_FILE, &data) != 0) { + wlr_log_errno(WLR_ERROR, "drmIoctl(EXPORT_SYNC_FILE) failed"); + return -1; + } + return data.fd; +}