* [PATCH libdrm 1/2] Add drm mode lease ioctl wrappers [v3]
2017-08-02 10:03 [PATCH libdrm 0/2] Add leasing and 64-bit seq wrappers keithp
@ 2017-08-02 10:03 ` keithp
2017-08-02 10:04 ` [PATCH libdrm 2/2] Add CrtcGetSequence and CrtcQueueSequence IOCTLs keithp
1 sibling, 0 replies; 3+ messages in thread
From: keithp @ 2017-08-02 10:03 UTC (permalink / raw)
To: dri-devel; +Cc: airlied, keithp
From: Keith Packard <keithp@keithp.com>
drmModeCreateLease
drmModeListLessees
drmModeGetLease
drmModeRevokeLease
Changes for v2:
Remove lessee id from GetLease
Remove lessor_id from ListLeases
Add revoke
Renumber to track kernel rebase on drm-next
Signed-off-by: Keith Packard <keithp@keithp.com>
---
include/drm/drm.h | 4 +++
include/drm/drm_mode.h | 66 ++++++++++++++++++++++++++++++++++++
xf86drmMode.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++
xf86drmMode.h | 23 +++++++++++++
4 files changed, 184 insertions(+)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index bf3674ae..7c736765 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -829,6 +829,10 @@ extern "C" {
#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic)
#define DRM_IOCTL_MODE_CREATEPROPBLOB DRM_IOWR(0xBD, struct drm_mode_create_blob)
#define DRM_IOCTL_MODE_DESTROYPROPBLOB DRM_IOWR(0xBE, struct drm_mode_destroy_blob)
+#define DRM_IOCTL_MODE_CREATE_LEASE DRM_IOWR(0xC3, struct drm_mode_create_lease)
+#define DRM_IOCTL_MODE_LIST_LESSEES DRM_IOWR(0xC4, struct drm_mode_list_lessees)
+#define DRM_IOCTL_MODE_GET_LEASE DRM_IOWR(0xC5, struct drm_mode_get_lease)
+#define DRM_IOCTL_MODE_REVOKE_LEASE DRM_IOWR(0xC6, struct drm_mode_revoke_lease)
#define DRM_IOCTL_SYNCOBJ_CREATE DRM_IOWR(0xBF, struct drm_syncobj_create)
#define DRM_IOCTL_SYNCOBJ_DESTROY DRM_IOWR(0xC0, struct drm_syncobj_destroy)
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 70571af6..a2b71614 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -677,6 +677,72 @@ struct drm_mode_destroy_blob {
__u32 blob_id;
};
+/**
+ * Lease mode resources to another user.
+ */
+struct drm_mode_create_lease {
+ /** Pointer to array of object ids (__u32) */
+ __u64 object_ids;
+ /** Number of object ids */
+ __u32 object_count;
+ /** flags for new FD (O_CLOEXEC, etc) */
+ __u32 flags;
+
+ /** Return: unique identifier for lessee. */
+ __u32 lessee_id;
+ /** Return: file descriptor to new drm_master file */
+ __u32 fd;
+};
+
+/**
+ * List lesses from a drm_master
+ */
+struct drm_mode_list_lessees {
+ /** Number of lessees.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_lessees;
+ __u32 pad;
+
+ /** Pointer to lessees.
+ * pointer to __u64 array of lessee ids
+ */
+ __u64 lessees_ptr;
+};
+
+/**
+ * Get leased objects for a lessee
+ */
+struct drm_mode_get_lease {
+ /** Number of leased objects.
+ * On input, provides length of the array.
+ * On output, provides total number. No
+ * more than the input number will be written
+ * back, so two calls can be used to get
+ * the size and then the data.
+ */
+ __u32 count_objects;
+ __u32 pad;
+
+ /** Pointer to objects.
+ * pointer to __u32 array of object ids
+ */
+ __u64 objects_ptr;
+};
+
+/**
+ * Revoke lease
+ */
+struct drm_mode_revoke_lease {
+ /** Unique ID of lessee
+ */
+ __u32 lessee_id;
+};
+
#if defined(__cplusplus)
}
#endif
diff --git a/xf86drmMode.c b/xf86drmMode.c
index d3bc20ea..affd3fb7 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -1485,3 +1485,94 @@ drmModeDestroyPropertyBlob(int fd, uint32_t id)
destroy.blob_id = id;
return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
}
+
+int
+drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags, uint32_t *lessee_id)
+{
+ struct drm_mode_create_lease create;
+ int ret;
+
+ memclear(create);
+ create.object_ids = (uintptr_t) objects;
+ create.object_count = num_objects;
+ create.flags = flags;
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATE_LEASE, &create);
+ if (ret == 0) {
+ *lessee_id = create.lessee_id;
+ return create.fd;
+ }
+ return -errno;
+}
+
+drmModeLesseeListPtr
+drmModeListLessees(int fd)
+{
+ struct drm_mode_list_lessees list;
+ uint32_t count;
+ drmModeLesseeListPtr ret;
+
+ memclear(list);
+
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list))
+ return NULL;
+
+ count = list.count_lessees;
+ ret = drmMalloc(sizeof (drmModeLesseeListRes) + count * sizeof (ret->lessees[0]));
+ if (!ret)
+ return NULL;
+
+ list.lessees_ptr = VOID2U64(&ret->lessees[0]);
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list)) {
+ drmFree(ret);
+ return NULL;
+ }
+
+ ret->count = count;
+ return ret;
+}
+
+drmModeObjectListPtr
+drmModeGetLease(int fd)
+{
+ struct drm_mode_get_lease get;
+ uint32_t count;
+ drmModeObjectListPtr ret;
+
+ memclear(get);
+
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get))
+ return NULL;
+
+ count = get.count_objects;
+ ret = drmMalloc(sizeof (drmModeObjectListRes) + count * sizeof (ret->objects[0]));
+ if (!ret)
+ return NULL;
+
+ get.objects_ptr = VOID2U64(&ret->objects[0]);
+ if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get)) {
+ drmFree(ret);
+ return NULL;
+ }
+
+ ret->count = count;
+ return ret;
+}
+
+int
+drmModeRevokeLease(int fd, uint32_t lessee_id)
+{
+ struct drm_mode_revoke_lease revoke;
+ int ret;
+
+ memclear(revoke);
+
+ revoke.lessee_id = lessee_id;
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_REVOKE_LEASE, &revoke);
+ if (ret == 0)
+ return 0;
+ return -errno;
+}
+
+
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 5b390d9f..b5e22720 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -521,6 +521,29 @@ extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size,
extern int drmModeDestroyPropertyBlob(int fd, uint32_t id);
+/*
+ * DRM mode lease APIs. These create and manage new drm_masters with
+ * access to a subset of the available DRM resources
+ */
+
+extern int drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags, uint32_t *lessee_id);
+
+typedef struct drmModeLesseeList {
+ uint32_t count;
+ uint32_t lessees[0];
+} drmModeLesseeListRes, *drmModeLesseeListPtr;
+
+extern drmModeLesseeListPtr drmModeListLessees(int fd);
+
+typedef struct drmModeObjectList {
+ uint32_t count;
+ uint32_t objects[0];
+} drmModeObjectListRes, *drmModeObjectListPtr;
+
+extern drmModeObjectListPtr drmModeGetLease(int fd);
+
+extern int drmModeRevokeLease(int fd, uint32_t lessee_id);
+
#if defined(__cplusplus)
}
#endif
--
2.11.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH libdrm 2/2] Add CrtcGetSequence and CrtcQueueSequence IOCTLs
2017-08-02 10:03 [PATCH libdrm 0/2] Add leasing and 64-bit seq wrappers keithp
2017-08-02 10:03 ` [PATCH libdrm 1/2] Add drm mode lease ioctl wrappers [v3] keithp
@ 2017-08-02 10:04 ` keithp
1 sibling, 0 replies; 3+ messages in thread
From: keithp @ 2017-08-02 10:04 UTC (permalink / raw)
To: dri-devel; +Cc: airlied, keithp
From: Keith Packard <keithp@keithp.com>
These provide a crtc-id based interface to get the current sequence
(frame) number and to queue an event to be delivered at a specific sequence.
Signed-off-by: Keith Packard <keithp@keithp.com>
---
include/drm/drm.h | 32 ++++++++++++++++++++++++++++++++
xf86drm.c | 33 +++++++++++++++++++++++++++++++++
xf86drm.h | 11 ++++++++++-
xf86drmMode.c | 9 +++++++++
4 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 7c736765..076040d4 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -712,6 +712,27 @@ struct drm_syncobj_handle {
__u32 pad;
};
+/* Query current scanout sequence number */
+struct drm_crtc_get_sequence {
+ __u32 crtc_id;
+ __u32 active;
+ __u64 sequence;
+ __s64 sequence_ns;
+};
+
+/* Queue event to be delivered at specified sequence */
+
+#define DRM_CRTC_SEQUENCE_RELATIVE 0x00000001 /* sequence is relative to current */
+#define DRM_CRTC_SEQUENCE_NEXT_ON_MISS 0x00000002 /* Use next sequence if we've missed */
+#define DRM_CRTC_SEQUENCE_FIRST_PIXEL_OUT 0x00000004 /* Signal when first pixel is displayed */
+
+struct drm_crtc_queue_sequence {
+ __u32 crtc_id;
+ __u32 flags;
+ __u64 sequence; /* on input, target sequence. on output, actual sequence */
+ __u64 user_data; /* user data passed to event */
+};
+
#if defined(__cplusplus)
}
#endif
@@ -794,6 +815,9 @@ extern "C" {
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
+#define DRM_IOCTL_CRTC_GET_SEQUENCE DRM_IOWR(0x3b, struct drm_crtc_get_sequence)
+#define DRM_IOCTL_CRTC_QUEUE_SEQUENCE DRM_IOWR(0x3c, struct drm_crtc_queue_sequence)
+
#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
@@ -869,6 +893,7 @@ struct drm_event {
#define DRM_EVENT_VBLANK 0x01
#define DRM_EVENT_FLIP_COMPLETE 0x02
+#define DRM_EVENT_CRTC_SEQUENCE 0x03
struct drm_event_vblank {
struct drm_event base;
@@ -879,6 +904,13 @@ struct drm_event_vblank {
__u32 crtc_id; /* 0 on older kernels that do not support this */
};
+struct drm_event_crtc_sequence {
+ struct drm_event base;
+ __u64 user_data;
+ __s64 time_ns;
+ __u64 sequence;
+};
+
/* typedef area */
typedef struct drm_clip_rect drm_clip_rect_t;
typedef struct drm_drawable_info drm_drawable_info_t;
diff --git a/xf86drm.c b/xf86drm.c
index 6ea01129..bffcd7e5 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -1695,6 +1695,39 @@ int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
return 0;
}
+int drmCrtcGetSequence(int fd, uint32_t crtcId, uint64_t *sequence, uint64_t *ns)
+{
+ struct drm_crtc_get_sequence get_seq;
+ int ret;
+
+ memclear(get_seq);
+ get_seq.crtc_id = crtcId;
+ ret = drmIoctl(fd, DRM_IOCTL_CRTC_GET_SEQUENCE, &get_seq);
+ if (ret)
+ return ret;
+
+ if (sequence)
+ *sequence = get_seq.sequence;
+ if (ns)
+ *ns = get_seq.sequence_ns;
+ return 0;
+}
+
+int drmCrtcQueueSequence(int fd, uint32_t crtcId, uint32_t flags, uint64_t sequence, uint64_t user_data)
+{
+ struct drm_crtc_queue_sequence queue_seq;
+ int ret;
+
+ memclear(queue_seq);
+ queue_seq.crtc_id = crtcId;
+ queue_seq.flags = flags;
+ queue_seq.sequence = sequence;
+ queue_seq.user_data = user_data;
+
+ ret = drmIoctl(fd, DRM_IOCTL_CRTC_QUEUE_SEQUENCE, &queue_seq);
+ return ret;
+}
+
/**
* Acquire the AGP device.
*
diff --git a/xf86drm.h b/xf86drm.h
index 2855a3ee..ed1cacda 100644
--- a/xf86drm.h
+++ b/xf86drm.h
@@ -636,6 +636,11 @@ extern int drmCtlUninstHandler(int fd);
extern int drmSetClientCap(int fd, uint64_t capability,
uint64_t value);
+extern int drmCrtcGetSequence(int fd, uint32_t crtcId,
+ uint64_t *sequence, uint64_t *ns);
+extern int drmCrtcQueueSequence(int fd, uint32_t crtcId,
+ uint32_t flags, uint64_t sequence,
+ uint64_t user_data);
/* General user-level programmer's API: authenticated client and/or X */
extern int drmMap(int fd,
drm_handle_t handle,
@@ -728,7 +733,7 @@ extern void drmMsg(const char *format, ...) DRM_PRINTFLIKE(1, 2);
extern int drmSetMaster(int fd);
extern int drmDropMaster(int fd);
-#define DRM_EVENT_CONTEXT_VERSION 3
+#define DRM_EVENT_CONTEXT_VERSION 4
typedef struct _drmEventContext {
@@ -755,6 +760,10 @@ typedef struct _drmEventContext {
unsigned int crtc_id,
void *user_data);
+ void (*sequence_handler)(int fd,
+ uint64_t sequence,
+ uint64_t ns,
+ uint64_t user_data);
} drmEventContext, *drmEventContextPtr;
extern int drmHandleEvent(int fd, drmEventContextPtr evctx);
diff --git a/xf86drmMode.c b/xf86drmMode.c
index affd3fb7..0780198e 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -889,6 +889,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
int len, i;
struct drm_event *e;
struct drm_event_vblank *vblank;
+ struct drm_event_crtc_sequence *seq;
void *user_data;
/* The DRM read semantics guarantees that we always get only
@@ -933,6 +934,14 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
vblank->tv_usec,
user_data);
break;
+ case DRM_EVENT_CRTC_SEQUENCE:
+ seq = (struct drm_event_crtc_sequence *) e;
+ if (evctx->version >= 4 && evctx->sequence_handler)
+ evctx->sequence_handler(fd,
+ seq->sequence,
+ seq->time_ns,
+ seq->user_data);
+ break;
default:
break;
}
--
2.11.0
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 3+ messages in thread