summaryrefslogtreecommitdiff
path: root/kms++/src/dmabufframebuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kms++/src/dmabufframebuffer.cpp')
-rw-r--r--kms++/src/dmabufframebuffer.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/kms++/src/dmabufframebuffer.cpp b/kms++/src/dmabufframebuffer.cpp
index cdf7a74..00ab94e 100644
--- a/kms++/src/dmabufframebuffer.cpp
+++ b/kms++/src/dmabufframebuffer.cpp
@@ -4,8 +4,10 @@
#include <stdexcept>
#include <sys/mman.h>
+#include <sys/ioctl.h>
#include <xf86drm.h>
#include <xf86drmMode.h>
+#include <linux/dma-buf.h>
#include <kms++/kms++.h>
@@ -78,4 +80,50 @@ int DmabufFramebuffer::prime_fd(unsigned plane)
return p.prime_fd;
}
+void DmabufFramebuffer::begin_cpu_access(CpuAccess access)
+{
+ if (m_sync_flags != 0)
+ throw runtime_error("begin_cpu sync already started");
+
+ switch (access) {
+ case CpuAccess::Read:
+ m_sync_flags = DMA_BUF_SYNC_READ;
+ break;
+ case CpuAccess::Write:
+ m_sync_flags = DMA_BUF_SYNC_WRITE;
+ break;
+ case CpuAccess::ReadWrite:
+ m_sync_flags = DMA_BUF_SYNC_RW;
+ break;
+ }
+
+ dma_buf_sync dbs {
+ .flags = DMA_BUF_SYNC_START | m_sync_flags
+ };
+
+ for (uint32_t p = 0; p < m_num_planes; ++p) {
+ int r = ioctl(prime_fd(p), DMA_BUF_IOCTL_SYNC, &dbs);
+ if (r)
+ throw runtime_error("DMA_BUF_IOCTL_SYNC failed");
+ }
+}
+
+void DmabufFramebuffer::end_cpu_access()
+{
+ if (m_sync_flags == 0)
+ throw runtime_error("begin_cpu sync not started");
+
+ dma_buf_sync dbs {
+ .flags = DMA_BUF_SYNC_END | m_sync_flags
+ };
+
+ for (uint32_t p = 0; p < m_num_planes; ++p) {
+ int r = ioctl(prime_fd(p), DMA_BUF_IOCTL_SYNC, &dbs);
+ if (r)
+ throw runtime_error("DMA_BUF_IOCTL_SYNC failed");
+ }
+
+ m_sync_flags = 0;
+}
+
}