diff options
author | Stanislav Vorobiov <s.vorobiov@samsung.com> | 2013-12-16 20:03:38 +0400 |
---|---|---|
committer | Stanislav Vorobiov <s.vorobiov@samsung.com> | 2014-03-06 17:57:11 +0400 |
commit | 56c3ef8f10406185c5b7dd995e8f3625164b9a7e (patch) | |
tree | 836407c35c138d1deac7b5f2ea3384e98360a3f6 | |
parent | 95be3fff22e2d6083a36d0eb1c5a6bd0d685d408 (diff) | |
download | libdrm-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.h | 55 | ||||
-rw-r--r-- | vigs/Makefile.am | 2 | ||||
-rw-r--r-- | vigs/vigs.c | 139 | ||||
-rw-r--r-- | vigs/vigs.h | 44 |
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 */ |