* [PATCH libdrm 0/2] Blob and atomic wrappers
@ 2015-05-22 12:36 Daniel Stone
2015-05-22 12:36 ` [PATCH libdrm 1/2] Support atomic modesetting ioctl Daniel Stone
2015-05-22 12:36 ` [PATCH libdrm 2/2] Add blob property create/destroy ioctl wrappers Daniel Stone
0 siblings, 2 replies; 4+ messages in thread
From: Daniel Stone @ 2015-05-22 12:36 UTC (permalink / raw)
To: dri-devel
Hi,
Nothing big here, just the wrappers for the blob-property API, as well
as the atomic API now it's been validated by Weston.
The blob work is my own, where the atomic work is a mega-squash of
commits from Ville and Rob in particular, with my own changes to modify
the user-facing API a little, and resync with the kernel interface.
Cheers,
Daniel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH libdrm 1/2] Support atomic modesetting ioctl
2015-05-22 12:36 [PATCH libdrm 0/2] Blob and atomic wrappers Daniel Stone
@ 2015-05-22 12:36 ` Daniel Stone
2015-05-22 12:36 ` [PATCH libdrm 2/2] Add blob property create/destroy ioctl wrappers Daniel Stone
1 sibling, 0 replies; 4+ messages in thread
From: Daniel Stone @ 2015-05-22 12:36 UTC (permalink / raw)
To: dri-devel
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Add support for the atomic modesetting ioctl through a property-set API.
[daniels: Squashed intermediate patches from Ville, Rob and myself.
Updated for current interface.]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Rob Clark <robclark@freedesktop.org>
Signed-off-by: Daniel Stone <daniels@collabora.com>
---
include/drm/drm.h | 9 +++
include/drm/drm_mode.h | 16 +++++
xf86drmMode.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++
xf86drmMode.h | 14 ++++
4 files changed, 225 insertions(+)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 229a29f..0b1d2ef 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -635,6 +635,13 @@ struct drm_get_cap {
*/
#define DRM_CLIENT_CAP_UNIVERSAL_PLANES 2
+/**
+ * DRM_CLIENT_CAP_ATOMIC
+ *
+ * If set to 1, the DRM core will allow atomic modesetting requests.
+ */
+#define DRM_CLIENT_CAP_ATOMIC 3
+
/** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */
struct drm_set_client_cap {
__u64 capability;
@@ -758,6 +765,7 @@ struct drm_prime_handle {
#define DRM_IOCTL_MODE_OBJ_GETPROPERTIES DRM_IOWR(0xB9, struct drm_mode_obj_get_properties)
#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2)
+#define DRM_IOCTL_MODE_ATOMIC DRM_IOWR(0xBC, struct drm_mode_atomic)
/**
* Device specific ioctls should only be in their respective headers
@@ -806,6 +814,7 @@ struct drm_event_vblank {
#define DRM_CAP_PRIME 0x5
#define DRM_CAP_TIMESTAMP_MONOTONIC 0x6
#define DRM_CAP_ASYNC_PAGE_FLIP 0x7
+#define DRM_CAP_ATOMIC 0xa
#define DRM_PRIME_CAP_IMPORT 0x1
#define DRM_PRIME_CAP_EXPORT 0x2
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index a2ab88a..66f856f 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -507,4 +507,20 @@ struct drm_mode_destroy_dumb {
__u32 handle;
};
+/* page-flip flags are valid, plus: */
+#define DRM_MODE_ATOMIC_TEST_ONLY 0x0100
+#define DRM_MODE_ATOMIC_NONBLOCK 0x0200
+#define DRM_MODE_ATOMIC_ALLOW_MODESET 0x0400
+
+struct drm_mode_atomic {
+ __u32 flags;
+ __u32 count_objs;
+ __u64 objs_ptr;
+ __u64 count_props_ptr;
+ __u64 props_ptr;
+ __u64 prop_values_ptr;
+ __u64 reserved;
+ __u64 user_data;
+};
+
#endif
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 1333da4..30b94b8 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -40,6 +40,7 @@
#include <stdint.h>
#include <sys/ioctl.h>
#include <stdio.h>
+#include <stdbool.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -1147,3 +1148,188 @@ int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop);
}
+
+typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr;
+
+struct _drmModeAtomicReqItem {
+ uint32_t object_id;
+ uint32_t property_id;
+ uint64_t value;
+ drmModeAtomicReqItemPtr next;
+};
+
+struct _drmModeAtomicReq {
+ unsigned int count_objs;
+ unsigned int count_props;
+ drmModeAtomicReqItem list;
+};
+
+drmModeAtomicReqPtr drmModeAtomicAlloc(void)
+{
+ drmModeAtomicReqPtr req;
+
+ req = drmMalloc(sizeof *req);
+ if (!req)
+ return NULL;
+
+ req->list.next = NULL;
+ req->count_props = 0;
+ req->count_objs = 0;
+
+ return req;
+}
+
+int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
+ uint32_t object_id,
+ uint32_t property_id,
+ uint64_t value)
+{
+ drmModeAtomicReqItemPtr prev = &req->list;
+ bool new_obj = false;
+
+ /* keep it sorted by object_id and property_id */
+ while (prev->next) {
+ if (prev->next->object_id > object_id)
+ break;
+
+ if (prev->next->object_id == object_id &&
+ prev->next->property_id >= property_id)
+ break;
+
+ prev = prev->next;
+ }
+
+ if ((prev == &req->list || prev->object_id != object_id) &&
+ (!prev->next || prev->next->object_id != object_id))
+ new_obj = true;
+
+ /* replace or add? */
+ if (prev->next &&
+ prev->next->object_id == object_id &&
+ prev->next->property_id == property_id) {
+ drmModeAtomicReqItemPtr item = prev->next;
+ item->value = value;
+ } else {
+ drmModeAtomicReqItemPtr item;
+
+ item = drmMalloc(sizeof *item);
+ if (!item)
+ return -1;
+
+ item->object_id = object_id;
+ item->property_id = property_id;
+ item->value = value;
+
+ item->next = prev->next;
+ prev->next = item;
+
+ req->count_props++;
+ }
+
+ if (new_obj)
+ req->count_objs++;
+
+ return 0;
+}
+
+void drmModeAtomicFree(drmModeAtomicReqPtr req)
+{
+ drmModeAtomicReqItemPtr item;
+
+ if (!req)
+ return;
+
+ item = req->list.next;
+
+ while (item) {
+ drmModeAtomicReqItemPtr next = item->next;
+
+ drmFree(item);
+
+ item = next;
+ }
+
+ drmFree(req);
+}
+
+int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags,
+ void *user_data)
+{
+ drmModeAtomicReqItemPtr item;
+ uint32_t *objs_ptr = NULL;
+ uint32_t *count_props_ptr = NULL;
+ uint32_t *props_ptr = NULL;
+ uint64_t *prop_values_ptr = NULL;
+ struct drm_mode_atomic atomic = { 0 };
+ unsigned int obj_idx = 0;
+ unsigned int prop_idx = 0;
+ int ret = -1;
+
+ if (!req)
+ return -1;
+
+ objs_ptr = drmMalloc(req->count_objs * sizeof objs_ptr[0]);
+ if (!objs_ptr) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ count_props_ptr = drmMalloc(req->count_objs * sizeof count_props_ptr[0]);
+ if (!count_props_ptr) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ props_ptr = drmMalloc(req->count_props * sizeof props_ptr[0]);
+ if (!props_ptr) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ prop_values_ptr = drmMalloc(req->count_props * sizeof prop_values_ptr[0]);
+ if (!prop_values_ptr) {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ item = req->list.next;
+
+ while (item) {
+ int count_props = 0;
+ drmModeAtomicReqItemPtr next = item;
+
+ objs_ptr[obj_idx] = item->object_id;
+
+ while (next && next->object_id == item->object_id) {
+ props_ptr[prop_idx] = next->property_id;
+ prop_values_ptr[prop_idx] = next->value;
+ prop_idx++;
+
+ count_props++;
+
+ next = next->next;
+ }
+
+ count_props_ptr[obj_idx++] = count_props;
+
+ item = next;
+ }
+
+ atomic.count_objs = req->count_objs;
+ atomic.flags = flags;
+ atomic.objs_ptr = VOID2U64(objs_ptr);
+ atomic.count_props_ptr = VOID2U64(count_props_ptr);
+ atomic.props_ptr = VOID2U64(props_ptr);
+ atomic.prop_values_ptr = VOID2U64(prop_values_ptr);
+ atomic.user_data = VOID2U64(user_data);
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic);
+
+out:
+ drmFree(objs_ptr);
+ drmFree(count_props_ptr);
+ drmFree(props_ptr);
+ drmFree(prop_values_ptr);
+
+ return ret;
+}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 20c3f15..3ba2333 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -484,6 +484,20 @@ extern int drmModeObjectSetProperty(int fd, uint32_t object_id,
uint32_t object_type, uint32_t property_id,
uint64_t value);
+
+typedef struct _drmModeAtomicReq drmModeAtomicReq, *drmModeAtomicReqPtr;
+
+extern drmModeAtomicReqPtr drmModeAtomicAlloc(void);
+extern int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
+ uint32_t object_id,
+ uint32_t property_id,
+ uint64_t value);
+extern int drmModeAtomicCommit(int fd,
+ drmModeAtomicReqPtr req,
+ uint32_t flags,
+ void *user_data);
+extern void drmModeAtomicFree(drmModeAtomicReqPtr req);
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
--
2.4.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH libdrm 2/2] Add blob property create/destroy ioctl wrappers
2015-05-22 12:36 [PATCH libdrm 0/2] Blob and atomic wrappers Daniel Stone
2015-05-22 12:36 ` [PATCH libdrm 1/2] Support atomic modesetting ioctl Daniel Stone
@ 2015-05-22 12:36 ` Daniel Stone
2015-06-04 15:14 ` Emil Velikov
1 sibling, 1 reply; 4+ messages in thread
From: Daniel Stone @ 2015-05-22 12:36 UTC (permalink / raw)
To: dri-devel
Signed-off-by: Daniel Stone <daniels@collabora.com>
---
include/drm/drm.h | 2 ++
include/drm/drm_mode.h | 21 +++++++++++++++++++++
xf86drmMode.c | 31 +++++++++++++++++++++++++++++++
xf86drmMode.h | 5 +++++
4 files changed, 59 insertions(+)
diff --git a/include/drm/drm.h b/include/drm/drm.h
index 0b1d2ef..15d4454 100644
--- a/include/drm/drm.h
+++ b/include/drm/drm.h
@@ -766,6 +766,8 @@ struct drm_prime_handle {
#define DRM_IOCTL_MODE_OBJ_SETPROPERTY DRM_IOWR(0xBA, struct drm_mode_obj_set_property)
#define DRM_IOCTL_MODE_CURSOR2 DRM_IOWR(0xBB, struct drm_mode_cursor2)
#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)
/**
* Device specific ioctls should only be in their respective headers
diff --git a/include/drm/drm_mode.h b/include/drm/drm_mode.h
index 66f856f..69c1ac3 100644
--- a/include/drm/drm_mode.h
+++ b/include/drm/drm_mode.h
@@ -523,4 +523,25 @@ struct drm_mode_atomic {
__u64 user_data;
};
+/**
+ * Create a new 'blob' data property, copying length bytes from data pointer,
+ * and returning new blob ID.
+ */
+struct drm_mode_create_blob {
+ /** Pointer to data to copy. */
+ __u64 data;
+ /** Length of data to copy. */
+ __u32 length;
+ /** Return: new property ID. */
+ __u32 blob_id;
+};
+
+/**
+ * Destroy a user-created blob property.
+ */
+struct drm_mode_destroy_blob {
+ __u32 blob_id;
+};
+
+
#endif
diff --git a/xf86drmMode.c b/xf86drmMode.c
index 30b94b8..4ef2d57 100644
--- a/xf86drmMode.c
+++ b/xf86drmMode.c
@@ -1333,3 +1333,34 @@ out:
return ret;
}
+
+int
+drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
+{
+ struct drm_mode_create_blob create;
+ int ret;
+
+ if (length >= 0xffffffff)
+ return -ERANGE;
+
+ create.length = length;
+ create.data = (uintptr_t) data;
+ create.blob_id = 0;
+ *id = 0;
+
+ ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create);
+ if (ret != 0)
+ return ret;
+
+ *id = create.blob_id;
+ return 0;
+}
+
+int
+drmModeDestroyPropertyBlob(int fd, uint32_t id)
+{
+ struct drm_mode_destroy_blob destroy;
+
+ destroy.blob_id = id;
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
+}
diff --git a/xf86drmMode.h b/xf86drmMode.h
index 3ba2333..a6f1182 100644
--- a/xf86drmMode.h
+++ b/xf86drmMode.h
@@ -498,6 +498,11 @@ extern int drmModeAtomicCommit(int fd,
void *user_data);
extern void drmModeAtomicFree(drmModeAtomicReqPtr req);
+extern int drmModeCreatePropertyBlob(int fd, const void *data, size_t size,
+ uint32_t *id);
+extern int drmModeDestroyPropertyBlob(int fd, uint32_t id);
+
+
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
--
2.4.1
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH libdrm 2/2] Add blob property create/destroy ioctl wrappers
2015-05-22 12:36 ` [PATCH libdrm 2/2] Add blob property create/destroy ioctl wrappers Daniel Stone
@ 2015-06-04 15:14 ` Emil Velikov
0 siblings, 0 replies; 4+ messages in thread
From: Emil Velikov @ 2015-06-04 15:14 UTC (permalink / raw)
To: Daniel Stone, dri-devel; +Cc: emil.l.velikov
Hi Daniel,
On 22/05/15 12:36, Daniel Stone wrote:
> Signed-off-by: Daniel Stone <daniels@collabora.com>
There is a trivial suggestion inline, although I must say thank you !
Thank you for keeping the impl. details of struct
_drmModeAtomicReqItem/_drmModeAtomicReq out of the public headers.
> --- a/xf86drmMode.c
> +++ b/xf86drmMode.c
> @@ -1333,3 +1333,34 @@ out:
>
> return ret;
> }
> +
> +int
> +drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
> +{
> + struct drm_mode_create_blob create;
Please explicitly zero the struct - most places use memclear()
> + int ret;
> +
> + if (length >= 0xffffffff)
> + return -ERANGE;
> +
> + create.length = length;
> + create.data = (uintptr_t) data;
> + create.blob_id = 0;
> + *id = 0;
> +
> + ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create);
> + if (ret != 0)
> + return ret;
> +
> + *id = create.blob_id;
> + return 0;
> +}
> +
> +int
> +drmModeDestroyPropertyBlob(int fd, uint32_t id)
> +{
> + struct drm_mode_destroy_blob destroy;
Ditto.
Thanks
Emil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-06-04 14:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-22 12:36 [PATCH libdrm 0/2] Blob and atomic wrappers Daniel Stone
2015-05-22 12:36 ` [PATCH libdrm 1/2] Support atomic modesetting ioctl Daniel Stone
2015-05-22 12:36 ` [PATCH libdrm 2/2] Add blob property create/destroy ioctl wrappers Daniel Stone
2015-06-04 15:14 ` Emil Velikov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.