diff options
author | jinhyung.jo <jinhyung.jo@samsung.com> | 2013-09-26 14:58:40 +0900 |
---|---|---|
committer | Joonyoung Shim <jy0922.shim@samsung.com> | 2017-02-15 13:37:33 +0900 |
commit | 87f1d99791a5c4197fe9193db9ff557102c57391 (patch) | |
tree | 2a7922600490a0a0db2e8f33d6846a750ed64fd3 | |
parent | a73d7b79e68dd010248d173145e3d0a2f8baf47d (diff) | |
download | libdrm-87f1d99791a5c4197fe9193db9ff557102c57391.tar.gz libdrm-87f1d99791a5c4197fe9193db9ff557102c57391.tar.bz2 libdrm-87f1d99791a5c4197fe9193db9ff557102c57391.zip |
libdrm_vigs added
Change-Id: Ie67c19bdb4a6f9e2190dbb4d3f825e878fca3635
Signed-off-by: Stanislav Vorobiov <s.vorobiov@samsung.com>
Signed-off-by: Jinhyung Jo <jinhyung.jo@samsung.com>
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | include/drm/Makefile.am | 45 | ||||
-rw-r--r-- | include/drm/vigs_drm.h | 136 | ||||
-rw-r--r-- | packaging/libdrm.spec | 2 | ||||
-rw-r--r-- | vigs/Makefile.am | 24 | ||||
-rw-r--r-- | vigs/libdrm_vigs.pc.in | 11 | ||||
-rw-r--r-- | vigs/vigs.c | 516 | ||||
-rw-r--r-- | vigs/vigs.h | 192 |
9 files changed, 944 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index dfb8fcdb..4161ad95 100644 --- a/Makefile.am +++ b/Makefile.am @@ -90,6 +90,10 @@ if HAVE_ETNAVIV ETNAVIV_SUBDIR = etnaviv endif +if HAVE_VIGS +VIGS_SUBDIR = vigs +endif + if BUILD_MANPAGES if HAVE_MANPAGES_STYLESHEET MAN_SUBDIR = man @@ -109,6 +113,7 @@ SUBDIRS = \ $(TEGRA_SUBDIR) \ $(VC4_SUBDIR) \ $(ETNAVIV_SUBDIR) \ + $(VIGS_SUBDIR) \ tests \ $(MAN_SUBDIR) diff --git a/configure.ac b/configure.ac index 8e593324..773f7d2f 100644 --- a/configure.ac +++ b/configure.ac @@ -137,6 +137,11 @@ AC_ARG_ENABLE(etnaviv-experimental-api, [Enable support for etnaviv's experimental API (default: disabled)]), [ETNAVIV=$enableval], [ETNAVIV=no]) +AC_ARG_ENABLE(vigs, + AS_HELP_STRING([--disable-vigs], + [Enable support for VIGS's API (default: enabled)]), + [VIGS=$enableval], [VIGS=yes]) + AC_ARG_ENABLE(install-test-programs, AS_HELP_STRING([--enable-install-test-programs], [Install test programs (default: no)]), @@ -426,6 +431,11 @@ if test "x$ETNAVIV" = xyes; then AC_DEFINE(HAVE_ETNAVIV, 1, [Have etnaviv support]) fi +AM_CONDITIONAL(HAVE_VIGS, [test "x$VIGS" = xyes]) +if test "x$VIGS" = xyes; then + AC_DEFINE(HAVE_VIGS, 1, [Have VIGS support]) +fi + AM_CONDITIONAL(HAVE_INSTALL_TESTS, [test "x$INSTALL_TESTS" = xyes]) if test "x$INSTALL_TESTS" = xyes; then AC_DEFINE(HAVE_INSTALL_TESTS, 1, [Install test programs]) @@ -532,6 +542,8 @@ AC_CONFIG_FILES([ vc4/libdrm_vc4.pc etnaviv/Makefile etnaviv/libdrm_etnaviv.pc + vigs/Makefile + vigs/libdrm_vigs.pc tests/Makefile tests/modeprint/Makefile tests/modetest/Makefile @@ -565,4 +577,5 @@ echo " Freedreno API $FREEDRENO (kgsl: $FREEDRENO_KGSL)" echo " Tegra API $TEGRA" echo " VC4 API $VC4" echo " Etnaviv API $ETNAVIV" +echo " VIGS API $VIGS" echo "" diff --git a/include/drm/Makefile.am b/include/drm/Makefile.am new file mode 100644 index 00000000..5f9695fd --- /dev/null +++ b/include/drm/Makefile.am @@ -0,0 +1,45 @@ +# Copyright 2005 Adam Jackson. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# on the rights to use, copy, modify, merge, publish, distribute, sub +# license, and/or sell copies of the Software, and to permit persons to whom +# the Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +# ADAM JACKSON BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# XXX airlied says, nothing besides *_drm.h and drm*.h should be necessary. +# however, r300 and via need their reg headers installed in order to build. +# better solutions are welcome. + +klibdrmincludedir = ${includedir}/libdrm +klibdrminclude_HEADERS = \ + drm.h \ + drm_mode.h \ + drm_fourcc.h \ + drm_sarea.h \ + i915_drm.h \ + mga_drm.h \ + nouveau_drm.h \ + r128_drm.h \ + radeon_drm.h \ + savage_drm.h \ + sis_drm.h \ + via_drm.h \ + mach64_drm.h \ + qxl_drm.h \ + vigs_drm.h + +if HAVE_VMWGFX +klibdrminclude_HEADERS += vmwgfx_drm.h +endif diff --git a/include/drm/vigs_drm.h b/include/drm/vigs_drm.h new file mode 100644 index 00000000..a31053e5 --- /dev/null +++ b/include/drm/vigs_drm.h @@ -0,0 +1,136 @@ +/* + * vigs_drm.h + */ + +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Authors: + * Stanislav Vorobiov <s.vorobiov@samsung.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _VIGS_DRM_H_ +#define _VIGS_DRM_H_ + +/* + * Bump this whenever driver interface changes. + */ +#define DRM_VIGS_DRIVER_VERSION 9 + +/* + * Surface access flags. + */ +#define DRM_VIGS_SAF_READ 1 +#define DRM_VIGS_SAF_WRITE 2 +#define DRM_VIGS_SAF_MASK 3 + +struct drm_vigs_get_protocol_version +{ + uint32_t version; +}; + +struct drm_vigs_create_surface +{ + uint32_t width; + uint32_t height; + uint32_t stride; + uint32_t format; + uint32_t handle; + uint32_t size; + uint32_t id; +}; + +struct drm_vigs_create_execbuffer +{ + uint32_t size; + uint32_t handle; +}; + +struct drm_vigs_gem_map +{ + uint32_t handle; + int track_access; + unsigned long address; +}; + +struct drm_vigs_surface_info +{ + uint32_t handle; + uint32_t width; + uint32_t height; + uint32_t stride; + uint32_t format; + uint32_t size; + uint32_t id; +}; + +struct drm_vigs_exec +{ + uint32_t handle; +}; + +struct drm_vigs_surface_set_gpu_dirty +{ + uint32_t handle; +}; + +struct drm_vigs_surface_start_access +{ + unsigned long address; + uint32_t saf; +}; + +struct drm_vigs_surface_end_access +{ + unsigned long address; + int sync; +}; + +#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_IOCTL_VIGS_GET_PROTOCOL_VERSION DRM_IOR(DRM_COMMAND_BASE + \ + DRM_VIGS_GET_PROTOCOL_VERSION, struct drm_vigs_get_protocol_version) +#define DRM_IOCTL_VIGS_CREATE_SURFACE DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_VIGS_CREATE_SURFACE, struct drm_vigs_create_surface) +#define DRM_IOCTL_VIGS_CREATE_EXECBUFFER DRM_IOWR(DRM_COMMAND_BASE + \ + 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_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 + \ + DRM_VIGS_EXEC, struct drm_vigs_exec) +#define DRM_IOCTL_VIGS_SURFACE_SET_GPU_DIRTY DRM_IOW(DRM_COMMAND_BASE + \ + DRM_VIGS_SURFACE_SET_GPU_DIRTY, struct drm_vigs_surface_set_gpu_dirty) +#define DRM_IOCTL_VIGS_SURFACE_START_ACCESS DRM_IOW(DRM_COMMAND_BASE + \ + 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) + +#endif diff --git a/packaging/libdrm.spec b/packaging/libdrm.spec index 63e5f9be..d7b27b31 100644 --- a/packaging/libdrm.spec +++ b/packaging/libdrm.spec @@ -78,6 +78,7 @@ make %{?_smp_mflags} %manifest %{name}.manifest %{_libdir}/libdrm.so.* %{_libdir}/libdrm_exynos.so.* +%{_libdir}/libdrm_vigs.so.* %files devel %manifest %{name}.manifest @@ -94,6 +95,7 @@ make %{?_smp_mflags} %endif %{_libdir}/libkms.so %{_libdir}/libdrm_exynos.so +%{_libdir}/libdrm_vigs.so %{_libdir}/pkgconfig/* diff --git a/vigs/Makefile.am b/vigs/Makefile.am new file mode 100644 index 00000000..dd35bc43 --- /dev/null +++ b/vigs/Makefile.am @@ -0,0 +1,24 @@ +# +# Update "-version-number M:m:r" whenever library interface changes. +# Only "M" part has to be updated. +# + +AM_CFLAGS = \ + $(WARN_CFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/vigs \ + $(PTHREADSTUBS_CFLAGS) \ + -I$(top_srcdir)/include/drm + +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_LIBADD = ../libdrm.la @PTHREADSTUBS_LIBS@ + +libdrm_vigs_la_SOURCES = vigs.c + +libdrm_vigsincludedir = ${includedir}/libdrm +libdrm_vigsinclude_HEADERS = vigs.h + +pkgconfigdir = @pkgconfigdir@ +pkgconfig_DATA = libdrm_vigs.pc diff --git a/vigs/libdrm_vigs.pc.in b/vigs/libdrm_vigs.pc.in new file mode 100644 index 00000000..676e82d5 --- /dev/null +++ b/vigs/libdrm_vigs.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: libdrm_vigs +Description: Userspace interface to VIGS kernel DRM services +Version: 2.4.35 +Libs: -L${libdir} -ldrm_vigs +Cflags: -I${includedir} -I${includedir}/libdrm -I${includedir}/vigs +Requires.private: libdrm diff --git a/vigs/vigs.c b/vigs/vigs.c new file mode 100644 index 00000000..5530d48e --- /dev/null +++ b/vigs/vigs.c @@ -0,0 +1,516 @@ +/* vigs.c + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Authors: + * Stanislav Vorobiov <s.vorobiov@samsung.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> + +#include <sys/mman.h> +#include <linux/stddef.h> + +#include <xf86drm.h> +#include <xf86atomic.h> + +#include "vigs.h" +#include "vigs_drm.h" + +#define vigs_offsetof(type, member) ((size_t)&((type*)0)->member) + +#define vigs_containerof(ptr, type, member) ((type*)((char*)(ptr) - vigs_offsetof(type, member))) + +struct vigs_drm_gem_info +{ + atomic_t ref_count; +}; + +struct vigs_drm_gem_impl +{ + struct vigs_drm_gem_info info; + + struct vigs_drm_gem gem; +}; + +struct vigs_drm_surface_impl +{ + struct vigs_drm_gem_info gem_info; + + struct vigs_drm_surface base; +}; + +struct vigs_drm_execbuffer_impl +{ + struct vigs_drm_gem_info gem_info; + + struct vigs_drm_execbuffer base; +}; + +static void vigs_drm_gem_close(struct vigs_drm_device *dev, uint32_t handle) +{ + struct drm_gem_close req = + { + .handle = handle, + }; + + if (handle) { + drmIoctl(dev->fd, DRM_IOCTL_GEM_CLOSE, &req); + } +} + +static void vigs_drm_gem_impl_init(struct vigs_drm_gem_impl *gem_impl, + struct vigs_drm_device *dev, + uint32_t handle, + uint32_t size, + uint32_t name) +{ + atomic_set(&gem_impl->info.ref_count, 1); + gem_impl->gem.dev = dev; + gem_impl->gem.size = size; + gem_impl->gem.handle = handle; + gem_impl->gem.name = name; +} + +int vigs_drm_device_create(int fd, struct vigs_drm_device **dev) +{ + drmVersionPtr version; + uint32_t major; + int ret; + + *dev = calloc(sizeof(**dev), 1); + + if (!*dev) { + ret = -ENOMEM; + goto fail1; + } + + version = drmGetVersion(fd); + + if (!version) { + ret = -EINVAL; + goto fail2; + } + + major = version->version_major; + + drmFreeVersion(version); + + if (major != DRM_VIGS_DRIVER_VERSION) { + ret = -EINVAL; + goto fail2; + } + + (*dev)->fd = fd; + + return 0; + +fail2: + free(*dev); +fail1: + *dev = NULL; + + return ret; +} + +void vigs_drm_device_destroy(struct vigs_drm_device *dev) +{ + free(dev); +} + +int vigs_drm_device_get_protocol_version(struct vigs_drm_device *dev, + uint32_t *protocol_version) +{ + struct drm_vigs_get_protocol_version req; + int ret; + + ret = drmIoctl(dev->fd, DRM_IOCTL_VIGS_GET_PROTOCOL_VERSION, &req); + + if (ret != 0) { + return -errno; + } + + if (protocol_version) { + *protocol_version = req.version; + } + + return 0; +} + +void vigs_drm_gem_ref(struct vigs_drm_gem *gem) +{ + struct vigs_drm_gem_impl *gem_impl; + + if (!gem) { + return; + } + + gem_impl = vigs_containerof(gem, struct vigs_drm_gem_impl, gem); + + atomic_inc(&gem_impl->info.ref_count); +} + +void vigs_drm_gem_unref(struct vigs_drm_gem *gem) +{ + struct vigs_drm_gem_impl *gem_impl; + + if (!gem) { + return; + } + + gem_impl = vigs_containerof(gem, struct vigs_drm_gem_impl, gem); + + assert(atomic_read(&gem_impl->info.ref_count) > 0); + if (!atomic_dec_and_test(&gem_impl->info.ref_count)) { + return; + } + + if (gem->vaddr) { + munmap(gem->vaddr, gem->size); + } + + vigs_drm_gem_close(gem->dev, gem->handle); + + free(gem_impl); +} + +int vigs_drm_gem_get_name(struct vigs_drm_gem *gem) +{ + struct drm_gem_flink req = + { + .handle = gem->handle, + }; + int ret; + + if (gem->name) { + return 0; + } + + ret = drmIoctl(gem->dev->fd, DRM_IOCTL_GEM_FLINK, &req); + + if (ret != 0) { + return -errno; + } + + gem->name = req.name; + + return 0; +} + +int vigs_drm_gem_map(struct vigs_drm_gem *gem, int track_access) +{ + struct drm_vigs_gem_map req = + { + .handle = gem->handle, + .track_access = track_access + }; + int ret; + + if (gem->vaddr) { + return 0; + } + + ret = drmIoctl(gem->dev->fd, DRM_IOCTL_VIGS_GEM_MAP, &req); + + if (ret != 0) { + return -errno; + } + + gem->vaddr = (void*)req.address; + + return 0; +} + +void vigs_drm_gem_unmap(struct vigs_drm_gem *gem) +{ + if (!gem->vaddr) { + return; + } + + munmap(gem->vaddr, gem->size); + gem->vaddr = NULL; +} + +int vigs_drm_surface_create(struct vigs_drm_device *dev, + uint32_t width, + uint32_t height, + uint32_t stride, + uint32_t format, + struct vigs_drm_surface **sfc) +{ + struct vigs_drm_surface_impl *sfc_impl; + struct drm_vigs_create_surface req = + { + .width = width, + .height = height, + .stride = stride, + .format = format, + }; + int ret; + + sfc_impl = calloc(sizeof(*sfc_impl), 1); + + if (!sfc_impl) { + ret = -ENOMEM; + goto fail1; + } + + ret = drmIoctl(dev->fd, DRM_IOCTL_VIGS_CREATE_SURFACE, &req); + + if (ret != 0) { + ret = -errno; + goto fail2; + } + + vigs_drm_gem_impl_init((struct vigs_drm_gem_impl*)sfc_impl, + dev, + req.handle, + req.size, + 0); + + sfc_impl->base.width = width; + sfc_impl->base.height = height; + sfc_impl->base.stride = stride; + sfc_impl->base.format = format; + sfc_impl->base.id = req.id; + + *sfc = &sfc_impl->base; + + return 0; + +fail2: + free(sfc_impl); +fail1: + *sfc = NULL; + + return ret; +} + +int vigs_drm_surface_open(struct vigs_drm_device *dev, + uint32_t name, + struct vigs_drm_surface **sfc) +{ + struct vigs_drm_surface_impl *sfc_impl; + struct drm_gem_open req = + { + .name = name, + }; + struct drm_vigs_surface_info info_req; + int ret; + + sfc_impl = calloc(sizeof(*sfc_impl), 1); + + if (!sfc_impl) { + ret = -ENOMEM; + goto fail1; + } + + ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req); + + if (ret != 0) { + ret = -errno; + goto fail2; + } + + info_req.handle = req.handle; + + ret = drmIoctl(dev->fd, DRM_IOCTL_VIGS_SURFACE_INFO, &info_req); + + if (ret != 0) { + ret = -errno; + goto fail3; + } + + vigs_drm_gem_impl_init((struct vigs_drm_gem_impl*)sfc_impl, + dev, + req.handle, + info_req.size, + name); + + sfc_impl->base.width = info_req.width; + sfc_impl->base.height = info_req.height; + sfc_impl->base.stride = info_req.stride; + sfc_impl->base.format = info_req.format; + sfc_impl->base.id = info_req.id; + + *sfc = &sfc_impl->base; + + return 0; + +fail3: + vigs_drm_gem_close(dev, req.handle); +fail2: + free(sfc_impl); +fail1: + *sfc = NULL; + + return ret; +} + +int vigs_drm_surface_set_gpu_dirty(struct vigs_drm_surface *sfc) +{ + struct drm_vigs_surface_set_gpu_dirty req = + { + .handle = sfc->gem.handle + }; + int ret; + + ret = drmIoctl(sfc->gem.dev->fd, DRM_IOCTL_VIGS_SURFACE_SET_GPU_DIRTY, &req); + + return (ret != 0) ? -errno : 0; +} + +int vigs_drm_surface_start_access(struct vigs_drm_surface *sfc, + uint32_t saf) +{ + struct drm_vigs_surface_start_access req = + { + .address = (unsigned long)sfc->gem.vaddr, + .saf = saf + }; + int ret; + + ret = drmIoctl(sfc->gem.dev->fd, DRM_IOCTL_VIGS_SURFACE_START_ACCESS, &req); + + return (ret != 0) ? -errno : 0; +} + +int vigs_drm_surface_end_access(struct vigs_drm_surface *sfc, + int sync) +{ + struct drm_vigs_surface_end_access req = + { + .address = (unsigned long)sfc->gem.vaddr, + .sync = sync + }; + int ret; + + ret = drmIoctl(sfc->gem.dev->fd, DRM_IOCTL_VIGS_SURFACE_END_ACCESS, &req); + + return (ret != 0) ? -errno : 0; +} + +int vigs_drm_execbuffer_create(struct vigs_drm_device *dev, + uint32_t size, + struct vigs_drm_execbuffer **execbuffer) +{ + struct vigs_drm_execbuffer_impl *execbuffer_impl; + struct drm_vigs_create_execbuffer req = + { + .size = size + }; + int ret; + + execbuffer_impl = calloc(sizeof(*execbuffer_impl), 1); + + if (!execbuffer_impl) { + ret = -ENOMEM; + goto fail1; + } + + ret = drmIoctl(dev->fd, DRM_IOCTL_VIGS_CREATE_EXECBUFFER, &req); + + if (ret != 0) { + ret = -errno; + goto fail2; + } + + vigs_drm_gem_impl_init((struct vigs_drm_gem_impl*)execbuffer_impl, + dev, + req.handle, + req.size, + 0); + + *execbuffer = &execbuffer_impl->base; + + return 0; + +fail2: + free(execbuffer_impl); +fail1: + *execbuffer = NULL; + + return ret; +} + +int vigs_drm_execbuffer_open(struct vigs_drm_device *dev, + uint32_t name, + struct vigs_drm_execbuffer **execbuffer) +{ + struct vigs_drm_execbuffer_impl *execbuffer_impl; + struct drm_gem_open req = + { + .name = name, + }; + int ret; + + execbuffer_impl = calloc(sizeof(*execbuffer_impl), 1); + + if (!execbuffer_impl) { + ret = -ENOMEM; + goto fail1; + } + + ret = drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req); + + if (ret != 0) { + ret = -errno; + goto fail2; + } + + vigs_drm_gem_impl_init((struct vigs_drm_gem_impl*)execbuffer_impl, + dev, + req.handle, + req.size, + name); + + *execbuffer = &execbuffer_impl->base; + + return 0; + +fail2: + free(execbuffer_impl); +fail1: + *execbuffer = NULL; + + return ret; +} + +int vigs_drm_execbuffer_exec(struct vigs_drm_execbuffer *execbuffer) +{ + struct drm_vigs_exec req = + { + .handle = execbuffer->gem.handle + }; + int ret; + + ret = drmIoctl(execbuffer->gem.dev->fd, DRM_IOCTL_VIGS_EXEC, &req); + + return (ret != 0) ? -errno : 0; +} diff --git a/vigs/vigs.h b/vigs/vigs.h new file mode 100644 index 00000000..681031a0 --- /dev/null +++ b/vigs/vigs.h @@ -0,0 +1,192 @@ +/* vigs.h + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Authors: + * Stanislav Vorobiov <s.vorobiov@samsung.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __VIGS_H__ +#define __VIGS_H__ + +#include <stdint.h> +#include <stdbool.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Surface formats. + */ +typedef enum +{ + vigs_drm_surface_bgrx8888 = 0x0, + vigs_drm_surface_bgra8888 = 0x1, +} vigs_drm_surface_format; + +/* + * Surface access flags. + */ +#define VIGS_DRM_SAF_READ 1 +#define VIGS_DRM_SAF_WRITE 2 + +struct vigs_drm_device +{ + /* DRM fd. */ + int fd; +}; + +struct vigs_drm_gem +{ + /* VIGS device object. */ + struct vigs_drm_device *dev; + + /* size of the buffer created. */ + uint32_t size; + + /* a gem handle to gem object created. */ + uint32_t handle; + + /* a gem global handle from flink request. initially 0. */ + uint32_t name; + + /* user space address to a gem buffer mmaped. initially NULL. */ + void *vaddr; +}; + +struct vigs_drm_surface +{ + struct vigs_drm_gem gem; + + uint32_t width; + uint32_t height; + uint32_t stride; + uint32_t format; + uint32_t id; +}; + +struct vigs_drm_execbuffer +{ + struct vigs_drm_gem gem; +}; + +/* + * All functions return 0 on success and < 0 on error, i.e. kernel style: + * return -ENOMEM; + */ + +/* + * Device functions. + * @{ + */ + +/* + * Returns -EINVAL on driver version mismatch. + */ +int vigs_drm_device_create(int fd, struct vigs_drm_device **dev); + +void vigs_drm_device_destroy(struct vigs_drm_device *dev); + +int vigs_drm_device_get_protocol_version(struct vigs_drm_device *dev, + uint32_t *protocol_version); + +/* + * @} + */ + +/* + * GEM functions. + * @{ + */ + +/* + * Passing NULL won't hurt, this is for convenience. + */ +void vigs_drm_gem_ref(struct vigs_drm_gem *gem); + +/* + * Passing NULL won't hurt, this is for convenience. + */ +void vigs_drm_gem_unref(struct vigs_drm_gem *gem); + +int vigs_drm_gem_get_name(struct vigs_drm_gem *gem); + +int vigs_drm_gem_map(struct vigs_drm_gem *gem, int track_access); + +void vigs_drm_gem_unmap(struct vigs_drm_gem *gem); + +/* + * @} + */ + +/* + * Surface functions. + * @{ + */ + +int vigs_drm_surface_create(struct vigs_drm_device *dev, + uint32_t width, + uint32_t height, + uint32_t stride, + uint32_t format, + struct vigs_drm_surface **sfc); + +int vigs_drm_surface_open(struct vigs_drm_device *dev, + uint32_t name, + struct vigs_drm_surface **sfc); + +int vigs_drm_surface_set_gpu_dirty(struct vigs_drm_surface *sfc); + +int vigs_drm_surface_start_access(struct vigs_drm_surface *sfc, + uint32_t saf); + +int vigs_drm_surface_end_access(struct vigs_drm_surface *sfc, + int sync); + +/* + * @} + */ + +/* + * Execbuffer functions. + * @{ + */ + +int vigs_drm_execbuffer_create(struct vigs_drm_device *dev, + uint32_t size, + struct vigs_drm_execbuffer **execbuffer); + +int vigs_drm_execbuffer_open(struct vigs_drm_device *dev, + uint32_t name, + struct vigs_drm_execbuffer **execbuffer); + +int vigs_drm_execbuffer_exec(struct vigs_drm_execbuffer *execbuffer); + +/* + * @} + */ + +#ifdef __cplusplus +}; +#endif /* __cplusplus */ + +#endif |