blob: 3dd9621d045914c64d47e3267748d44835308152 [file] [log] [blame]
Chris Wilsonc3440442016-06-18 00:42:19 +01001/*
2 * Copyright © 2016 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
Chris Wilsonc3440442016-06-18 00:42:19 +010024#include "igt.h"
25#include "igt_vgem.h"
26
27#include <sys/mman.h>
28
Daniel Vetter93153992016-07-27 14:34:59 +020029/**
30 * SECTION:igt_vgem
31 * @short_description: VGEM support library
32 * @title: VGEM
33 * @include: igt.h
34 *
35 * This library provides various auxiliary helper functions for writing VGEM
36 * tests. VGEM is especially useful as a virtual dma-buf import and exporter and
37 * for testing cross driver synchronization (either using epxlicit dma-fences or
38 * using implicit fences attached to dma-bufs).
39 */
40
Chris Wilsonc3440442016-06-18 00:42:19 +010041int __vgem_create(int fd, struct vgem_bo *bo)
42{
43 struct drm_mode_create_dumb arg;
44
45 memset(&arg, 0, sizeof(arg));
46 arg.width = bo->width;
47 arg.height = bo->height;
48 arg.bpp = bo->bpp;
49
50 if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &arg))
51 return -errno;
52
53 bo->handle = arg.handle;
54 bo->pitch = arg.pitch;
55 bo->size = arg.size;
56
57 return 0;
58}
59
60void vgem_create(int fd, struct vgem_bo *bo)
61{
62 igt_assert_eq(__vgem_create(fd, bo), 0);
63}
64
65void *__vgem_mmap(int fd, struct vgem_bo *bo, unsigned prot)
66{
67 struct drm_mode_map_dumb arg;
68 void *ptr;
69
70 memset(&arg, 0, sizeof(arg));
71 arg.handle = bo->handle;
72 if (drmIoctl(fd, DRM_IOCTL_MODE_MAP_DUMB, &arg))
73 return NULL;
74
75 ptr = mmap64(0, bo->size, prot, MAP_SHARED, fd, arg.offset);
76 if (ptr == MAP_FAILED)
77 return NULL;
78
79 return ptr;
80}
81
82void *vgem_mmap(int fd, struct vgem_bo *bo, unsigned prot)
83{
84 void *ptr;
85
86 igt_assert_f((ptr = __vgem_mmap(fd, bo, prot)),
87 "vgem_map(fd=%d, bo->handle=%d, prot=%x)\n",
88 fd, bo->handle, prot);
89
90 return ptr;
91}
92
Chris Wilson93256e32016-06-22 07:21:09 +010093#define LOCAL_VGEM_FENCE_ATTACH 0x1
94#define LOCAL_VGEM_FENCE_SIGNAL 0x2
95
96#define LOCAL_IOCTL_VGEM_FENCE_ATTACH DRM_IOWR( DRM_COMMAND_BASE + LOCAL_VGEM_FENCE_ATTACH, struct local_vgem_fence_attach)
97#define LOCAL_IOCTL_VGEM_FENCE_SIGNAL DRM_IOW( DRM_COMMAND_BASE + LOCAL_VGEM_FENCE_SIGNAL, struct local_vgem_fence_signal)
98
99struct local_vgem_fence_attach {
100 uint32_t handle;
101 uint32_t flags;
Chris Wilson93256e32016-06-22 07:21:09 +0100102 uint32_t out_fence;
103 uint32_t pad;
104};
105
106struct local_vgem_fence_signal {
107 uint32_t fence;
108 uint32_t flags;
109};
110
111bool vgem_has_fences(int fd)
112{
113 struct local_vgem_fence_signal arg;
114 int err;
115
116 err = 0;
117 memset(&arg, 0, sizeof(arg));
118 if (drmIoctl(fd, LOCAL_IOCTL_VGEM_FENCE_SIGNAL, &arg))
119 err = -errno;
120 errno = 0;
121 return err == -ENOENT;
122}
123
124static int __vgem_fence_attach(int fd, struct local_vgem_fence_attach *arg)
125{
126 int err = 0;
127 if (igt_ioctl(fd, LOCAL_IOCTL_VGEM_FENCE_ATTACH, arg))
128 err = -errno;
129 errno = 0;
130 return err;
131}
132
Chris Wilsonc8ab5772016-07-15 09:01:59 +0100133bool vgem_fence_has_flag(int fd, unsigned flags)
134{
135 struct local_vgem_fence_attach arg;
136 struct vgem_bo bo;
137 bool ret = false;
138
139 memset(&bo, 0, sizeof(bo));
140 bo.width = 1;
141 bo.height = 1;
142 bo.bpp = 32;
143 vgem_create(fd, &bo);
144
145 memset(&arg, 0, sizeof(arg));
146 arg.handle = bo.handle;
147 arg.flags = flags;
148 if (__vgem_fence_attach(fd, &arg) == 0) {
149 vgem_fence_signal(fd, arg.out_fence);
150 ret = true;
151 }
152 gem_close(fd, bo.handle);
153
154 return ret;
155}
156
157uint32_t vgem_fence_attach(int fd, struct vgem_bo *bo, unsigned flags)
Chris Wilson93256e32016-06-22 07:21:09 +0100158{
159 struct local_vgem_fence_attach arg;
160
161 memset(&arg, 0, sizeof(arg));
162 arg.handle = bo->handle;
Chris Wilsonc8ab5772016-07-15 09:01:59 +0100163 arg.flags = flags;
Chris Wilson93256e32016-06-22 07:21:09 +0100164 igt_assert_eq(__vgem_fence_attach(fd, &arg), 0);
165 return arg.out_fence;
166}
167
Chris Wilson3d8f55c2016-07-18 10:04:51 +0100168static int ioctl_vgem_fence_signal(int fd, struct local_vgem_fence_signal *arg)
Chris Wilson93256e32016-06-22 07:21:09 +0100169{
170 int err = 0;
171 if (igt_ioctl(fd, LOCAL_IOCTL_VGEM_FENCE_SIGNAL, arg))
172 err = -errno;
173 errno = 0;
174 return err;
175}
176
Chris Wilson3d8f55c2016-07-18 10:04:51 +0100177int __vgem_fence_signal(int fd, uint32_t fence)
Chris Wilson93256e32016-06-22 07:21:09 +0100178{
179 struct local_vgem_fence_signal arg;
180
181 memset(&arg, 0, sizeof(arg));
182 arg.fence = fence;
Chris Wilson3d8f55c2016-07-18 10:04:51 +0100183
184 return ioctl_vgem_fence_signal(fd, &arg);
185}
186
187void vgem_fence_signal(int fd, uint32_t fence)
188{
189 igt_assert_eq(__vgem_fence_signal(fd, fence), 0);
Chris Wilson93256e32016-06-22 07:21:09 +0100190}