• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2018 NVIDIA 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 shall be included in
12  * all copies or substantial portions of the Software.
13  *
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.
21  */
22 
23 #include <errno.h>
24 #include <string.h>
25 
26 #include "private.h"
27 #include "tegra.h"
28 #include "vic.h"
29 #include "vic30.h"
30 
31 struct vic30 {
32     struct vic base;
33 
34     struct {
35         struct drm_tegra_mapping *map;
36         struct drm_tegra_bo *bo;
37     } config;
38 
39     struct {
40         struct drm_tegra_mapping *map;
41         struct drm_tegra_bo *bo;
42     } filter;
43 
44     struct {
45         struct drm_tegra_mapping *map;
46         struct drm_tegra_bo *bo;
47     } hist;
48 };
49 
vic30_fill(struct vic * v,struct vic_image * output,unsigned int left,unsigned int top,unsigned int right,unsigned int bottom,unsigned int alpha,unsigned int red,unsigned int green,unsigned int blue)50 static int vic30_fill(struct vic *v, struct vic_image *output,
51                       unsigned int left, unsigned int top,
52                       unsigned int right, unsigned int bottom,
53                       unsigned int alpha, unsigned int red,
54                       unsigned int green, unsigned int blue)
55 {
56     struct vic30 *vic = container_of(v, struct vic30, base);
57     ConfigStruct *c;
58     int err;
59 
60     err = drm_tegra_bo_map(vic->config.bo, (void **)&c);
61     if (err < 0) {
62         fprintf(stderr, "failed to map configuration structure: %s\n",
63                 strerror(-err));
64         return err;
65     }
66 
67     memset(c, 0, sizeof(*c));
68 
69     c->surfaceList0Struct.TargetRectLeft = left;
70     c->surfaceList0Struct.TargetRectTop = top;
71     c->surfaceList0Struct.TargetRectRight = right;
72     c->surfaceList0Struct.TargetRectBottom = bottom;
73 
74     c->blending0Struct.PixelFormat = output->format;
75     c->blending0Struct.BackgroundAlpha = alpha;
76     c->blending0Struct.BackgroundR = red;
77     c->blending0Struct.BackgroundG = green;
78     c->blending0Struct.BackgroundB = blue;
79     c->blending0Struct.LumaWidth = output->stride - 1;
80     c->blending0Struct.LumaHeight = output->height - 1;
81     c->blending0Struct.ChromaWidth = 16383;
82     c->blending0Struct.ChromaWidth = 16383;
83     c->blending0Struct.TargetRectLeft = left;
84     c->blending0Struct.TargetRectTop = top;
85     c->blending0Struct.TargetRectRight = right;
86     c->blending0Struct.TargetRectBottom = bottom;
87     c->blending0Struct.SurfaceWidth = output->width - 1;
88     c->blending0Struct.SurfaceHeight = output->height - 1;
89     c->blending0Struct.BlkKind = output->kind;
90     c->blending0Struct.BlkHeight = 0;
91 
92     c->fetchControl0Struct.TargetRectLeft = left;
93     c->fetchControl0Struct.TargetRectTop = top;
94     c->fetchControl0Struct.TargetRectRight = right;
95     c->fetchControl0Struct.TargetRectBottom = bottom;
96 
97     drm_tegra_bo_unmap(vic->config.bo);
98 
99     return 0;
100 }
101 
vic30_blit(struct vic * v,struct vic_image * output,struct vic_image * input)102 static int vic30_blit(struct vic *v, struct vic_image *output,
103                       struct vic_image *input)
104 {
105     struct vic30 *vic = container_of(v, struct vic30, base);
106     ColorConversionLumaAlphaStruct *ccla;
107     ColorConversionMatrixStruct *ccm;
108     ColorConversionClampStruct *ccc;
109     SurfaceListSurfaceStruct *s;
110     BlendingSurfaceStruct *b;
111     SurfaceCache0Struct *sc;
112     ConfigStruct *c;
113     int err;
114 
115     err = drm_tegra_bo_map(vic->config.bo, (void **)&c);
116     if (err < 0) {
117         fprintf(stderr, "failed to map configuration structure: %s\n",
118                 strerror(-err));
119         return err;
120     }
121 
122     memset(c, 0, sizeof(*c));
123 
124     c->surfaceList0Struct.TargetRectLeft = 0;
125     c->surfaceList0Struct.TargetRectTop = 0;
126     c->surfaceList0Struct.TargetRectRight = output->width - 1;
127     c->surfaceList0Struct.TargetRectBottom = output->height - 1;
128 
129     c->blending0Struct.PixelFormat = output->format;
130     c->blending0Struct.BackgroundAlpha = 0;
131     c->blending0Struct.BackgroundR = 0;
132     c->blending0Struct.BackgroundG = 0;
133     c->blending0Struct.BackgroundB = 0;
134     c->blending0Struct.LumaWidth = output->stride - 1;
135     c->blending0Struct.LumaHeight = output->height - 1;
136     c->blending0Struct.ChromaWidth = 16383;
137     c->blending0Struct.ChromaWidth = 16383;
138     c->blending0Struct.TargetRectLeft = 0;
139     c->blending0Struct.TargetRectTop = 0;
140     c->blending0Struct.TargetRectRight = output->width - 1;
141     c->blending0Struct.TargetRectBottom = output->height - 1;
142     c->blending0Struct.SurfaceWidth = output->width - 1;
143     c->blending0Struct.SurfaceHeight = output->height - 1;
144     c->blending0Struct.BlkKind = output->kind;
145     c->blending0Struct.BlkHeight = 0;
146 
147     c->fetchControl0Struct.TargetRectLeft = 0;
148     c->fetchControl0Struct.TargetRectTop = 0;
149     c->fetchControl0Struct.TargetRectRight = output->width - 1;
150     c->fetchControl0Struct.TargetRectBottom = output->height - 1;
151 
152     /* setup fetch parameters for slot 0 */
153     c->fetchControl0Struct.Enable0 = 0x1;
154     c->fetchControl0Struct.Iir0 = 0x300;
155 
156     /* setup cache parameters for slot 0 */
157     sc = &c->surfaceCache0Struct;
158     sc->PixelFormat0 = input->format;
159 
160     /* setup surface configuration for slot 0 */
161     s = &c->surfaceListSurfaceStruct[0];
162     s->Enable = 1;
163     s->FrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
164     s->PixelFormat = input->format;
165     s->SurfaceWidth = input->width - 1;
166     s->SurfaceHeight = input->height - 1;
167     s->LumaWidth = input->stride - 1;
168     s->LumaHeight = input->height - 1;
169     s->ChromaWidth = 16383;
170     s->ChromaHeight = 16383;
171     s->CacheWidth = VIC_CACHE_WIDTH_256Bx1; //VIC_CACHE_WIDTH_16Bx16;
172     s->BlkKind = input->kind;
173     s->BlkHeight = 0;
174     s->DestRectLeft = 0;
175     s->DestRectTop = 0;
176     s->DestRectRight = output->width - 1;
177     s->DestRectBottom = output->height - 1;
178     s->SourceRectLeft = 0 << 16;
179     s->SourceRectTop = 0 << 16;
180     s->SourceRectRight = (input->width - 1) << 16;
181     s->SourceRectBottom = (input->height - 1) << 16;
182 
183     /* setup color conversion for slot 0 */
184     ccla = &c->colorConversionLumaAlphaStruct[0];
185     ccla->PlanarAlpha = 1023;
186     ccla->ConstantAlpha = 0;
187 
188     ccm = &c->colorConversionMatrixStruct[0];
189     ccm->c00 = 1023;
190     ccm->c11 = 1023;
191     ccm->c22 = 1023;
192 
193     ccc = &c->colorConversionClampStruct[0];
194     ccc->low = 0;
195     ccc->high = 1023;
196 
197     /* setup blending for slot 0 */
198     b = &c->blendingSurfaceStruct[0];
199     b->AlphaK1 = 1023;
200     b->SrcFactCMatchSelect = VIC_BLEND_SRCFACTC_K1;
201     b->SrcFactAMatchSelect = VIC_BLEND_SRCFACTA_K1;
202     b->DstFactCMatchSelect = VIC_BLEND_DSTFACTC_NEG_K1_TIMES_SRC;
203     b->DstFactAMatchSelect = VIC_BLEND_DSTFACTA_NEG_K1_TIMES_SRC;
204 
205     drm_tegra_bo_unmap(vic->config.bo);
206 
207     return 0;
208 }
209 
vic30_flip(struct vic * v,struct vic_image * output,struct vic_image * input)210 static int vic30_flip(struct vic *v, struct vic_image *output,
211                       struct vic_image *input)
212 {
213     struct vic30 *vic = container_of(v, struct vic30, base);
214     ColorConversionLumaAlphaStruct *ccla;
215     ColorConversionMatrixStruct *ccm;
216     ColorConversionClampStruct *ccc;
217     SurfaceListSurfaceStruct *s;
218     BlendingSurfaceStruct *b;
219     SurfaceCache0Struct *sc;
220     ConfigStruct *c;
221     int err;
222 
223     err = drm_tegra_bo_map(vic->config.bo, (void **)&c);
224     if (err < 0) {
225         fprintf(stderr, "failed to map configuration structure: %s\n",
226                 strerror(-err));
227         return err;
228     }
229 
230     memset(c, 0, sizeof(*c));
231 
232     c->surfaceList0Struct.TargetRectLeft = 0;
233     c->surfaceList0Struct.TargetRectTop = 0;
234     c->surfaceList0Struct.TargetRectRight = output->width - 1;
235     c->surfaceList0Struct.TargetRectBottom = output->height - 1;
236 
237     c->blending0Struct.PixelFormat = output->format;
238     c->blending0Struct.BackgroundAlpha = 0;
239     c->blending0Struct.BackgroundR = 0;
240     c->blending0Struct.BackgroundG = 0;
241     c->blending0Struct.BackgroundB = 0;
242     c->blending0Struct.LumaWidth = output->stride - 1;
243     c->blending0Struct.LumaHeight = output->height - 1;
244     c->blending0Struct.ChromaWidth = 16383;
245     c->blending0Struct.ChromaWidth = 16383;
246     c->blending0Struct.TargetRectLeft = 0;
247     c->blending0Struct.TargetRectTop = 0;
248     c->blending0Struct.TargetRectRight = output->width - 1;
249     c->blending0Struct.TargetRectBottom = output->height - 1;
250     c->blending0Struct.SurfaceWidth = output->width - 1;
251     c->blending0Struct.SurfaceHeight = output->height - 1;
252     c->blending0Struct.BlkKind = output->kind;
253     c->blending0Struct.BlkHeight = 0;
254     c->blending0Struct.OutputFlipY = 1;
255 
256     c->fetchControl0Struct.TargetRectLeft = 0;
257     c->fetchControl0Struct.TargetRectTop = 0;
258     c->fetchControl0Struct.TargetRectRight = output->width - 1;
259     c->fetchControl0Struct.TargetRectBottom = output->height - 1;
260 
261     /* setup fetch parameters for slot 0 */
262     c->fetchControl0Struct.Enable0 = 0x1;
263     c->fetchControl0Struct.Iir0 = 0x300;
264 
265     /* setup cache parameters for slot 0 */
266     sc = &c->surfaceCache0Struct;
267     sc->PixelFormat0 = input->format;
268 
269     /* setup surface configuration for slot 0 */
270     s = &c->surfaceListSurfaceStruct[0];
271     s->Enable = 1;
272     s->FrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
273     s->PixelFormat = input->format;
274     s->SurfaceWidth = input->width - 1;
275     s->SurfaceHeight = input->height - 1;
276     s->LumaWidth = input->stride - 1;
277     s->LumaHeight = input->height - 1;
278     s->ChromaWidth = 16383;
279     s->ChromaHeight = 16383;
280     s->CacheWidth = VIC_CACHE_WIDTH_256Bx1;
281     s->BlkKind = input->kind;
282     s->BlkHeight = 0;
283     s->DestRectLeft = 0;
284     s->DestRectTop = 0;
285     s->DestRectRight = output->width - 1;
286     s->DestRectBottom = output->height - 1;
287     s->SourceRectLeft = 0 << 16;
288     s->SourceRectTop = 0 << 16;
289     s->SourceRectRight = (input->width - 1) << 16;
290     s->SourceRectBottom = (input->height - 1) << 16;
291 
292     /* setup color conversion for slot 0 */
293     ccla = &c->colorConversionLumaAlphaStruct[0];
294     ccla->PlanarAlpha = 1023;
295     ccla->ConstantAlpha = 0;
296 
297     ccm = &c->colorConversionMatrixStruct[0];
298     ccm->c00 = 1023;
299     ccm->c11 = 1023;
300     ccm->c22 = 1023;
301 
302     ccc = &c->colorConversionClampStruct[0];
303     ccc->low = 0;
304     ccc->high = 1023;
305 
306     /* setup blending for slot 0 */
307     b = &c->blendingSurfaceStruct[0];
308     b->AlphaK1 = 1023;
309     b->SrcFactCMatchSelect = VIC_BLEND_SRCFACTC_K1;
310     b->SrcFactAMatchSelect = VIC_BLEND_SRCFACTA_K1;
311     b->DstFactCMatchSelect = VIC_BLEND_DSTFACTC_NEG_K1_TIMES_SRC;
312     b->DstFactAMatchSelect = VIC_BLEND_DSTFACTA_NEG_K1_TIMES_SRC;
313 
314     drm_tegra_bo_unmap(vic->config.bo);
315 
316     return 0;
317 }
318 
vic30_execute(struct vic * v,struct drm_tegra_pushbuf * pushbuf,uint32_t ** ptrp,struct vic_image * output,struct vic_image ** inputs,unsigned int num_inputs)319 static int vic30_execute(struct vic *v, struct drm_tegra_pushbuf *pushbuf,
320                          uint32_t **ptrp, struct vic_image *output,
321                          struct vic_image **inputs, unsigned int num_inputs)
322 {
323     struct vic30 *vic = container_of(v, struct vic30, base);
324     unsigned int i;
325 
326     if (num_inputs > 1)
327         return -EINVAL;
328 
329     VIC_PUSH_METHOD(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_APPLICATION_ID, 1);
330     VIC_PUSH_METHOD(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_CONTROL_PARAMS, (sizeof(ConfigStruct) / 16) << 16);
331     VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_CONFIG_STRUCT_OFFSET, vic->config.map, 0, 0);
332     VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_HIST_OFFSET, vic->hist.map, 0, 0);
333     VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_OUTPUT_SURFACE_LUMA_OFFSET, output->map, 0, 0);
334 
335     for (i = 0; i < num_inputs; i++)
336         VIC_PUSH_BUFFER(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_SET_SURFACE0_SLOT0_LUMA_OFFSET, inputs[i]->map, 0, 0);
337 
338     VIC_PUSH_METHOD(pushbuf, ptrp, NVA0B6_VIDEO_COMPOSITOR_EXECUTE, 1 << 8);
339 
340     return 0;
341 }
342 
vic30_free(struct vic * v)343 static void vic30_free(struct vic *v)
344 {
345     struct vic30 *vic = container_of(v, struct vic30, base);
346 
347     drm_tegra_channel_unmap(vic->hist.map);
348     drm_tegra_bo_unref(vic->hist.bo);
349 
350     drm_tegra_channel_unmap(vic->filter.map);
351     drm_tegra_bo_unref(vic->filter.bo);
352 
353     drm_tegra_channel_unmap(vic->config.map);
354     drm_tegra_bo_unref(vic->config.bo);
355 
356     drm_tegra_syncpoint_free(v->syncpt);
357 
358     free(vic);
359 }
360 
361 static const struct vic_ops vic30_ops = {
362     .fill = vic30_fill,
363     .blit = vic30_blit,
364     .flip = vic30_flip,
365     .execute = vic30_execute,
366     .free = vic30_free,
367 };
368 
vic30_new(struct drm_tegra * drm,struct drm_tegra_channel * channel,struct vic ** vicp)369 int vic30_new(struct drm_tegra *drm, struct drm_tegra_channel *channel,
370               struct vic **vicp)
371 {
372     struct vic30 *vic;
373     void *ptr;
374     int err;
375 
376     vic = calloc(1, sizeof(*vic));
377     if (!vic)
378         return -ENOMEM;
379 
380     vic->base.drm = drm;
381     vic->base.channel = channel;
382     vic->base.ops = &vic30_ops;
383     vic->base.version = 0x40;
384 
385     err = drm_tegra_syncpoint_new(drm, &vic->base.syncpt);
386     if (err < 0) {
387         fprintf(stderr, "failed to allocate syncpoint: %s\n", strerror(-err));
388         return err;
389     }
390 
391     err = drm_tegra_bo_new(drm, 0, 16384, &vic->config.bo);
392     if (err < 0) {
393         fprintf(stderr, "failed to allocate configuration structure: %s\n",
394                 strerror(-err));
395         return err;
396     }
397 
398     err = drm_tegra_channel_map(channel, vic->config.bo, DRM_TEGRA_CHANNEL_MAP_READ,
399                                 &vic->config.map);
400     if (err < 0) {
401         fprintf(stderr, "failed to map configuration structure: %s\n",
402                 strerror(-err));
403         return err;
404     }
405 
406     err = drm_tegra_bo_new(drm, 0, 16384, &vic->filter.bo);
407     if (err < 0) {
408         fprintf(stderr, "failed to allocate filter buffer: %s\n",
409                 strerror(-err));
410         return err;
411     }
412 
413     err = drm_tegra_bo_map(vic->filter.bo, &ptr);
414     if (err < 0) {
415         fprintf(stderr, "failed to map filter buffer: %s\n", strerror(-err));
416         return err;
417     }
418 
419     memset(ptr, 0, 16384);
420     drm_tegra_bo_unmap(vic->filter.bo);
421 
422     err = drm_tegra_channel_map(channel, vic->filter.bo, DRM_TEGRA_CHANNEL_MAP_READ,
423                                 &vic->filter.map);
424     if (err < 0) {
425         fprintf(stderr, "failed to map filter buffer: %s\n",
426                 strerror(-err));
427         return err;
428     }
429 
430     err = drm_tegra_bo_new(drm, 0, 4096, &vic->hist.bo);
431     if (err < 0) {
432         fprintf(stderr, "failed to allocate history buffer: %s\n",
433                 strerror(-err));
434         return err;
435     }
436 
437     err = drm_tegra_bo_map(vic->hist.bo, &ptr);
438     if (err < 0) {
439         fprintf(stderr, "failed to map history buffer: %s\n", strerror(-err));
440         return err;
441     }
442 
443     memset(ptr, 0, 4096);
444     drm_tegra_bo_unmap(vic->hist.bo);
445 
446     err = drm_tegra_channel_map(channel, vic->hist.bo, DRM_TEGRA_CHANNEL_MAP_READ_WRITE,
447                                 &vic->hist.map);
448     if (err < 0) {
449         fprintf(stderr, "failed to map histogram buffer: %s\n",
450                 strerror(-err));
451         return err;
452     }
453 
454     if (vicp)
455         *vicp = &vic->base;
456 
457     return 0;
458 }
459