xref: /aosp_15_r20/external/libdrm/tests/tegra/vic.c (revision 7688df22e49036ff52a766b7101da3a49edadb8c)
1*7688df22SAndroid Build Coastguard Worker /*
2*7688df22SAndroid Build Coastguard Worker  * Copyright © 2018 NVIDIA Corporation
3*7688df22SAndroid Build Coastguard Worker  *
4*7688df22SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*7688df22SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*7688df22SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*7688df22SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*7688df22SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*7688df22SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*7688df22SAndroid Build Coastguard Worker  *
11*7688df22SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
12*7688df22SAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
13*7688df22SAndroid Build Coastguard Worker  *
14*7688df22SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*7688df22SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*7688df22SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*7688df22SAndroid Build Coastguard Worker  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*7688df22SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*7688df22SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*7688df22SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
21*7688df22SAndroid Build Coastguard Worker  */
22*7688df22SAndroid Build Coastguard Worker 
23*7688df22SAndroid Build Coastguard Worker #include <errno.h>
24*7688df22SAndroid Build Coastguard Worker #include <stdio.h> /* XXX remove */
25*7688df22SAndroid Build Coastguard Worker #include <stdlib.h>
26*7688df22SAndroid Build Coastguard Worker 
27*7688df22SAndroid Build Coastguard Worker #include "util_math.h"
28*7688df22SAndroid Build Coastguard Worker 
29*7688df22SAndroid Build Coastguard Worker #include "tegra.h"
30*7688df22SAndroid Build Coastguard Worker #include "host1x.h"
31*7688df22SAndroid Build Coastguard Worker #include "vic.h"
32*7688df22SAndroid Build Coastguard Worker 
33*7688df22SAndroid Build Coastguard Worker #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
34*7688df22SAndroid Build Coastguard Worker 
vic_format_get_info(unsigned int format)35*7688df22SAndroid Build Coastguard Worker const struct vic_format_info *vic_format_get_info(unsigned int format)
36*7688df22SAndroid Build Coastguard Worker {
37*7688df22SAndroid Build Coastguard Worker     static const struct vic_format_info formats[] = {
38*7688df22SAndroid Build Coastguard Worker         { .format = VIC_PIXEL_FORMAT_A8R8G8B8, .cpp = 4 },
39*7688df22SAndroid Build Coastguard Worker     };
40*7688df22SAndroid Build Coastguard Worker     unsigned int i;
41*7688df22SAndroid Build Coastguard Worker 
42*7688df22SAndroid Build Coastguard Worker     for (i = 0; i < ARRAY_SIZE(formats); i++) {
43*7688df22SAndroid Build Coastguard Worker         if (formats[i].format == format)
44*7688df22SAndroid Build Coastguard Worker             return &formats[i];
45*7688df22SAndroid Build Coastguard Worker     }
46*7688df22SAndroid Build Coastguard Worker 
47*7688df22SAndroid Build Coastguard Worker     return 0;
48*7688df22SAndroid Build Coastguard Worker }
49*7688df22SAndroid Build Coastguard Worker 
vic_image_new(struct vic * vic,unsigned int width,unsigned int height,unsigned int format,unsigned int kind,uint32_t flags,struct vic_image ** imagep)50*7688df22SAndroid Build Coastguard Worker int vic_image_new(struct vic *vic, unsigned int width, unsigned int height,
51*7688df22SAndroid Build Coastguard Worker                   unsigned int format, unsigned int kind, uint32_t flags,
52*7688df22SAndroid Build Coastguard Worker                   struct vic_image **imagep)
53*7688df22SAndroid Build Coastguard Worker {
54*7688df22SAndroid Build Coastguard Worker     const struct vic_format_info *info = vic_format_get_info(format);
55*7688df22SAndroid Build Coastguard Worker     struct vic_image *image;
56*7688df22SAndroid Build Coastguard Worker     int err;
57*7688df22SAndroid Build Coastguard Worker 
58*7688df22SAndroid Build Coastguard Worker     if (!info)
59*7688df22SAndroid Build Coastguard Worker         return -EINVAL;
60*7688df22SAndroid Build Coastguard Worker 
61*7688df22SAndroid Build Coastguard Worker     image = calloc(1, sizeof(*image));
62*7688df22SAndroid Build Coastguard Worker     if (!image)
63*7688df22SAndroid Build Coastguard Worker         return -ENOMEM;
64*7688df22SAndroid Build Coastguard Worker 
65*7688df22SAndroid Build Coastguard Worker     if (kind == VIC_BLK_KIND_PITCH)
66*7688df22SAndroid Build Coastguard Worker         image->align = 256;
67*7688df22SAndroid Build Coastguard Worker     else
68*7688df22SAndroid Build Coastguard Worker         image->align = 256; /* XXX */
69*7688df22SAndroid Build Coastguard Worker 
70*7688df22SAndroid Build Coastguard Worker     image->width = width;
71*7688df22SAndroid Build Coastguard Worker     image->stride = ALIGN(width, image->align);
72*7688df22SAndroid Build Coastguard Worker     image->pitch = image->stride * info->cpp;
73*7688df22SAndroid Build Coastguard Worker     image->height = height;
74*7688df22SAndroid Build Coastguard Worker     image->format = format;
75*7688df22SAndroid Build Coastguard Worker     image->kind = kind;
76*7688df22SAndroid Build Coastguard Worker 
77*7688df22SAndroid Build Coastguard Worker     image->size = image->pitch * image->height;
78*7688df22SAndroid Build Coastguard Worker 
79*7688df22SAndroid Build Coastguard Worker     printf("image: %ux%u align: %zu stride: %u pitch: %u size: %zu\n",
80*7688df22SAndroid Build Coastguard Worker            image->width, image->height, image->align, image->stride,
81*7688df22SAndroid Build Coastguard Worker            image->pitch, image->size);
82*7688df22SAndroid Build Coastguard Worker 
83*7688df22SAndroid Build Coastguard Worker     err = drm_tegra_bo_new(vic->drm, 0, image->size, &image->bo);
84*7688df22SAndroid Build Coastguard Worker     if (err < 0) {
85*7688df22SAndroid Build Coastguard Worker         free(image);
86*7688df22SAndroid Build Coastguard Worker         return err;
87*7688df22SAndroid Build Coastguard Worker     }
88*7688df22SAndroid Build Coastguard Worker 
89*7688df22SAndroid Build Coastguard Worker     err = drm_tegra_channel_map(vic->channel, image->bo, flags, &image->map);
90*7688df22SAndroid Build Coastguard Worker     if (err < 0) {
91*7688df22SAndroid Build Coastguard Worker         drm_tegra_bo_unref(image->bo);
92*7688df22SAndroid Build Coastguard Worker         free(image);
93*7688df22SAndroid Build Coastguard Worker         return err;
94*7688df22SAndroid Build Coastguard Worker     }
95*7688df22SAndroid Build Coastguard Worker 
96*7688df22SAndroid Build Coastguard Worker     *imagep = image;
97*7688df22SAndroid Build Coastguard Worker     return 0;
98*7688df22SAndroid Build Coastguard Worker }
99*7688df22SAndroid Build Coastguard Worker 
vic_image_free(struct vic_image * image)100*7688df22SAndroid Build Coastguard Worker void vic_image_free(struct vic_image *image)
101*7688df22SAndroid Build Coastguard Worker {
102*7688df22SAndroid Build Coastguard Worker     if (image) {
103*7688df22SAndroid Build Coastguard Worker         drm_tegra_channel_unmap(image->map);
104*7688df22SAndroid Build Coastguard Worker         drm_tegra_bo_unref(image->bo);
105*7688df22SAndroid Build Coastguard Worker         free(image);
106*7688df22SAndroid Build Coastguard Worker     }
107*7688df22SAndroid Build Coastguard Worker }
108*7688df22SAndroid Build Coastguard Worker 
vic_image_dump(struct vic_image * image,FILE * fp)109*7688df22SAndroid Build Coastguard Worker void vic_image_dump(struct vic_image *image, FILE *fp)
110*7688df22SAndroid Build Coastguard Worker {
111*7688df22SAndroid Build Coastguard Worker     unsigned int i, j;
112*7688df22SAndroid Build Coastguard Worker     void *ptr;
113*7688df22SAndroid Build Coastguard Worker     int err;
114*7688df22SAndroid Build Coastguard Worker 
115*7688df22SAndroid Build Coastguard Worker     err = drm_tegra_bo_map(image->bo, &ptr);
116*7688df22SAndroid Build Coastguard Worker     if (err < 0)
117*7688df22SAndroid Build Coastguard Worker         return;
118*7688df22SAndroid Build Coastguard Worker 
119*7688df22SAndroid Build Coastguard Worker     for (j = 0; j < image->height; j++) {
120*7688df22SAndroid Build Coastguard Worker         uint32_t *pixels = (uint32_t *)((unsigned long)ptr + j * image->pitch);
121*7688df22SAndroid Build Coastguard Worker 
122*7688df22SAndroid Build Coastguard Worker         printf("   ");
123*7688df22SAndroid Build Coastguard Worker 
124*7688df22SAndroid Build Coastguard Worker         for (i = 0; i < image->width; i++)
125*7688df22SAndroid Build Coastguard Worker             printf(" %08x", pixels[i]);
126*7688df22SAndroid Build Coastguard Worker 
127*7688df22SAndroid Build Coastguard Worker         printf("\n");
128*7688df22SAndroid Build Coastguard Worker     }
129*7688df22SAndroid Build Coastguard Worker 
130*7688df22SAndroid Build Coastguard Worker     drm_tegra_bo_unmap(image->bo);
131*7688df22SAndroid Build Coastguard Worker }
132*7688df22SAndroid Build Coastguard Worker 
133*7688df22SAndroid Build Coastguard Worker /* from vic30.c */
134*7688df22SAndroid Build Coastguard Worker int vic30_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
135*7688df22SAndroid Build Coastguard Worker               struct vic **vicp);
136*7688df22SAndroid Build Coastguard Worker 
137*7688df22SAndroid Build Coastguard Worker /* from vic40.c */
138*7688df22SAndroid Build Coastguard Worker int vic40_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
139*7688df22SAndroid Build Coastguard Worker               struct vic **vicp);
140*7688df22SAndroid Build Coastguard Worker 
141*7688df22SAndroid Build Coastguard Worker /* from vic41.c */
142*7688df22SAndroid Build Coastguard Worker int vic41_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
143*7688df22SAndroid Build Coastguard Worker               struct vic **vicp);
144*7688df22SAndroid Build Coastguard Worker 
145*7688df22SAndroid Build Coastguard Worker /* from vic42.c */
146*7688df22SAndroid Build Coastguard Worker int vic42_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
147*7688df22SAndroid Build Coastguard Worker               struct vic **vicp);
148*7688df22SAndroid Build Coastguard Worker 
vic_new(struct drm_tegra * drm,struct drm_tegra_channel * channel,struct vic ** vicp)149*7688df22SAndroid Build Coastguard Worker int vic_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
150*7688df22SAndroid Build Coastguard Worker             struct vic **vicp)
151*7688df22SAndroid Build Coastguard Worker {
152*7688df22SAndroid Build Coastguard Worker     unsigned int version;
153*7688df22SAndroid Build Coastguard Worker 
154*7688df22SAndroid Build Coastguard Worker     version = drm_tegra_channel_get_version(channel);
155*7688df22SAndroid Build Coastguard Worker 
156*7688df22SAndroid Build Coastguard Worker     switch (version) {
157*7688df22SAndroid Build Coastguard Worker     case 0x40:
158*7688df22SAndroid Build Coastguard Worker         return vic30_new(drm, channel, vicp);
159*7688df22SAndroid Build Coastguard Worker 
160*7688df22SAndroid Build Coastguard Worker     case 0x21:
161*7688df22SAndroid Build Coastguard Worker         return vic40_new(drm, channel, vicp);
162*7688df22SAndroid Build Coastguard Worker 
163*7688df22SAndroid Build Coastguard Worker     case 0x18:
164*7688df22SAndroid Build Coastguard Worker         return vic41_new(drm, channel, vicp);
165*7688df22SAndroid Build Coastguard Worker 
166*7688df22SAndroid Build Coastguard Worker     case 0x19:
167*7688df22SAndroid Build Coastguard Worker         return vic42_new(drm, channel, vicp);
168*7688df22SAndroid Build Coastguard Worker     }
169*7688df22SAndroid Build Coastguard Worker 
170*7688df22SAndroid Build Coastguard Worker     return -ENOTSUP;
171*7688df22SAndroid Build Coastguard Worker }
172*7688df22SAndroid Build Coastguard Worker 
vic_free(struct vic * vic)173*7688df22SAndroid Build Coastguard Worker void vic_free(struct vic *vic)
174*7688df22SAndroid Build Coastguard Worker {
175*7688df22SAndroid Build Coastguard Worker     if (vic)
176*7688df22SAndroid Build Coastguard Worker         vic->ops->free(vic);
177*7688df22SAndroid Build Coastguard Worker }
178*7688df22SAndroid Build Coastguard Worker 
vic_clear(struct vic * vic,struct vic_image * output,unsigned int alpha,unsigned int red,unsigned int green,unsigned int blue)179*7688df22SAndroid Build Coastguard Worker int vic_clear(struct vic *vic, struct vic_image *output, unsigned int alpha,
180*7688df22SAndroid Build Coastguard Worker               unsigned int red, unsigned int green, unsigned int blue)
181*7688df22SAndroid Build Coastguard Worker {
182*7688df22SAndroid Build Coastguard Worker     return vic->ops->fill(vic, output, 0, 0, output->width - 1,
183*7688df22SAndroid Build Coastguard Worker                           output->height - 1, alpha, red, green, blue);
184*7688df22SAndroid Build Coastguard Worker }
185