summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Vorobiov <s.vorobiov@samsung.com>2013-12-16 20:03:38 +0400
committerStanislav Vorobiov <s.vorobiov@samsung.com>2014-03-06 17:57:11 +0400
commit56c3ef8f10406185c5b7dd995e8f3625164b9a7e (patch)
tree836407c35c138d1deac7b5f2ea3384e98360a3f6
parent95be3fff22e2d6083a36d0eb1c5a6bd0d685d408 (diff)
downloadlibdrm-56c3ef8f10406185c5b7dd995e8f3625164b9a7e.tar.gz
libdrm-56c3ef8f10406185c5b7dd995e8f3625164b9a7e.tar.bz2
libdrm-56c3ef8f10406185c5b7dd995e8f3625164b9a7e.zip
libdrm_vigs: Fence support added
VIGS kernel driver now supports fences, so update libdrm to expose them to user space Change-Id: I9c07084a357c0a8dc87c049e01238f9049ca0828 Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
-rw-r--r--include/drm/vigs_drm.h55
-rw-r--r--vigs/Makefile.am2
-rw-r--r--vigs/vigs.c139
-rw-r--r--vigs/vigs.h44
4 files changed, 233 insertions, 7 deletions
diff --git a/include/drm/vigs_drm.h b/include/drm/vigs_drm.h
index a31053e5..3a11ab21 100644
--- a/include/drm/vigs_drm.h
+++ b/include/drm/vigs_drm.h
@@ -33,7 +33,7 @@
/*
* Bump this whenever driver interface changes.
*/
-#define DRM_VIGS_DRIVER_VERSION 9
+#define DRM_VIGS_DRIVER_VERSION 10
/*
* Surface access flags.
@@ -71,6 +71,11 @@ struct drm_vigs_gem_map
unsigned long address;
};
+struct drm_vigs_gem_wait
+{
+ uint32_t handle;
+};
+
struct drm_vigs_surface_info
{
uint32_t handle;
@@ -104,15 +109,43 @@ struct drm_vigs_surface_end_access
int sync;
};
+struct drm_vigs_create_fence
+{
+ int send;
+ uint32_t handle;
+ uint32_t seq;
+};
+
+struct drm_vigs_fence_wait
+{
+ uint32_t handle;
+};
+
+struct drm_vigs_fence_signaled
+{
+ uint32_t handle;
+ int signaled;
+};
+
+struct drm_vigs_fence_unref
+{
+ uint32_t handle;
+};
+
#define DRM_VIGS_GET_PROTOCOL_VERSION 0x00
#define DRM_VIGS_CREATE_SURFACE 0x01
#define DRM_VIGS_CREATE_EXECBUFFER 0x02
#define DRM_VIGS_GEM_MAP 0x03
-#define DRM_VIGS_SURFACE_INFO 0x04
-#define DRM_VIGS_EXEC 0x05
-#define DRM_VIGS_SURFACE_SET_GPU_DIRTY 0x06
-#define DRM_VIGS_SURFACE_START_ACCESS 0x07
-#define DRM_VIGS_SURFACE_END_ACCESS 0x08
+#define DRM_VIGS_GEM_WAIT 0x04
+#define DRM_VIGS_SURFACE_INFO 0x05
+#define DRM_VIGS_EXEC 0x06
+#define DRM_VIGS_SURFACE_SET_GPU_DIRTY 0x07
+#define DRM_VIGS_SURFACE_START_ACCESS 0x08
+#define DRM_VIGS_SURFACE_END_ACCESS 0x09
+#define DRM_VIGS_CREATE_FENCE 0x0A
+#define DRM_VIGS_FENCE_WAIT 0x0B
+#define DRM_VIGS_FENCE_SIGNALED 0x0C
+#define DRM_VIGS_FENCE_UNREF 0x0D
#define DRM_IOCTL_VIGS_GET_PROTOCOL_VERSION DRM_IOR(DRM_COMMAND_BASE + \
DRM_VIGS_GET_PROTOCOL_VERSION, struct drm_vigs_get_protocol_version)
@@ -122,6 +155,8 @@ struct drm_vigs_surface_end_access
DRM_VIGS_CREATE_EXECBUFFER, struct drm_vigs_create_execbuffer)
#define DRM_IOCTL_VIGS_GEM_MAP DRM_IOWR(DRM_COMMAND_BASE + \
DRM_VIGS_GEM_MAP, struct drm_vigs_gem_map)
+#define DRM_IOCTL_VIGS_GEM_WAIT DRM_IOW(DRM_COMMAND_BASE + \
+ DRM_VIGS_GEM_WAIT, struct drm_vigs_gem_wait)
#define DRM_IOCTL_VIGS_SURFACE_INFO DRM_IOWR(DRM_COMMAND_BASE + \
DRM_VIGS_SURFACE_INFO, struct drm_vigs_surface_info)
#define DRM_IOCTL_VIGS_EXEC DRM_IOW(DRM_COMMAND_BASE + \
@@ -132,5 +167,13 @@ struct drm_vigs_surface_end_access
DRM_VIGS_SURFACE_START_ACCESS, struct drm_vigs_surface_start_access)
#define DRM_IOCTL_VIGS_SURFACE_END_ACCESS DRM_IOW(DRM_COMMAND_BASE + \
DRM_VIGS_SURFACE_END_ACCESS, struct drm_vigs_surface_end_access)
+#define DRM_IOCTL_VIGS_CREATE_FENCE DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_VIGS_CREATE_FENCE, struct drm_vigs_create_fence)
+#define DRM_IOCTL_VIGS_FENCE_WAIT DRM_IOW(DRM_COMMAND_BASE + \
+ DRM_VIGS_FENCE_WAIT, struct drm_vigs_fence_wait)
+#define DRM_IOCTL_VIGS_FENCE_SIGNALED DRM_IOWR(DRM_COMMAND_BASE + \
+ DRM_VIGS_FENCE_SIGNALED, struct drm_vigs_fence_signaled)
+#define DRM_IOCTL_VIGS_FENCE_UNREF DRM_IOW(DRM_COMMAND_BASE + \
+ DRM_VIGS_FENCE_UNREF, struct drm_vigs_fence_unref)
#endif
diff --git a/vigs/Makefile.am b/vigs/Makefile.am
index dd35bc43..df85b564 100644
--- a/vigs/Makefile.am
+++ b/vigs/Makefile.am
@@ -12,7 +12,7 @@ AM_CFLAGS = \
libdrm_vigs_la_LTLIBRARIES = libdrm_vigs.la
libdrm_vigs_ladir = $(libdir)
-libdrm_vigs_la_LDFLAGS = -version-number 4:0:0 -no-undefined
+libdrm_vigs_la_LDFLAGS = -version-number 5:0:0 -no-undefined
libdrm_vigs_la_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@
libdrm_vigs_la_SOURCES = vigs.c
diff --git a/vigs/vigs.c b/vigs/vigs.c
index 5530d48e..dc95a7c5 100644
--- a/vigs/vigs.c
+++ b/vigs/vigs.c
@@ -73,6 +73,13 @@ struct vigs_drm_execbuffer_impl
struct vigs_drm_execbuffer base;
};
+struct vigs_drm_fence_impl
+{
+ struct vigs_drm_fence base;
+
+ atomic_t ref_count;
+};
+
static void vigs_drm_gem_close(struct vigs_drm_device *dev, uint32_t handle)
{
struct drm_gem_close req =
@@ -257,6 +264,23 @@ void vigs_drm_gem_unmap(struct vigs_drm_gem *gem)
gem->vaddr = NULL;
}
+int vigs_drm_gem_wait(struct vigs_drm_gem *gem)
+{
+ struct drm_vigs_gem_wait req =
+ {
+ .handle = gem->handle,
+ };
+ int ret;
+
+ ret = drmIoctl(gem->dev->fd, DRM_IOCTL_VIGS_GEM_WAIT, &req);
+
+ if (ret != 0) {
+ return -errno;
+ }
+
+ return 0;
+}
+
int vigs_drm_surface_create(struct vigs_drm_device *dev,
uint32_t width,
uint32_t height,
@@ -514,3 +538,118 @@ int vigs_drm_execbuffer_exec(struct vigs_drm_execbuffer *execbuffer)
return (ret != 0) ? -errno : 0;
}
+
+int vigs_drm_fence_create(struct vigs_drm_device *dev,
+ int send,
+ struct vigs_drm_fence **fence)
+{
+ struct vigs_drm_fence_impl *fence_impl;
+ struct drm_vigs_create_fence req =
+ {
+ .send = send
+ };
+ int ret;
+
+ fence_impl = calloc(sizeof(*fence_impl), 1);
+
+ if (!fence_impl) {
+ ret = -ENOMEM;
+ goto fail1;
+ }
+
+ ret = drmIoctl(dev->fd, DRM_IOCTL_VIGS_CREATE_FENCE, &req);
+
+ if (ret != 0) {
+ ret = -errno;
+ goto fail2;
+ }
+
+ atomic_set(&fence_impl->ref_count, 1);
+ fence_impl->base.dev = dev;
+ fence_impl->base.handle = req.handle;
+ fence_impl->base.seq = req.seq;
+ fence_impl->base.signaled = 0;
+
+ *fence = &fence_impl->base;
+
+ return 0;
+
+fail2:
+ free(fence_impl);
+fail1:
+ *fence = NULL;
+
+ return ret;
+}
+
+void vigs_drm_fence_ref(struct vigs_drm_fence *fence)
+{
+ struct vigs_drm_fence_impl *fence_impl;
+
+ if (!fence) {
+ return;
+ }
+
+ fence_impl = vigs_containerof(fence, struct vigs_drm_fence_impl, base);
+
+ atomic_inc(&fence_impl->ref_count);
+}
+
+void vigs_drm_fence_unref(struct vigs_drm_fence *fence)
+{
+ struct vigs_drm_fence_impl *fence_impl;
+ struct drm_vigs_fence_unref req;
+
+ if (!fence) {
+ return;
+ }
+
+ fence_impl = vigs_containerof(fence, struct vigs_drm_fence_impl, base);
+
+ assert(atomic_read(&fence_impl->ref_count) > 0);
+ if (!atomic_dec_and_test(&fence_impl->ref_count)) {
+ return;
+ }
+
+ req.handle = fence->handle;
+
+ drmIoctl(fence->dev->fd, DRM_IOCTL_VIGS_FENCE_UNREF, &req);
+
+ free(fence_impl);
+}
+
+int vigs_drm_fence_wait(struct vigs_drm_fence *fence)
+{
+ struct drm_vigs_fence_wait req =
+ {
+ .handle = fence->handle
+ };
+ int ret;
+
+ ret = drmIoctl(fence->dev->fd, DRM_IOCTL_VIGS_FENCE_WAIT, &req);
+
+ return (ret != 0) ? -errno : 0;
+}
+
+int vigs_drm_fence_check(struct vigs_drm_fence *fence)
+{
+ struct drm_vigs_fence_signaled req =
+ {
+ .handle = fence->handle
+ };
+ int ret;
+
+ if (fence->signaled) {
+ return 0;
+ }
+
+ ret = drmIoctl(fence->dev->fd, DRM_IOCTL_VIGS_FENCE_SIGNALED, &req);
+
+ if (ret != 0) {
+ return -errno;
+ }
+
+ fence->signaled = req.signaled;
+
+ return 0;
+}
diff --git a/vigs/vigs.h b/vigs/vigs.h
index 681031a0..f44027bd 100644
--- a/vigs/vigs.h
+++ b/vigs/vigs.h
@@ -89,6 +89,21 @@ struct vigs_drm_execbuffer
struct vigs_drm_gem gem;
};
+struct vigs_drm_fence
+{
+ /* VIGS device object. */
+ struct vigs_drm_device *dev;
+
+ /* a handle to fence object. */
+ uint32_t handle;
+
+ /* fence sequence number. */
+ uint32_t seq;
+
+ /* is fence signaled ? updated on 'vigs_drm_fence_check'. */
+ int signaled;
+};
+
/*
* All functions return 0 on success and < 0 on error, i.e. kernel style:
* return -ENOMEM;
@@ -134,6 +149,8 @@ int vigs_drm_gem_map(struct vigs_drm_gem *gem, int track_access);
void vigs_drm_gem_unmap(struct vigs_drm_gem *gem);
+int vigs_drm_gem_wait(struct vigs_drm_gem *gem);
+
/*
* @}
*/
@@ -185,6 +202,33 @@ int vigs_drm_execbuffer_exec(struct vigs_drm_execbuffer *execbuffer);
* @}
*/
+/*
+ * Fence functions.
+ * @{
+ */
+
+int vigs_drm_fence_create(struct vigs_drm_device *dev,
+ int send,
+ struct vigs_drm_fence **fence);
+
+/*
+ * Passing NULL won't hurt, this is for convenience.
+ */
+void vigs_drm_fence_ref(struct vigs_drm_fence *fence);
+
+/*
+ * Passing NULL won't hurt, this is for convenience.
+ */
+void vigs_drm_fence_unref(struct vigs_drm_fence *fence);
+
+int vigs_drm_fence_wait(struct vigs_drm_fence *fence);
+
+int vigs_drm_fence_check(struct vigs_drm_fence *fence);
+
+/*
+ * @}
+ */
+
#ifdef __cplusplus
};
#endif /* __cplusplus */