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.
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
;
43 err
= drm_tegra_job_new(channel
, &job
);
45 fprintf(stderr
, "failed to create job: %s\n", strerror(-err
));
49 err
= drm_tegra_job_get_pushbuf(job
, &pushbuf
);
51 fprintf(stderr
, "failed to create push buffer: %s\n", strerror(-err
));
55 err
= vic_clear(vic
, output
, 1023, 1023, 0, 0);
57 fprintf(stderr
, "failed to clear surface: %s\n", strerror(-err
));
61 err
= drm_tegra_pushbuf_begin(pushbuf
, 32, &ptr
);
63 fprintf(stderr
, "failed to prepare push buffer: %s\n", strerror(-err
));
67 err
= vic
->ops
->execute(vic
, pushbuf
, &ptr
, output
, NULL
, 0);
69 fprintf(stderr
, "failed to execute operation: %s\n", strerror(-err
));
73 err
= drm_tegra_pushbuf_sync_cond(pushbuf
, &ptr
, vic
->syncpt
,
74 DRM_TEGRA_SYNC_COND_OP_DONE
);
76 fprintf(stderr
, "failed to push syncpoint: %s\n", strerror(-err
));
80 err
= drm_tegra_pushbuf_end(pushbuf
, ptr
);
82 fprintf(stderr
, "failed to update push buffer: %s\n", strerror(-err
));
86 err
= drm_tegra_job_submit(job
, NULL
);
88 fprintf(stderr
, "failed to submit job: %s\n", strerror(-err
));
92 err
= drm_tegra_job_wait(job
, 1000000000);
94 fprintf(stderr
, "failed to wait for job: %s\n", strerror(-err
));
98 drm_tegra_job_free(job
);
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
;
112 err
= drm_tegra_job_new(channel
, &job
);
114 fprintf(stderr
, "failed to create job: %s\n", strerror(-err
));
118 err
= drm_tegra_job_get_pushbuf(job
, &pushbuf
);
120 fprintf(stderr
, "failed to create push buffer: %s\n", strerror(-err
));
124 err
= drm_tegra_pushbuf_begin(pushbuf
, 32, &ptr
);
126 fprintf(stderr
, "failed to prepare push buffer: %s\n", strerror(-err
));
130 err
= vic
->ops
->fill(vic
, output
, 0, output
->height
/ 2, output
->width
- 1,
131 output
->height
-1, 1023, 0, 0, 1023);
133 fprintf(stderr
, "failed to fill surface: %s\n", strerror(-err
));
137 err
= vic
->ops
->execute(vic
, pushbuf
, &ptr
, output
, NULL
, 0);
139 fprintf(stderr
, "failed to execute operation: %s\n", strerror(-err
));
143 err
= drm_tegra_pushbuf_sync_cond(pushbuf
, &ptr
, vic
->syncpt
,
144 DRM_TEGRA_SYNC_COND_OP_DONE
);
146 fprintf(stderr
, "failed to push syncpoint: %s\n", strerror(-err
));
150 err
= drm_tegra_pushbuf_end(pushbuf
, ptr
);
152 fprintf(stderr
, "failed to update push buffer: %s\n", strerror(-err
));
156 err
= drm_tegra_job_submit(job
, NULL
);
158 fprintf(stderr
, "failed to submit job: %s\n", strerror(-err
));
162 err
= drm_tegra_job_wait(job
, 1000000000);
164 fprintf(stderr
, "failed to wait for job: %s\n", strerror(-err
));
168 drm_tegra_job_free(job
);
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
;
182 err
= drm_tegra_job_new(channel
, &job
);
184 fprintf(stderr
, "failed to create job: %s\n", strerror(-err
));
188 err
= drm_tegra_job_get_pushbuf(job
, &pushbuf
);
190 fprintf(stderr
, "failed to create push buffer: %s\n", strerror(-err
));
194 err
= drm_tegra_pushbuf_begin(pushbuf
, 32, &ptr
);
196 fprintf(stderr
, "failed to prepare push buffer: %s\n", strerror(-err
));
200 err
= vic
->ops
->blit(vic
, output
, input
);
202 fprintf(stderr
, "failed to blit surface: %s\n", strerror(-err
));
206 err
= vic
->ops
->execute(vic
, pushbuf
, &ptr
, output
, &input
, 1);
208 fprintf(stderr
, "failed to execute operation: %s\n", strerror(-err
));
212 err
= drm_tegra_pushbuf_sync_cond(pushbuf
, &ptr
, vic
->syncpt
,
213 DRM_TEGRA_SYNC_COND_OP_DONE
);
215 fprintf(stderr
, "failed to push syncpoint: %s\n", strerror(-err
));
219 err
= drm_tegra_pushbuf_end(pushbuf
, ptr
);
221 fprintf(stderr
, "failed to update push buffer: %s\n", strerror(-err
));
225 err
= drm_tegra_job_submit(job
, NULL
);
227 fprintf(stderr
, "failed to submit job: %s\n", strerror(-err
));
231 err
= drm_tegra_job_wait(job
, 1000000000);
233 fprintf(stderr
, "failed to wait for job: %s\n", strerror(-err
));
237 drm_tegra_job_free(job
);
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
;
258 fd
= open(device
, O_RDWR
);
260 fprintf(stderr
, "open() failed: %s\n", strerror(errno
));
264 err
= drm_tegra_new(fd
, &drm
);
266 fprintf(stderr
, "failed to open Tegra device: %s\n", strerror(-err
));
271 err
= drm_tegra_channel_open(drm
, DRM_TEGRA_VIC
, &channel
);
273 fprintf(stderr
, "failed to open channel to VIC: %s\n", strerror(-err
));
277 version
= drm_tegra_channel_get_version(channel
);
278 printf("version: %08x\n", version
);
280 err
= vic_new(drm
, channel
, &vic
);
282 fprintf(stderr
, "failed to create VIC: %s\n", strerror(-err
));
286 err
= vic_image_new(vic
, width
, height
, format
, kind
, DRM_TEGRA_CHANNEL_MAP_READ_WRITE
,
289 fprintf(stderr
, "failed to create input image: %d\n", err
);
293 err
= vic_image_new(vic
, width
, height
, format
, kind
, DRM_TEGRA_CHANNEL_MAP_READ_WRITE
,
296 fprintf(stderr
, "failed to create output image: %d\n", err
);
300 err
= clear(vic
, channel
, input
);
302 fprintf(stderr
, "failed to clear image: %s\n", strerror(-err
));
306 err
= fill(vic
, channel
, input
);
308 fprintf(stderr
, "failed to fill rectangle: %s\n", strerror(-err
));
312 err
= blit(vic
, channel
, output
, input
);
314 fprintf(stderr
, "failed to blit image: %s\n", strerror(-err
));
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
);
328 drm_tegra_channel_close(channel
);
329 drm_tegra_close(drm
);