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.
35 struct drm_tegra_mapping
*map
;
36 struct drm_tegra_bo
*bo
;
40 struct drm_tegra_mapping
*map
;
41 struct drm_tegra_bo
*bo
;
45 struct drm_tegra_mapping
*map
;
46 struct drm_tegra_bo
*bo
;
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
)
56 struct vic30
*vic
= container_of(v
, struct vic30
, base
);
60 err
= drm_tegra_bo_map(vic
->config
.bo
, (void **)&c
);
62 fprintf(stderr
, "failed to map configuration structure: %s\n",
67 memset(c
, 0, sizeof(*c
));
69 c
->surfaceList0Struct
.TargetRectLeft
= left
;
70 c
->surfaceList0Struct
.TargetRectTop
= top
;
71 c
->surfaceList0Struct
.TargetRectRight
= right
;
72 c
->surfaceList0Struct
.TargetRectBottom
= bottom
;
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;
92 c
->fetchControl0Struct
.TargetRectLeft
= left
;
93 c
->fetchControl0Struct
.TargetRectTop
= top
;
94 c
->fetchControl0Struct
.TargetRectRight
= right
;
95 c
->fetchControl0Struct
.TargetRectBottom
= bottom
;
97 drm_tegra_bo_unmap(vic
->config
.bo
);
102 static int vic30_blit(struct vic
*v
, struct vic_image
*output
,
103 struct vic_image
*input
)
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
;
115 err
= drm_tegra_bo_map(vic
->config
.bo
, (void **)&c
);
117 fprintf(stderr
, "failed to map configuration structure: %s\n",
122 memset(c
, 0, sizeof(*c
));
124 c
->surfaceList0Struct
.TargetRectLeft
= 0;
125 c
->surfaceList0Struct
.TargetRectTop
= 0;
126 c
->surfaceList0Struct
.TargetRectRight
= output
->width
- 1;
127 c
->surfaceList0Struct
.TargetRectBottom
= output
->height
- 1;
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;
147 c
->fetchControl0Struct
.TargetRectLeft
= 0;
148 c
->fetchControl0Struct
.TargetRectTop
= 0;
149 c
->fetchControl0Struct
.TargetRectRight
= output
->width
- 1;
150 c
->fetchControl0Struct
.TargetRectBottom
= output
->height
- 1;
152 /* setup fetch parameters for slot 0 */
153 c
->fetchControl0Struct
.Enable0
= 0x1;
154 c
->fetchControl0Struct
.Iir0
= 0x300;
156 /* setup cache parameters for slot 0 */
157 sc
= &c
->surfaceCache0Struct
;
158 sc
->PixelFormat0
= input
->format
;
160 /* setup surface configuration for slot 0 */
161 s
= &c
->surfaceListSurfaceStruct
[0];
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
;
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;
183 /* setup color conversion for slot 0 */
184 ccla
= &c
->colorConversionLumaAlphaStruct
[0];
185 ccla
->PlanarAlpha
= 1023;
186 ccla
->ConstantAlpha
= 0;
188 ccm
= &c
->colorConversionMatrixStruct
[0];
193 ccc
= &c
->colorConversionClampStruct
[0];
197 /* setup blending for slot 0 */
198 b
= &c
->blendingSurfaceStruct
[0];
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
;
205 drm_tegra_bo_unmap(vic
->config
.bo
);
210 static int vic30_flip(struct vic
*v
, struct vic_image
*output
,
211 struct vic_image
*input
)
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
;
223 err
= drm_tegra_bo_map(vic
->config
.bo
, (void **)&c
);
225 fprintf(stderr
, "failed to map configuration structure: %s\n",
230 memset(c
, 0, sizeof(*c
));
232 c
->surfaceList0Struct
.TargetRectLeft
= 0;
233 c
->surfaceList0Struct
.TargetRectTop
= 0;
234 c
->surfaceList0Struct
.TargetRectRight
= output
->width
- 1;
235 c
->surfaceList0Struct
.TargetRectBottom
= output
->height
- 1;
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;
256 c
->fetchControl0Struct
.TargetRectLeft
= 0;
257 c
->fetchControl0Struct
.TargetRectTop
= 0;
258 c
->fetchControl0Struct
.TargetRectRight
= output
->width
- 1;
259 c
->fetchControl0Struct
.TargetRectBottom
= output
->height
- 1;
261 /* setup fetch parameters for slot 0 */
262 c
->fetchControl0Struct
.Enable0
= 0x1;
263 c
->fetchControl0Struct
.Iir0
= 0x300;
265 /* setup cache parameters for slot 0 */
266 sc
= &c
->surfaceCache0Struct
;
267 sc
->PixelFormat0
= input
->format
;
269 /* setup surface configuration for slot 0 */
270 s
= &c
->surfaceListSurfaceStruct
[0];
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
;
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;
292 /* setup color conversion for slot 0 */
293 ccla
= &c
->colorConversionLumaAlphaStruct
[0];
294 ccla
->PlanarAlpha
= 1023;
295 ccla
->ConstantAlpha
= 0;
297 ccm
= &c
->colorConversionMatrixStruct
[0];
302 ccc
= &c
->colorConversionClampStruct
[0];
306 /* setup blending for slot 0 */
307 b
= &c
->blendingSurfaceStruct
[0];
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
;
314 drm_tegra_bo_unmap(vic
->config
.bo
);
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
)
323 struct vic30
*vic
= container_of(v
, struct vic30
, base
);
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);
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);
338 VIC_PUSH_METHOD(pushbuf
, ptrp
, NVA0B6_VIDEO_COMPOSITOR_EXECUTE
, 1 << 8);
343 static void vic30_free(struct vic
*v
)
345 struct vic30
*vic
= container_of(v
, struct vic30
, base
);
347 drm_tegra_channel_unmap(vic
->hist
.map
);
348 drm_tegra_bo_unref(vic
->hist
.bo
);
350 drm_tegra_channel_unmap(vic
->filter
.map
);
351 drm_tegra_bo_unref(vic
->filter
.bo
);
353 drm_tegra_channel_unmap(vic
->config
.map
);
354 drm_tegra_bo_unref(vic
->config
.bo
);
356 drm_tegra_syncpoint_free(v
->syncpt
);
361 static const struct vic_ops vic30_ops
= {
365 .execute
= vic30_execute
,
369 int vic30_new(struct drm_tegra
*drm
, struct drm_tegra_channel
*channel
,
376 vic
= calloc(1, sizeof(*vic
));
381 vic
->base
.channel
= channel
;
382 vic
->base
.ops
= &vic30_ops
;
383 vic
->base
.version
= 0x40;
385 err
= drm_tegra_syncpoint_new(drm
, &vic
->base
.syncpt
);
387 fprintf(stderr
, "failed to allocate syncpoint: %s\n", strerror(-err
));
391 err
= drm_tegra_bo_new(drm
, 0, 16384, &vic
->config
.bo
);
393 fprintf(stderr
, "failed to allocate configuration structure: %s\n",
398 err
= drm_tegra_channel_map(channel
, vic
->config
.bo
, DRM_TEGRA_CHANNEL_MAP_READ
,
401 fprintf(stderr
, "failed to map configuration structure: %s\n",
406 err
= drm_tegra_bo_new(drm
, 0, 16384, &vic
->filter
.bo
);
408 fprintf(stderr
, "failed to allocate filter buffer: %s\n",
413 err
= drm_tegra_bo_map(vic
->filter
.bo
, &ptr
);
415 fprintf(stderr
, "failed to map filter buffer: %s\n", strerror(-err
));
419 memset(ptr
, 0, 16384);
420 drm_tegra_bo_unmap(vic
->filter
.bo
);
422 err
= drm_tegra_channel_map(channel
, vic
->filter
.bo
, DRM_TEGRA_CHANNEL_MAP_READ
,
425 fprintf(stderr
, "failed to map filter buffer: %s\n",
430 err
= drm_tegra_bo_new(drm
, 0, 4096, &vic
->hist
.bo
);
432 fprintf(stderr
, "failed to allocate history buffer: %s\n",
437 err
= drm_tegra_bo_map(vic
->hist
.bo
, &ptr
);
439 fprintf(stderr
, "failed to map history buffer: %s\n", strerror(-err
));
443 memset(ptr
, 0, 4096);
444 drm_tegra_bo_unmap(vic
->hist
.bo
);
446 err
= drm_tegra_channel_map(channel
, vic
->hist
.bo
, DRM_TEGRA_CHANNEL_MAP_READ_WRITE
,
449 fprintf(stderr
, "failed to map histogram buffer: %s\n",