summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjinhyung.jo <jinhyung.jo@samsung.com>2013-09-26 14:58:40 +0900
committerJoonyoung Shim <jy0922.shim@samsung.com>2017-02-15 13:37:33 +0900
commit87f1d99791a5c4197fe9193db9ff557102c57391 (patch)
tree2a7922600490a0a0db2e8f33d6846a750ed64fd3
parenta73d7b79e68dd010248d173145e3d0a2f8baf47d (diff)
downloadlibdrm-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.am5
-rw-r--r--configure.ac13
-rw-r--r--include/drm/Makefile.am45
-rw-r--r--include/drm/vigs_drm.h136
-rw-r--r--packaging/libdrm.spec2
-rw-r--r--vigs/Makefile.am24
-rw-r--r--vigs/libdrm_vigs.pc.in11
-rw-r--r--vigs/vigs.c516
-rw-r--r--vigs/vigs.h192
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