summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-12-09 18:37:42 +0100
committerEmil Velikov <emil.l.velikov@gmail.com>2015-12-18 17:44:05 +0000
commitc13c504ed2778fe5410d4883a7025abd75d0a6a1 (patch)
treef82520d45a23ff14a3f72b44225c5d71d3587e71
parentca6c5f8c81e762b25c7b999fa5fd9d17fd67e4dc (diff)
tests: Add libkms-test library
This library contains abstractions for KMS that help remove the need for a lot of boilerplate in KMS test programs. Signed-off-by: Thierry Reding <treding@nvidia.com> Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
-rw-r--r--configure.ac1
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/kms/Makefile.am20
-rw-r--r--tests/kms/libkms-test-crtc.c47
-rw-r--r--tests/kms/libkms-test-device.c218
-rw-r--r--tests/kms/libkms-test-framebuffer.c157
-rw-r--r--tests/kms/libkms-test-plane.c139
-rw-r--r--tests/kms/libkms-test-screen.c92
-rw-r--r--tests/kms/libkms-test.h120
9 files changed, 795 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index ca6cbf4e..0c66dfc6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -499,6 +499,7 @@ AC_CONFIG_FILES([
tests/Makefile
tests/modeprint/Makefile
tests/modetest/Makefile
+ tests/kms/Makefile
tests/kmstest/Makefile
tests/proptest/Makefile
tests/radeon/Makefile
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7ffc076f..58feb123 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = util modeprint proptest modetest vbltest
+SUBDIRS = util kms modeprint proptest modetest vbltest
if HAVE_LIBKMS
SUBDIRS += kmstest
diff --git a/tests/kms/Makefile.am b/tests/kms/Makefile.am
new file mode 100644
index 00000000..da464218
--- /dev/null
+++ b/tests/kms/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = \
+ -I$(top_srcdir)/include/drm \
+ -I$(top_srcdir)/tests \
+ -I$(top_srcdir)
+
+AM_CFLAGS = \
+ $(WARN_CFLAGS)
+
+noinst_LTLIBRARIES = libkms-test.la
+
+libkms_test_la_SOURCES = \
+ libkms-test.h \
+ libkms-test-crtc.c \
+ libkms-test-device.c \
+ libkms-test-framebuffer.c \
+ libkms-test-plane.c \
+ libkms-test-screen.c
+
+libkms_test_la_LIBADD = \
+ $(top_builddir)/libdrm.la
diff --git a/tests/kms/libkms-test-crtc.c b/tests/kms/libkms-test-crtc.c
new file mode 100644
index 00000000..3adb4903
--- /dev/null
+++ b/tests/kms/libkms-test-crtc.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 "libkms-test.h"
+
+struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id)
+{
+ struct kms_crtc *crtc;
+
+ crtc = calloc(1, sizeof(*crtc));
+ if (!crtc)
+ return NULL;
+
+ crtc->device = device;
+ crtc->id = id;
+
+ return crtc;
+}
+
+void kms_crtc_free(struct kms_crtc *crtc)
+{
+ free(crtc);
+}
diff --git a/tests/kms/libkms-test-device.c b/tests/kms/libkms-test-device.c
new file mode 100644
index 00000000..53c7349b
--- /dev/null
+++ b/tests/kms/libkms-test-device.c
@@ -0,0 +1,218 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "util/common.h"
+#include "libkms-test.h"
+
+static const char *const connector_names[] = {
+ "Unknown",
+ "VGA",
+ "DVI-I",
+ "DVI-D",
+ "DVI-A",
+ "Composite",
+ "SVIDEO",
+ "LVDS",
+ "Component",
+ "9PinDIN",
+ "DisplayPort",
+ "HDMI-A",
+ "HDMI-B",
+ "TV",
+ "eDP",
+ "Virtual",
+ "DSI",
+};
+
+static void kms_device_probe_screens(struct kms_device *device)
+{
+ unsigned int counts[ARRAY_SIZE(connector_names)];
+ struct kms_screen *screen;
+ drmModeRes *res;
+ int i;
+
+ memset(counts, 0, sizeof(counts));
+
+ res = drmModeGetResources(device->fd);
+ if (!res)
+ return;
+
+ device->screens = calloc(res->count_connectors, sizeof(screen));
+ if (!device->screens)
+ return;
+
+ for (i = 0; i < res->count_connectors; i++) {
+ unsigned int *count;
+ const char *type;
+ int len;
+
+ screen = kms_screen_create(device, res->connectors[i]);
+ if (!screen)
+ continue;
+
+ /* assign a unique name to this screen */
+ type = connector_names[screen->type];
+ count = &counts[screen->type];
+
+ len = snprintf(NULL, 0, "%s-%u", type, *count);
+
+ screen->name = malloc(len + 1);
+ if (!screen->name) {
+ free(screen);
+ continue;
+ }
+
+ snprintf(screen->name, len + 1, "%s-%u", type, *count);
+ (*count)++;
+
+ device->screens[i] = screen;
+ device->num_screens++;
+ }
+
+ drmModeFreeResources(res);
+}
+
+static void kms_device_probe_crtcs(struct kms_device *device)
+{
+ struct kms_crtc *crtc;
+ drmModeRes *res;
+ int i;
+
+ res = drmModeGetResources(device->fd);
+ if (!res)
+ return;
+
+ device->crtcs = calloc(res->count_crtcs, sizeof(crtc));
+ if (!device->crtcs)
+ return;
+
+ for (i = 0; i < res->count_crtcs; i++) {
+ crtc = kms_crtc_create(device, res->crtcs[i]);
+ if (!crtc)
+ continue;
+
+ device->crtcs[i] = crtc;
+ device->num_crtcs++;
+ }
+
+ drmModeFreeResources(res);
+}
+
+static void kms_device_probe_planes(struct kms_device *device)
+{
+ struct kms_plane *plane;
+ drmModePlaneRes *res;
+ unsigned int i;
+
+ res = drmModeGetPlaneResources(device->fd);
+ if (!res)
+ return;
+
+ device->planes = calloc(res->count_planes, sizeof(plane));
+ if (!device->planes)
+ return;
+
+ for (i = 0; i < res->count_planes; i++) {
+ plane = kms_plane_create(device, res->planes[i]);
+ if (!plane)
+ continue;
+
+ device->planes[i] = plane;
+ device->num_planes++;
+ }
+
+ drmModeFreePlaneResources(res);
+}
+
+static void kms_device_probe(struct kms_device *device)
+{
+ kms_device_probe_screens(device);
+ kms_device_probe_crtcs(device);
+ kms_device_probe_planes(device);
+}
+
+struct kms_device *kms_device_open(int fd)
+{
+ struct kms_device *device;
+
+ device = calloc(1, sizeof(*device));
+ if (!device)
+ return NULL;
+
+ device->fd = fd;
+
+ kms_device_probe(device);
+
+ return device;
+}
+
+void kms_device_close(struct kms_device *device)
+{
+ unsigned int i;
+
+ for (i = 0; i < device->num_planes; i++)
+ kms_plane_free(device->planes[i]);
+
+ free(device->planes);
+
+ for (i = 0; i < device->num_crtcs; i++)
+ kms_crtc_free(device->crtcs[i]);
+
+ free(device->crtcs);
+
+ for (i = 0; i < device->num_screens; i++)
+ kms_screen_free(device->screens[i]);
+
+ free(device->screens);
+
+ if (device->fd >= 0)
+ close(device->fd);
+
+ free(device);
+}
+
+struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device,
+ uint32_t type,
+ unsigned int index)
+{
+ unsigned int i;
+
+ for (i = 0; i < device->num_planes; i++) {
+ if (device->planes[i]->type == type) {
+ if (index == 0)
+ return device->planes[i];
+
+ index--;
+ }
+ }
+
+ return NULL;
+}
diff --git a/tests/kms/libkms-test-framebuffer.c b/tests/kms/libkms-test-framebuffer.c
new file mode 100644
index 00000000..c9e5ad3c
--- /dev/null
+++ b/tests/kms/libkms-test-framebuffer.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 <errno.h>
+#include <string.h>
+
+#include <sys/mman.h>
+
+#include <drm_fourcc.h>
+
+#include "xf86drm.h"
+
+#include "libkms-test.h"
+
+struct kms_framebuffer *kms_framebuffer_create(struct kms_device *device,
+ unsigned int width,
+ unsigned int height,
+ uint32_t format)
+{
+ uint32_t handles[4], pitches[4], offsets[4];
+ struct drm_mode_create_dumb args;
+ struct kms_framebuffer *fb;
+ int err;
+
+ fb = calloc(1, sizeof(*fb));
+ if (!fb)
+ return NULL;
+
+ fb->device = device;
+ fb->width = width;
+ fb->height = height;
+ fb->format = format;
+
+ memset(&args, 0, sizeof(args));
+ args.width = width;
+ args.height = height;
+
+ switch (format) {
+ case DRM_FORMAT_XRGB8888:
+ case DRM_FORMAT_XBGR8888:
+ case DRM_FORMAT_RGBA8888:
+ args.bpp = 32;
+ break;
+
+ default:
+ free(fb);
+ return NULL;
+ }
+
+ err = drmIoctl(device->fd, DRM_IOCTL_MODE_CREATE_DUMB, &args);
+ if (err < 0) {
+ free(fb);
+ return NULL;
+ }
+
+ fb->handle = args.handle;
+ fb->pitch = args.pitch;
+ fb->size = args.size;
+
+ handles[0] = fb->handle;
+ pitches[0] = fb->pitch;
+ offsets[0] = 0;
+
+ err = drmModeAddFB2(device->fd, width, height, format, handles,
+ pitches, offsets, &fb->id, 0);
+ if (err < 0) {
+ kms_framebuffer_free(fb);
+ return NULL;
+ }
+
+ return fb;
+}
+
+void kms_framebuffer_free(struct kms_framebuffer *fb)
+{
+ struct kms_device *device = fb->device;
+ struct drm_mode_destroy_dumb args;
+ int err;
+
+ if (fb->id) {
+ err = drmModeRmFB(device->fd, fb->id);
+ if (err < 0) {
+ /* not much we can do now */
+ }
+ }
+
+ memset(&args, 0, sizeof(args));
+ args.handle = fb->handle;
+
+ err = drmIoctl(device->fd, DRM_IOCTL_MODE_DESTROY_DUMB, &args);
+ if (err < 0) {
+ /* not much we can do now */
+ }
+
+ free(fb);
+}
+
+int kms_framebuffer_map(struct kms_framebuffer *fb, void **ptrp)
+{
+ struct kms_device *device = fb->device;
+ struct drm_mode_map_dumb args;
+ void *ptr;
+ int err;
+
+ if (fb->ptr) {
+ *ptrp = fb->ptr;
+ return 0;
+ }
+
+ memset(&args, 0, sizeof(args));
+ args.handle = fb->handle;
+
+ err = drmIoctl(device->fd, DRM_IOCTL_MODE_MAP_DUMB, &args);
+ if (err < 0)
+ return -errno;
+
+ ptr = mmap(0, fb->size, PROT_READ | PROT_WRITE, MAP_SHARED,
+ device->fd, args.offset);
+ if (ptr == MAP_FAILED)
+ return -errno;
+
+ *ptrp = fb->ptr = ptr;
+
+ return 0;
+}
+
+void kms_framebuffer_unmap(struct kms_framebuffer *fb)
+{
+ if (fb->ptr) {
+ munmap(fb->ptr, fb->size);
+ fb->ptr = NULL;
+ }
+}
diff --git a/tests/kms/libkms-test-plane.c b/tests/kms/libkms-test-plane.c
new file mode 100644
index 00000000..8eb78af1
--- /dev/null
+++ b/tests/kms/libkms-test-plane.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 <errno.h>
+#include <string.h>
+
+#include "libkms-test.h"
+
+static int kms_plane_probe(struct kms_plane *plane)
+{
+ struct kms_device *device = plane->device;
+ drmModeObjectPropertiesPtr props;
+ drmModePlane *p;
+ unsigned int i;
+
+ p = drmModeGetPlane(device->fd, plane->id);
+ if (!p)
+ return -ENODEV;
+
+ /* TODO: allow dynamic assignment to CRTCs */
+ if (p->crtc_id == 0) {
+ for (i = 0; i < device->num_crtcs; i++) {
+ if (p->possible_crtcs & (1 << i)) {
+ p->crtc_id = device->crtcs[i]->id;
+ break;
+ }
+ }
+ }
+
+ for (i = 0; i < device->num_crtcs; i++) {
+ if (device->crtcs[i]->id == p->crtc_id) {
+ plane->crtc = device->crtcs[i];
+ break;
+ }
+ }
+
+ plane->formats = calloc(p->count_formats, sizeof(uint32_t));
+ if (!plane->formats)
+ return -ENOMEM;
+
+ for (i = 0; i < p->count_formats; i++)
+ plane->formats[i] = p->formats[i];
+
+ plane->num_formats = p->count_formats;
+
+ drmModeFreePlane(p);
+
+ props = drmModeObjectGetProperties(device->fd, plane->id,
+ DRM_MODE_OBJECT_PLANE);
+ if (!props)
+ return -ENODEV;
+
+ for (i = 0; i < props->count_props; i++) {
+ drmModePropertyPtr prop;
+
+ prop = drmModeGetProperty(device->fd, props->props[i]);
+ if (prop) {
+ if (strcmp(prop->name, "type") == 0)
+ plane->type = props->prop_values[i];
+
+ drmModeFreeProperty(prop);
+ }
+ }
+
+ drmModeFreeObjectProperties(props);
+
+ return 0;
+}
+
+struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id)
+{
+ struct kms_plane *plane;
+
+ plane = calloc(1, sizeof(*plane));
+ if (!plane)
+ return NULL;
+
+ plane->device = device;
+ plane->id = id;
+
+ kms_plane_probe(plane);
+
+ return plane;
+}
+
+void kms_plane_free(struct kms_plane *plane)
+{
+ free(plane);
+}
+
+int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb,
+ unsigned int x, unsigned int y)
+{
+ struct kms_device *device = plane->device;
+ int err;
+
+ err = drmModeSetPlane(device->fd, plane->id, plane->crtc->id, fb->id,
+ 0, x, y, fb->width, fb->height, 0 << 16,
+ 0 << 16, fb->width << 16, fb->height << 16);
+ if (err < 0)
+ return -errno;
+
+ return 0;
+}
+
+bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format)
+{
+ unsigned int i;
+
+ for (i = 0; i < plane->num_formats; i++)
+ if (plane->formats[i] == format)
+ return true;
+
+ return false;
+}
diff --git a/tests/kms/libkms-test-screen.c b/tests/kms/libkms-test-screen.c
new file mode 100644
index 00000000..33690222
--- /dev/null
+++ b/tests/kms/libkms-test-screen.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 <errno.h>
+#include <string.h>
+
+#include "libkms-test.h"
+
+static void kms_screen_probe(struct kms_screen *screen)
+{
+ struct kms_device *device = screen->device;
+ drmModeConnector *con;
+
+ con = drmModeGetConnector(device->fd, screen->id);
+ if (!con)
+ return;
+
+ screen->type = con->connector_type;
+
+ if (con->connection == DRM_MODE_CONNECTED)
+ screen->connected = true;
+ else
+ screen->connected = false;
+
+ memcpy(&screen->mode, &con->modes[0], sizeof(drmModeModeInfo));
+ screen->width = screen->mode.hdisplay;
+ screen->height = screen->mode.vdisplay;
+
+ drmModeFreeConnector(con);
+}
+
+struct kms_screen *kms_screen_create(struct kms_device *device, uint32_t id)
+{
+ struct kms_screen *screen;
+
+ screen = calloc(1, sizeof(*screen));
+ if (!screen)
+ return NULL;
+
+ screen->device = device;
+ screen->id = id;
+
+ kms_screen_probe(screen);
+
+ return screen;
+}
+
+void kms_screen_free(struct kms_screen *screen)
+{
+ if (screen)
+ free(screen->name);
+
+ free(screen);
+}
+
+int kms_screen_set(struct kms_screen *screen, struct kms_crtc *crtc,
+ struct kms_framebuffer *fb)
+{
+ struct kms_device *device = screen->device;
+ int err;
+
+ err = drmModeSetCrtc(device->fd, crtc->id, fb->id, 0, 0, &screen->id,
+ 1, &screen->mode);
+ if (err < 0)
+ return -errno;
+
+ return 0;
+}
diff --git a/tests/kms/libkms-test.h b/tests/kms/libkms-test.h
new file mode 100644
index 00000000..7b1d02e9
--- /dev/null
+++ b/tests/kms/libkms-test.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2014 NVIDIA Corporation
+ *
+ * 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
+ * THE AUTHORS OR COPYRIGHT HOLDERS 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 LIBKMS_TEST_H
+#define LIBKMS_TEST_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <xf86drmMode.h>
+
+struct kms_device {
+ int fd;
+
+ struct kms_screen **screens;
+ unsigned int num_screens;
+
+ struct kms_crtc **crtcs;
+ unsigned int num_crtcs;
+
+ struct kms_plane **planes;
+ unsigned int num_planes;
+};
+
+struct kms_device *kms_device_open(int fd);
+void kms_device_close(struct kms_device *device);
+
+struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device,
+ uint32_t type,
+ unsigned int index);
+
+struct kms_crtc {
+ struct kms_device *device;
+ uint32_t id;
+};
+
+struct kms_crtc *kms_crtc_create(struct kms_device *device, uint32_t id);
+void kms_crtc_free(struct kms_crtc *crtc);
+
+struct kms_framebuffer {
+ struct kms_device *device;
+
+ unsigned int width;
+ unsigned int height;
+ unsigned int pitch;
+ uint32_t format;
+ size_t size;
+
+ uint32_t handle;
+ uint32_t id;
+
+ void *ptr;
+};
+
+struct kms_framebuffer *kms_framebuffer_create(struct kms_device *device,
+ unsigned int width,
+ unsigned int height,
+ uint32_t format);
+void kms_framebuffer_free(struct kms_framebuffer *fb);
+int kms_framebuffer_map(struct kms_framebuffer *fb, void **ptrp);
+void kms_framebuffer_unmap(struct kms_framebuffer *fb);
+
+struct kms_screen {
+ struct kms_device *device;
+ bool connected;
+ uint32_t type;
+ uint32_t id;
+
+ unsigned int width;
+ unsigned int height;
+ char *name;
+
+ drmModeModeInfo mode;
+};
+
+struct kms_screen *kms_screen_create(struct kms_device *device, uint32_t id);
+void kms_screen_free(struct kms_screen *screen);
+
+int kms_screen_set(struct kms_screen *screen, struct kms_crtc *crtc,
+ struct kms_framebuffer *fb);
+
+struct kms_plane {
+ struct kms_device *device;
+ struct kms_crtc *crtc;
+ unsigned int type;
+ uint32_t id;
+
+ uint32_t *formats;
+ unsigned int num_formats;
+};
+
+struct kms_plane *kms_plane_create(struct kms_device *device, uint32_t id);
+void kms_plane_free(struct kms_plane *plane);
+
+int kms_plane_set(struct kms_plane *plane, struct kms_framebuffer *fb,
+ unsigned int x, unsigned int y);
+bool kms_plane_supports_format(struct kms_plane *plane, uint32_t format);
+
+#endif