modetest: switch usage to proper options grammar
[drm/libdrm.git] / tests / tegra / vic-blit.c
blob7baf9e7a0cc19786ff0ec744f41e16b84d64ccdf
1 /*
2 * Copyright © 2018 NVIDIA Corporation
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <unistd.h>
29 #include "tegra.h"
31 #include "host1x.h"
32 #include "vic.h"
34 /* clear output image to red */
35 static int clear(struct vic *vic, struct drm_tegra_channel *channel,
36 struct vic_image *output)
38 struct drm_tegra_pushbuf *pushbuf;
39 struct drm_tegra_job *job;
40 uint32_t *ptr;
41 int err;
43 err = drm_tegra_job_new(channel, &job);
44 if (err < 0) {
45 fprintf(stderr, "failed to create job: %s\n", strerror(-err));
46 return 1;
49 err = drm_tegra_job_get_pushbuf(job, &pushbuf);
50 if (err < 0) {
51 fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
52 return 1;
55 err = vic_clear(vic, output, 1023, 1023, 0, 0);
56 if (err < 0) {
57 fprintf(stderr, "failed to clear surface: %s\n", strerror(-err));
58 return err;
61 err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr);
62 if (err < 0) {
63 fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
64 return err;
67 err = vic->ops->execute(vic, pushbuf, &ptr, output, NULL, 0);
68 if (err < 0) {
69 fprintf(stderr, "failed to execute operation: %s\n", strerror(-err));
70 return err;
73 err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt,
74 DRM_TEGRA_SYNC_COND_OP_DONE);
75 if (err < 0) {
76 fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
77 return err;
80 err = drm_tegra_pushbuf_end(pushbuf, ptr);
81 if (err < 0) {
82 fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err));
83 return err;
86 err = drm_tegra_job_submit(job, NULL);
87 if (err < 0) {
88 fprintf(stderr, "failed to submit job: %s\n", strerror(-err));
89 return err;
92 err = drm_tegra_job_wait(job, 1000000000);
93 if (err < 0) {
94 fprintf(stderr, "failed to wait for job: %s\n", strerror(-err));
95 return err;
98 drm_tegra_job_free(job);
100 return 0;
103 /* fill bottom half of image to blue */
104 static int fill(struct vic *vic, struct drm_tegra_channel *channel,
105 struct vic_image *output)
107 struct drm_tegra_pushbuf *pushbuf;
108 struct drm_tegra_job *job;
109 uint32_t *ptr;
110 int err;
112 err = drm_tegra_job_new(channel, &job);
113 if (err < 0) {
114 fprintf(stderr, "failed to create job: %s\n", strerror(-err));
115 return 1;
118 err = drm_tegra_job_get_pushbuf(job, &pushbuf);
119 if (err < 0) {
120 fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
121 return 1;
124 err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr);
125 if (err < 0) {
126 fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
127 return err;
130 err = vic->ops->fill(vic, output, 0, output->height / 2, output->width - 1,
131 output->height -1, 1023, 0, 0, 1023);
132 if (err < 0) {
133 fprintf(stderr, "failed to fill surface: %s\n", strerror(-err));
134 return err;
137 err = vic->ops->execute(vic, pushbuf, &ptr, output, NULL, 0);
138 if (err < 0) {
139 fprintf(stderr, "failed to execute operation: %s\n", strerror(-err));
140 return err;
143 err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt,
144 DRM_TEGRA_SYNC_COND_OP_DONE);
145 if (err < 0) {
146 fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
147 return err;
150 err = drm_tegra_pushbuf_end(pushbuf, ptr);
151 if (err < 0) {
152 fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err));
153 return err;
156 err = drm_tegra_job_submit(job, NULL);
157 if (err < 0) {
158 fprintf(stderr, "failed to submit job: %s\n", strerror(-err));
159 return err;
162 err = drm_tegra_job_wait(job, 1000000000);
163 if (err < 0) {
164 fprintf(stderr, "failed to wait for job: %s\n", strerror(-err));
165 return err;
168 drm_tegra_job_free(job);
170 return 0;
173 /* blit image */
174 static int blit(struct vic *vic, struct drm_tegra_channel *channel,
175 struct vic_image *output, struct vic_image *input)
177 struct drm_tegra_pushbuf *pushbuf;
178 struct drm_tegra_job *job;
179 uint32_t *ptr;
180 int err;
182 err = drm_tegra_job_new(channel, &job);
183 if (err < 0) {
184 fprintf(stderr, "failed to create job: %s\n", strerror(-err));
185 return 1;
188 err = drm_tegra_job_get_pushbuf(job, &pushbuf);
189 if (err < 0) {
190 fprintf(stderr, "failed to create push buffer: %s\n", strerror(-err));
191 return 1;
194 err = drm_tegra_pushbuf_begin(pushbuf, 32, &ptr);
195 if (err < 0) {
196 fprintf(stderr, "failed to prepare push buffer: %s\n", strerror(-err));
197 return err;
200 err = vic->ops->blit(vic, output, input);
201 if (err < 0) {
202 fprintf(stderr, "failed to blit surface: %s\n", strerror(-err));
203 return err;
206 err = vic->ops->execute(vic, pushbuf, &ptr, output, &input, 1);
207 if (err < 0) {
208 fprintf(stderr, "failed to execute operation: %s\n", strerror(-err));
209 return err;
212 err = drm_tegra_pushbuf_sync_cond(pushbuf, &ptr, vic->syncpt,
213 DRM_TEGRA_SYNC_COND_OP_DONE);
214 if (err < 0) {
215 fprintf(stderr, "failed to push syncpoint: %s\n", strerror(-err));
216 return err;
219 err = drm_tegra_pushbuf_end(pushbuf, ptr);
220 if (err < 0) {
221 fprintf(stderr, "failed to update push buffer: %s\n", strerror(-err));
222 return err;
225 err = drm_tegra_job_submit(job, NULL);
226 if (err < 0) {
227 fprintf(stderr, "failed to submit job: %s\n", strerror(-err));
228 return err;
231 err = drm_tegra_job_wait(job, 1000000000);
232 if (err < 0) {
233 fprintf(stderr, "failed to wait for job: %s\n", strerror(-err));
234 return err;
237 drm_tegra_job_free(job);
239 return 0;
242 int main(int argc, char *argv[])
244 const unsigned int format = VIC_PIXEL_FORMAT_A8R8G8B8;
245 const unsigned int kind = VIC_BLK_KIND_PITCH;
246 const unsigned int width = 16, height = 16;
247 const char *device = "/dev/dri/renderD128";
248 struct drm_tegra_channel *channel;
249 struct vic_image *input, *output;
250 struct drm_tegra *drm;
251 unsigned int version;
252 struct vic *vic;
253 int fd, err;
255 if (argc > 1)
256 device = argv[1];
258 fd = open(device, O_RDWR);
259 if (fd < 0) {
260 fprintf(stderr, "open() failed: %s\n", strerror(errno));
261 return 1;
264 err = drm_tegra_new(fd, &drm);
265 if (err < 0) {
266 fprintf(stderr, "failed to open Tegra device: %s\n", strerror(-err));
267 close(fd);
268 return 1;
271 err = drm_tegra_channel_open(drm, DRM_TEGRA_VIC, &channel);
272 if (err < 0) {
273 fprintf(stderr, "failed to open channel to VIC: %s\n", strerror(-err));
274 return 1;
277 version = drm_tegra_channel_get_version(channel);
278 printf("version: %08x\n", version);
280 err = vic_new(drm, channel, &vic);
281 if (err < 0) {
282 fprintf(stderr, "failed to create VIC: %s\n", strerror(-err));
283 return 1;
286 err = vic_image_new(vic, width, height, format, kind, DRM_TEGRA_CHANNEL_MAP_READ_WRITE,
287 &input);
288 if (err < 0) {
289 fprintf(stderr, "failed to create input image: %d\n", err);
290 return 1;
293 err = vic_image_new(vic, width, height, format, kind, DRM_TEGRA_CHANNEL_MAP_READ_WRITE,
294 &output);
295 if (err < 0) {
296 fprintf(stderr, "failed to create output image: %d\n", err);
297 return 1;
300 err = clear(vic, channel, input);
301 if (err < 0) {
302 fprintf(stderr, "failed to clear image: %s\n", strerror(-err));
303 return 1;
306 err = fill(vic, channel, input);
307 if (err < 0) {
308 fprintf(stderr, "failed to fill rectangle: %s\n", strerror(-err));
309 return 1;
312 err = blit(vic, channel, output, input);
313 if (err < 0) {
314 fprintf(stderr, "failed to blit image: %s\n", strerror(-err));
315 return 1;
318 printf("input: %ux%u\n", input->width, input->height);
319 vic_image_dump(input, stdout);
321 printf("output: %ux%u\n", output->width, output->height);
322 vic_image_dump(output, stdout);
324 vic_image_free(output);
325 vic_image_free(input);
327 vic_free(vic);
328 drm_tegra_channel_close(channel);
329 drm_tegra_close(drm);
330 close(fd);
332 return 0;