summaryrefslogtreecommitdiff
path: root/src/syncobject.hpp
diff options
context:
space:
mode:
authorPancakeTAS <pancake@mgnet.work>2026-05-18 15:51:33 +0200
committerPancakeTAS <pancake@mgnet.work>2026-05-18 15:51:33 +0200
commit9d2e04c95285825a196205163eebd945a362fb5e (patch)
tree59fdd2cfad0d3d548e54b54740806d7604218b89 /src/syncobject.hpp
parentExtend sync objects with timeline support (diff)
Split public/private API into respective locations
Diffstat (limited to '')
-rw-r--r--src/syncobject.hpp225
1 files changed, 0 insertions, 225 deletions
diff --git a/src/syncobject.hpp b/src/syncobject.hpp
deleted file mode 100644
index 6221753..0000000
--- a/src/syncobject.hpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-
-#pragma once
-
-#include <cstdint>
-#include <optional>
-#include <vector>
-
-namespace drm {
-
- ///
- /// A DRM synchronization object is a container which can hold one DRM fence.
- ///
- /// Their primary use-case is to implement Vulkan fences & semaphores, however they can
- /// be used across ordinary processes as well.
- ///
- /// A sync object is reference counted, therefore destroying a sync object does not
- /// invalidate all exported opaque file descriptors.
- ///
- /// Ordinary use cases for sync objects include:
- /// - Creating two sync objects in separate processes, exporting a sync object fd into
- /// the other process. Then signaling/polling the shared sync object.
- /// - Exporting a Vulkan fence/semaphore as a sync file and importing it into a sync object.
- /// It is then possible to wait for a signal from Vulkan inside of the DRM subsystem.
- ///
- /// Timeline synchronization objects extend the single DRM fence to a list of fences, where
- /// fences are identified via 64-bit unsigned integer.
- ///
- /// https://www.kernel.org/doc/html/v6.19/gpu/drm-mm.html#drm-sync-objects
- ///
- class SyncObject {
- public:
- ///
- /// Create a new DRM sync object
- ///
- /// By default, the sync object will not have a DRM fence emplaced.
- ///
- /// @param fd DRM node file descriptor
- /// @param signal Emplace a signaled fence on creation
- /// @throws drm::ioctl::Exception on failure
- ///
- SyncObject(int fd, bool signal = false);
-
- ///
- /// Import a DRM sync object from a file descriptor
- ///
- /// @param fd DRM node file descriptor
- /// @param syncobj_fd Sync object file descriptor
- /// @param close Close the file descriptor after import (regardless of success)
- /// @throws drm::ioctl::Exception on failure
- ///
- SyncObject(int fd, int syncobj_fd, bool close = true);
-
- ///
- /// Export a reference to the sync object
- ///
- /// @throws drm::ioctl::Exception on failure
- /// @returns Exported file descriptor.
- ///
- [[nodiscard]] int exportFd() const;
-
- ///
- /// Import a sync file (DRM fence) into the sync object
- ///
- /// @param syncfile_fd File descriptor to import
- /// @param point Timeline point to export for timeline sync objects
- /// @param close Close the file descriptor after import (regardless of success)
- /// @throws drm::ioctl::Exception on failure
- ///
- void importSyncFile(int syncfile_fd, uint64_t point = 0, bool close = true) const;
-
- ///
- /// Export a sync file from the DRM fence within the sync object
- ///
- /// Any subsequent modifications to the sync object are not applied to
- /// the exported sync file.
- ///
- /// @param point Timeline point to export for timeline sync objects
- /// @throws drm::ioctl::Exception on failure
- /// @returns Exported file descriptor
- ///
- [[nodiscard]] int exportSyncFile(uint64_t point = 0) const;
-
- ///
- /// Register an eventfd to be signaled by a sync object
- ///
- /// @param eventfd_fd File descriptor to signal
- /// @param point Timeline point to signal for timeline sync objects
- /// @param waitAvailable Only wait for a fence to be available, as opposed to signaled.
- /// @throws drm::ioctl::Exception on failure
- ///
- void registerEventFd(int eventfd_fd, uint64_t point = 0, bool waitAvailable = false) const;
-
- ///
- /// Copy a DRM fence into another sync object
- ///
- /// @param dstObject Destination sync object handle
- /// @param srcPoint Timeline point to copy from
- /// @param dstPoint Timeline point to copy into
- /// @throws drm::ioctl::Exception on failure
- ///
- void transfer(uint32_t dstObject, uint64_t srcPoint = 0, uint64_t dstPoint = 0) const;
-
- ///
- /// Emplace signaled fences into a list of sync objects
- ///
- /// When not using timeline sync objects, pass an empty list of timeline points.
- ///
- /// @param fd DRM node file descriptor
- /// @param objects List of sync object handles
- /// @param points List of timeline points to signal for each sync object
- /// @throws drm::ioctl::Exception on failure
- /// @throws std::invalid_argument invalid points size
- ///
- static void signal(
- int fd,
- const std::vector<uint32_t>& objects,
- const std::vector<uint64_t>& points = {}
- );
-
- ///
- /// Remove the DRM fence from a list of sync objects
- ///
- /// @param fd DRM node file descriptor
- /// @param objects List of sync object handles
- /// @throws drm::ioctl::Exception on failure
- ///
- static void reset(int fd, const std::vector<uint32_t>& objects);
-
- ///
- /// Wait for a list of sync objects to be signaled
- ///
- /// When not using timeline sync objects, pass an empty list of timeline points.
- ///
- /// If waitEmpty or waitAvailable is not set, any empty sync object will result in
- /// an error.
- ///
- /// If waitAvailable is set, the function will return as soon as a fence is emplaced into
- /// all sync objects, as opposed to waiting for the fence to be signaled. This option
- /// should not be used together with waitEmpty.
- ///
- /// @param fd DRM node file descriptor
- /// @param objects List of sync object handles
- /// @param points List of timeline points to wait on for each sync object
- /// @param timeout Absolute timeout in nanoseconds, or zero for polling
- /// @param waitAll Wait for all sync objects, as opposed to a single one
- /// @param waitEmpty Wait for sync objects, which do not yet have a fence emplaced
- /// @param waitAvailable Only wait for a fence to be available, as opposed to signaled.
- /// @param deadlineHint Set a CLOCK_MONOTONIC deadline hint in nanoseconds on all fences
- /// @throws drm::ioctl::Exception on failure
- /// @throws std::invalid_argument invalid points size
- /// @return Handle which was signaled first, when waitAll is false.
- ///
- [[nodiscard]]
- static uint32_t wait(
- int fd,
- const std::vector<uint32_t>& objects,
- const std::vector<uint64_t>& points = {},
- int64_t timeout = 0,
- bool waitAll = false,
- bool waitEmpty = false,
- bool waitAvailable = false,
- std::optional<uint64_t> deadlineHint = std::nullopt
- );
-
- ///
- /// Query the timeline points of a list of sync objects
- ///
- /// This should only be used with timeline sync objects.
- ///
- /// @param fd DRM node file descriptor
- /// @param objects List of sync object handles
- /// @param lastSubmitted Query the last submitted instead of signaled point.
- /// @throws drm::ioctl::Exception on failure
- /// @returns List of timeline points
- ///
- [[nodiscard]]
- static std::vector<uint64_t> query(
- int fd,
- const std::vector<uint32_t>& objects,
- bool lastSubmitted = false
- );
-
- // Into handle
- operator uint32_t() const { return this->m_handle; }
-
- // Move constructor/operator
- SyncObject(SyncObject&& other) noexcept : m_fd(other.m_fd), m_handle(other.m_handle) {
- other.m_fd = -1; // invalidate other
- }
-
- SyncObject& operator=(SyncObject&& other) noexcept {
- if (this != &other) {
- this->destruct();
- m_handle = other.m_handle;
- m_fd = other.m_fd;
- other.m_fd = -1; // invalidate other
- }
-
- return *this;
- }
-
- // Copy constructor/operator
- SyncObject(const SyncObject& other)
- : SyncObject(other.m_fd, other.exportFd(), true) {}
-
- SyncObject& operator=(const SyncObject& other) {
- if (this != &other) {
- const int fd = other.exportFd();
- *this = SyncObject(other.m_fd, fd, true);
- }
-
- return *this;
- }
-
- // Destructor
- ~SyncObject();
- private:
- int m_fd; // indicates object validity (>= 0)
- uint32_t m_handle;
-
- void destruct() noexcept;
- };
-
-}