• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2013-2014 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  * Authors:
24  *    Damien Lespiau <damien.lespiau@intel.com>
25  */
26 
27 /*
28  * This file is an "advanced" test for the render_copy() function, a very simple
29  * workload for the 3D engine. The basic test in gem_render_copy.c is intentionally
30  * kept extremely simple to allow for aub instrumentation and to ease debugging of
31  * the render copy functions themselves. This test on the overhand aims to stress
32  * the execbuffer interface with a simple render workload.
33  */
34 
35 #include "igt.h"
36 #include <stdbool.h>
37 #include <unistd.h>
38 #include <stdlib.h>
39 #include <sys/ioctl.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <fcntl.h>
43 #include <inttypes.h>
44 #include <errno.h>
45 #include <sys/stat.h>
46 #include <sys/time.h>
47 
48 #include <drm.h>
49 
50 #include "intel_bufmgr.h"
51 
52 IGT_TEST_DESCRIPTION("Advanced test for the render_copy() function.");
53 
54 #define WIDTH 512
55 #define STRIDE (WIDTH*4)
56 #define HEIGHT 512
57 #define SIZE (HEIGHT*STRIDE)
58 
59 #define SRC_COLOR	0xffff00ff
60 #define DST_COLOR	0xfff0ff00
61 
62 typedef struct {
63 	int fd;
64 	uint32_t devid;
65 	drm_intel_bufmgr *bufmgr;
66 	struct intel_batchbuffer *batch;
67 	igt_render_copyfunc_t render_copy;
68 	uint32_t linear[WIDTH * HEIGHT];
69 } data_t;
70 
data_init(data_t * data)71 static void data_init(data_t *data)
72 {
73 	data->fd = drm_open_driver(DRIVER_INTEL);
74 	data->devid = intel_get_drm_devid(data->fd);
75 
76 	data->bufmgr = drm_intel_bufmgr_gem_init(data->fd, 4096);
77 	igt_assert(data->bufmgr);
78 
79 	data->render_copy = igt_get_render_copyfunc(data->devid);
80 	igt_require_f(data->render_copy,
81 		      "no render-copy function\n");
82 
83 	data->batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);
84 	igt_assert(data->batch);
85 }
86 
data_fini(data_t * data)87 static void data_fini(data_t *data)
88 {
89 	 intel_batchbuffer_free(data->batch);
90 	 drm_intel_bufmgr_destroy(data->bufmgr);
91 	 close(data->fd);
92 }
93 
scratch_buf_init(data_t * data,struct igt_buf * buf,int width,int height,int stride,uint32_t color)94 static void scratch_buf_init(data_t *data, struct igt_buf *buf,
95 			     int width, int height, int stride, uint32_t color)
96 {
97 	drm_intel_bo *bo;
98 	int i;
99 
100 	bo = drm_intel_bo_alloc(data->bufmgr, "", SIZE, 4096);
101 	for (i = 0; i < width * height; i++)
102 		data->linear[i] = color;
103 	gem_write(data->fd, bo->handle, 0, data->linear,
104 		  sizeof(data->linear));
105 
106 	memset(buf, 0, sizeof(*buf));
107 
108 	buf->bo = bo;
109 	buf->stride = stride;
110 	buf->tiling = I915_TILING_NONE;
111 	buf->size = SIZE;
112 	buf->bpp = 32;
113 }
114 
scratch_buf_fini(data_t * data,struct igt_buf * buf)115 static void scratch_buf_fini(data_t *data, struct igt_buf *buf)
116 {
117 	dri_bo_unreference(buf->bo);
118 	memset(buf, 0, sizeof(*buf));
119 }
120 
121 static void
scratch_buf_check(data_t * data,struct igt_buf * buf,int x,int y,uint32_t color)122 scratch_buf_check(data_t *data, struct igt_buf *buf, int x, int y,
123 		  uint32_t color)
124 {
125 	uint32_t val;
126 
127 	gem_read(data->fd, buf->bo->handle, 0,
128 		 data->linear, sizeof(data->linear));
129 	val = data->linear[y * WIDTH + x];
130 	igt_assert_f(val == color,
131 		     "Expected 0x%08x, found 0x%08x at (%d,%d)\n",
132 		     color, val, x, y);
133 }
134 
copy(data_t * data)135 static void copy(data_t *data)
136 {
137 	struct igt_buf src, dst;
138 
139 	scratch_buf_init(data, &src, WIDTH, HEIGHT, STRIDE, SRC_COLOR);
140 	scratch_buf_init(data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR);
141 
142 	scratch_buf_check(data, &src, WIDTH / 2, HEIGHT / 2, SRC_COLOR);
143 	scratch_buf_check(data, &dst, WIDTH / 2, HEIGHT / 2, DST_COLOR);
144 
145 	data->render_copy(data->batch, NULL,
146 			  &src, 0, 0, WIDTH, HEIGHT,
147 			  &dst, WIDTH / 2, HEIGHT / 2);
148 
149 	scratch_buf_check(data, &dst, 10, 10, DST_COLOR);
150 	scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
151 
152 	scratch_buf_fini(data, &src);
153 	scratch_buf_fini(data, &dst);
154 }
155 
copy_flink(data_t * data)156 static void copy_flink(data_t *data)
157 {
158 	data_t local;
159 	struct igt_buf src, dst;
160 	struct igt_buf local_src, local_dst;
161 	struct igt_buf flink;
162 	uint32_t name;
163 
164 	data_init(&local);
165 
166 	scratch_buf_init(data, &src, WIDTH, HEIGHT, STRIDE, 0);
167 	scratch_buf_init(data, &dst, WIDTH, HEIGHT, STRIDE, DST_COLOR);
168 
169 	data->render_copy(data->batch, NULL,
170 			  &src, 0, 0, WIDTH, HEIGHT,
171 			  &dst, WIDTH, HEIGHT);
172 
173 	scratch_buf_init(&local, &local_src, WIDTH, HEIGHT, STRIDE, 0);
174 	scratch_buf_init(&local, &local_dst, WIDTH, HEIGHT, STRIDE, SRC_COLOR);
175 
176 	local.render_copy(local.batch, NULL,
177 			  &local_src, 0, 0, WIDTH, HEIGHT,
178 			  &local_dst, WIDTH, HEIGHT);
179 
180 
181 	drm_intel_bo_flink(local_dst.bo, &name);
182 	flink = local_dst;
183 	flink.bo = drm_intel_bo_gem_create_from_name(data->bufmgr, "flink", name);
184 
185 	data->render_copy(data->batch, NULL,
186 			  &flink, 0, 0, WIDTH, HEIGHT,
187 			  &dst, WIDTH / 2, HEIGHT / 2);
188 
189 	scratch_buf_check(data, &dst, 10, 10, DST_COLOR);
190 	scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
191 
192 	scratch_buf_check(data, &dst, 10, 10, DST_COLOR);
193 	scratch_buf_check(data, &dst, WIDTH - 10, HEIGHT - 10, SRC_COLOR);
194 
195 	scratch_buf_fini(data, &src);
196 	scratch_buf_fini(data, &flink);
197 	scratch_buf_fini(data, &dst);
198 
199 	scratch_buf_fini(&local, &local_src);
200 	scratch_buf_fini(&local, &local_dst);
201 
202 	data_fini(&local);
203 }
204 
205 igt_main
206 {
207 	data_t data = {0, };
208 
209 	igt_fixture {
210 		data_init(&data);
211 		igt_require_gem(data.fd);
212 	}
213 
214 	igt_subtest("normal") {
215 		int loop = 100;
216 		while (loop--)
217 			copy(&data);
218 	}
219 
220 	igt_subtest("interruptible") {
221 		int loop = 100;
222 		igt_fork_signal_helper();
223 		while (loop--)
224 			copy(&data);
225 		igt_stop_signal_helper();
226 	}
227 
228 	igt_subtest("flink") {
229 		int loop = 100;
230 		while (loop--)
231 			copy_flink(&data);
232 	}
233 
234 	igt_subtest("flink-interruptible") {
235 		int loop = 100;
236 		igt_fork_signal_helper();
237 		while (loop--)
238 			copy_flink(&data);
239 		igt_stop_signal_helper();
240 	}
241 }
242