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