1 /* Copyright 2022 Advanced Micro Devices, Inc.
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 * OTHER DEALINGS IN THE SOFTWARE.
20 *
21 * Authors: AMD
22 *
23 */
24
25 #include <string.h>
26 #include "vpe_types.h"
27 #include "vpe_priv.h"
28 #include "common.h"
29
vpe_find_color_space_from_table(const struct vpe_color_space * table,int table_size,const struct vpe_color_space * cs)30 bool vpe_find_color_space_from_table(
31 const struct vpe_color_space *table, int table_size, const struct vpe_color_space *cs)
32 {
33 int i;
34 for (i = 0; i < table_size; i++) {
35 if (!memcmp(table, cs, sizeof(struct vpe_color_space)))
36 return true;
37 }
38 return false;
39 }
40
vpe_is_dual_plane_format(enum vpe_surface_pixel_format format)41 bool vpe_is_dual_plane_format(enum vpe_surface_pixel_format format)
42 {
43 switch (format) {
44 // nv12/21
45 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
46 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
47 // p010
48 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
49 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
50 return true;
51 default:
52 return false;
53 }
54 }
55
vpe_is_32bit_packed_rgb(enum vpe_surface_pixel_format format)56 bool vpe_is_32bit_packed_rgb(enum vpe_surface_pixel_format format)
57 {
58 switch (format) {
59 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
60 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
61 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
62 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
63 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
64 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
65 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
66 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
67 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
68 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
69 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
70 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
71 return true;
72 default:
73 return false;
74 }
75 }
76
vpe_is_8bit(enum vpe_surface_pixel_format format)77 bool vpe_is_8bit(enum vpe_surface_pixel_format format) {
78 return vpe_is_rgb8(format) ||
79 vpe_is_yuv420_8(format) ||
80 vpe_is_yuv444_8(format);
81 }
82
vpe_is_10bit(enum vpe_surface_pixel_format format)83 bool vpe_is_10bit(enum vpe_surface_pixel_format format) {
84 return vpe_is_rgb10(format) ||
85 vpe_is_yuv420_10(format) ||
86 vpe_is_yuv444_10(format);
87 }
88
vpe_is_rgb8(enum vpe_surface_pixel_format format)89 bool vpe_is_rgb8(enum vpe_surface_pixel_format format)
90 {
91 switch (format) {
92 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
93 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
94 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
95 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
96 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
97 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
98 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
99 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
100 return true;
101 default:
102 return false;
103 }
104 }
105
vpe_is_rgb10(enum vpe_surface_pixel_format format)106 bool vpe_is_rgb10(enum vpe_surface_pixel_format format)
107 {
108 switch (format) {
109 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
110 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
111 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
112 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
113 return true;
114 default:
115 return false;
116 }
117 }
118
vpe_is_fp16(enum vpe_surface_pixel_format format)119 bool vpe_is_fp16(enum vpe_surface_pixel_format format)
120 {
121 switch (format) {
122 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
123 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
124 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
125 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
126 return true;
127 default:
128 return false;
129 }
130 }
131
vpe_is_yuv420_8(enum vpe_surface_pixel_format format)132 bool vpe_is_yuv420_8(enum vpe_surface_pixel_format format)
133 {
134 switch (format) {
135 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
136 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
137 return true;
138 default:
139 return false;
140 }
141 }
142
vpe_is_yuv420_10(enum vpe_surface_pixel_format format)143 bool vpe_is_yuv420_10(enum vpe_surface_pixel_format format)
144 {
145 switch (format) {
146 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
147 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
148 return true;
149 default:
150 return false;
151 }
152 }
vpe_is_yuv420_16(enum vpe_surface_pixel_format format)153 bool vpe_is_yuv420_16(enum vpe_surface_pixel_format format)
154 {
155 switch (format) {
156 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_16bpc_YCrCb:
157 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_16bpc_YCbCr:
158 return true;
159 default:
160 return false;
161 }
162 }
163
vpe_is_yuv420(enum vpe_surface_pixel_format format)164 bool vpe_is_yuv420(enum vpe_surface_pixel_format format)
165 {
166 return (vpe_is_yuv420_8(format) || vpe_is_yuv420_10(format) || vpe_is_yuv420_16(format));
167 }
168
vpe_is_yuv444_8(enum vpe_surface_pixel_format format)169 bool vpe_is_yuv444_8(enum vpe_surface_pixel_format format)
170 {
171 switch (format) {
172 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
173 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
174 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
175 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
176 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
177 return true;
178 default:
179 return false;
180 }
181 }
182
vpe_is_yuv444_10(enum vpe_surface_pixel_format format)183 bool vpe_is_yuv444_10(enum vpe_surface_pixel_format format)
184 {
185 switch (format) {
186 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
187 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
188 return true;
189 default:
190 return false;
191 }
192 }
vpe_is_yuv444(enum vpe_surface_pixel_format format)193 bool vpe_is_yuv444(enum vpe_surface_pixel_format format)
194 {
195 return (vpe_is_yuv444_8(format) ||
196 vpe_is_yuv444_10(format));
197 }
198
vpe_is_yuv8(enum vpe_surface_pixel_format format)199 bool vpe_is_yuv8(enum vpe_surface_pixel_format format)
200 {
201 return (vpe_is_yuv420_8(format) ||
202 vpe_is_yuv444_8(format));
203 }
204
vpe_is_yuv10(enum vpe_surface_pixel_format format)205 bool vpe_is_yuv10(enum vpe_surface_pixel_format format)
206 {
207 return (vpe_is_yuv420_10(format) ||
208 vpe_is_yuv444_10(format));
209 }
210
vpe_is_yuv(enum vpe_surface_pixel_format format)211 bool vpe_is_yuv(enum vpe_surface_pixel_format format)
212 {
213 return (vpe_is_yuv420(format) ||
214 vpe_is_yuv444(format));
215 }
216
vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format,int plane_idx)217 uint8_t vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format, int plane_idx)
218 {
219 switch (format) {
220 // nv12/21
221 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
222 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
223 if (plane_idx == 0)
224 return 1;
225 else
226 return 2;
227 // P010
228 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
229 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
230 if (plane_idx == 0)
231 return 2;
232 else
233 return 4;
234 // 64bpp
235 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
236 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
237 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
238 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
239 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
240 return 8;
241 default:
242 break;
243 }
244 // default 32bpp packed format
245 return 4;
246 }
247
vpe_get_color_depth(enum vpe_surface_pixel_format format)248 enum color_depth vpe_get_color_depth(enum vpe_surface_pixel_format format)
249 {
250 enum color_depth c_depth;
251 switch (format) {
252 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
253 c_depth = COLOR_DEPTH_666;
254 break;
255 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
256 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
257 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
258 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
259 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
260 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
261 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
262 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
263 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
264 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
265 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
266 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
267 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
268 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
269 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
270 c_depth = COLOR_DEPTH_888;
271 break;
272 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
273 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
274 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
275 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
276 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
277 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
278 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
279 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
280 c_depth = COLOR_DEPTH_101010;
281 break;
282 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
283 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
284 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
285 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
286 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
287 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_16bpc_YCrCb:
288 c_depth = COLOR_DEPTH_161616;
289 break;
290 default:
291 c_depth = COLOR_DEPTH_888;
292 }
293
294 return c_depth;
295 }
296
vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format)297 bool vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format)
298 {
299 bool alpha = true;
300
301 switch (format) {
302 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
303 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
304 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
305 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
306 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
307 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
308 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
309 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
310 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
311 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
312 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
313 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
314 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
315 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
316 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
317 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
318 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
319 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
320 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
321 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
322 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
323 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
324 alpha = true;
325 break;
326 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
327 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
328 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
329 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
330 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
331 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE:
332 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
333 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
334 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
335 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
336 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
337 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
338 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
339 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
340 default:
341 alpha = false;
342 break;
343 }
344
345 return alpha;
346 }
347
348 // Note there is another function vpe_is_hdr that performs the same function but with the translated
349 // internal VPE enums, not the api enums as done below. C does not support function overloading so
350 // another function is needed here.
is_HDR(enum vpe_transfer_function tf)351 static bool is_HDR(enum vpe_transfer_function tf)
352 {
353 return (tf == VPE_TF_PQ || tf == VPE_TF_G10 || tf == VPE_TF_HLG);
354 }
355
vpe_check_output_support(struct vpe * vpe,const struct vpe_build_param * param)356 enum vpe_status vpe_check_output_support(struct vpe *vpe, const struct vpe_build_param *param)
357 {
358 struct vpe_priv *vpe_priv = container_of(vpe, struct vpe_priv, pub);
359 struct vpec *vpec;
360 struct dpp *dpp;
361 struct cdc_be *cdc_be;
362 const struct vpe_surface_info *surface_info = ¶m->dst_surface;
363 struct vpe_dcc_surface_param params;
364 struct vpe_surface_dcc_cap cap;
365 bool support;
366
367 vpec = &vpe_priv->resource.vpec;
368 dpp = vpe_priv->resource.dpp[0];
369 cdc_be = vpe_priv->resource.cdc_be[0];
370
371 // swizzle mode
372 support = vpec->funcs->check_swmode_support(vpec, surface_info->swizzle);
373 if (!support) {
374 vpe_log("output swizzle mode not supported %d\n", surface_info->swizzle);
375 return VPE_STATUS_SWIZZLE_NOT_SUPPORTED;
376 }
377
378 // pitch
379 if ((uint32_t)(surface_info->plane_size.surface_size.x +
380 (int32_t)surface_info->plane_size.surface_size.width) >
381 surface_info->plane_size.surface_pitch) {
382 vpe_log("pitch alignment not supported %lu. %lu\n", surface_info->plane_size.surface_pitch,
383 vpe->caps->plane_caps.pitch_alignment);
384 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
385 }
386
387 // target rect shouldn't exceed width/height
388 if ((param->target_rect.x < surface_info->plane_size.surface_size.x ||
389 param->target_rect.x + (int32_t)param->target_rect.width >
390 surface_info->plane_size.surface_size.x +
391 (int32_t)surface_info->plane_size.surface_size.width)) {
392 vpe_log("target rect exceed surface boundary, target x= %d, width = %u, surface x = %d, "
393 "width = %u\n",
394 param->target_rect.x, param->target_rect.width, surface_info->plane_size.surface_size.x,
395 surface_info->plane_size.surface_size.width);
396 return VPE_STATUS_PARAM_CHECK_ERROR;
397 }
398
399 if ((param->target_rect.y < surface_info->plane_size.surface_size.y ||
400 param->target_rect.y + (int32_t)param->target_rect.height >
401 surface_info->plane_size.surface_size.y +
402 (int32_t)surface_info->plane_size.surface_size.height)) {
403 vpe_log(
404 "target rect exceed surface boundary, y= %d, height = %u, surface x = %d, width = %u\n",
405 param->target_rect.y, param->target_rect.height,
406 surface_info->plane_size.surface_size.y, surface_info->plane_size.surface_size.height);
407 return VPE_STATUS_PARAM_CHECK_ERROR;
408 }
409
410 if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
411 if ((uint32_t)(surface_info->plane_size.chroma_size.x +
412 (int32_t)surface_info->plane_size.chroma_size.width) >
413 surface_info->plane_size.chroma_pitch) {
414 vpe_log("chroma pitch alignment not supported %u. %u\n",
415 surface_info->plane_size.chroma_pitch, vpe->caps->plane_caps.pitch_alignment);
416 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
417 }
418 }
419
420 // output dcc
421 if (surface_info->dcc.enable) {
422
423 params.surface_size.width = surface_info->plane_size.surface_size.width;
424 params.surface_size.height = surface_info->plane_size.surface_size.height;
425 params.format = surface_info->format;
426 params.swizzle_mode = surface_info->swizzle;
427 params.scan = VPE_SCAN_PATTERN_0_DEGREE;
428 support = vpe->cap_funcs->get_dcc_compression_output_cap(vpe, ¶ms, &cap);
429 if (!support) {
430 vpe_log("output dcc not supported\n");
431 return VPE_STATUS_OUTPUT_DCC_NOT_SUPPORTED;
432 }
433 }
434
435 // pixel format
436 support = cdc_be->funcs->check_output_format(cdc_be, surface_info->format);
437 if (!support) {
438 vpe_log("output pixel format not supported %d\n", (int)surface_info->format);
439 return VPE_STATUS_PIXEL_FORMAT_NOT_SUPPORTED;
440 }
441
442 // color space value
443 support = vpe_priv->resource.check_output_color_space(
444 vpe_priv, surface_info->format, &surface_info->cs);
445 if (!support) {
446 vpe_log("output color space not supported fmt: %d, "
447 "encoding: %d, cositing: %d, gamma: %d, range: %d, primaries: %d\n",
448 (int)surface_info->format, (int)surface_info->cs.encoding,
449 (int)surface_info->cs.cositing, (int)surface_info->cs.tf, (int)surface_info->cs.range,
450 (int)surface_info->cs.primaries);
451 return VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED;
452 }
453
454 return VPE_STATUS_OK;
455 }
456
vpe_check_input_support(struct vpe * vpe,const struct vpe_stream * stream)457 enum vpe_status vpe_check_input_support(struct vpe *vpe, const struct vpe_stream *stream)
458 {
459 struct vpe_priv *vpe_priv = container_of(vpe, struct vpe_priv, pub);
460 struct vpec *vpec;
461 struct dpp *dpp;
462 struct cdc_fe *cdc_fe;
463 const struct vpe_surface_info *surface_info = &stream->surface_info;
464 struct vpe_dcc_surface_param params;
465 struct vpe_surface_dcc_cap cap;
466 bool support;
467 const PHYSICAL_ADDRESS_LOC *addrloc;
468 bool use_adj = vpe_use_csc_adjust(&stream->color_adj);
469 enum vpe_status status = VPE_STATUS_OK;
470
471 vpec = &vpe_priv->resource.vpec;
472 dpp = vpe_priv->resource.dpp[0];
473 cdc_fe = vpe_priv->resource.cdc_fe[0];
474
475 // swizzle mode
476 support = vpec->funcs->check_swmode_support(vpec, surface_info->swizzle);
477 if (!support) {
478 vpe_log("input swizzle mode not supported %d\n", surface_info->swizzle);
479 return VPE_STATUS_SWIZZLE_NOT_SUPPORTED;
480 }
481
482 // pitch & address
483 if ((uint32_t)(surface_info->plane_size.surface_size.x +
484 (int32_t)surface_info->plane_size.surface_size.width) >
485 surface_info->plane_size.surface_pitch) {
486
487 vpe_log("pitch alignment not supported %d. %d\n", surface_info->plane_size.surface_pitch,
488 vpe->caps->plane_caps.pitch_alignment);
489 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
490 }
491
492 if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
493
494 addrloc = &surface_info->address.video_progressive.luma_addr;
495 if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
496 vpe_log("failed. addr not aligned to 256 bytes\n");
497 return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
498 }
499
500 if (vpe_is_dual_plane_format(surface_info->format)) {
501 if ((uint32_t)(surface_info->plane_size.chroma_size.x +
502 (int32_t)surface_info->plane_size.chroma_size.width) >
503 surface_info->plane_size.chroma_pitch) {
504 vpe_log("chroma pitch alignment not supported %d. %d\n",
505 surface_info->plane_size.chroma_pitch, vpe->caps->plane_caps.pitch_alignment);
506 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
507 }
508
509 addrloc = &surface_info->address.video_progressive.chroma_addr;
510 if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
511 vpe_log("failed. addr not aligned to 256 bytes\n");
512 return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
513 }
514 }
515 } else {
516 addrloc = &surface_info->address.grph.addr;
517 if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
518 vpe_log("failed. addr not aligned to 256 bytes\n");
519 return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
520 }
521 }
522
523 // input dcc
524 if (surface_info->dcc.enable) {
525
526 params.surface_size.width = surface_info->plane_size.surface_size.width;
527 params.surface_size.height = surface_info->plane_size.surface_size.height;
528 params.format = surface_info->format;
529 params.swizzle_mode = surface_info->swizzle;
530
531 support = vpe->cap_funcs->get_dcc_compression_input_cap(vpe, ¶ms, &cap);
532 //only support non dual plane formats
533 if (!support) {
534 vpe_log("input internal dcc not supported\n");
535 return VPE_STATUS_INPUT_DCC_NOT_SUPPORTED;
536 }
537 }
538
539 // pixel format
540 support = cdc_fe->funcs->check_input_format(cdc_fe, surface_info->format);
541 if (!support) {
542 vpe_log("input pixel format not supported %d\n", (int)surface_info->format);
543 return VPE_STATUS_PIXEL_FORMAT_NOT_SUPPORTED;
544 }
545
546 // color space value
547 support = vpe_priv->resource.check_input_color_space(
548 vpe_priv, surface_info->format, &surface_info->cs);
549 if (!support) {
550 vpe_log("input color space not supported fmt: %d, "
551 "encoding: %d, cositing: %d, gamma: %d, range: %d, primaries: %d\n",
552 (int)surface_info->format, (int)surface_info->cs.encoding,
553 (int)surface_info->cs.cositing, (int)surface_info->cs.tf, (int)surface_info->cs.range,
554 (int)surface_info->cs.primaries);
555 return VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED;
556 }
557
558 if (surface_info->cs.primaries == VPE_PRIMARIES_BT2020 &&
559 surface_info->cs.encoding == VPE_PIXEL_ENCODING_RGB && use_adj) {
560 // for BT2020 + RGB input with adjustments, it is expected not working.
561 vpe_log("for BT2020 + RGB input with adjustments, it is expected not working\n");
562 return VPE_STATUS_ADJUSTMENT_NOT_SUPPORTED;
563 }
564
565 // rotation and mirror
566 status = vpe_priv->resource.check_mirror_rotation_support(stream);
567 if (status != VPE_STATUS_OK) {
568 vpe_log("Rotation %d and mirroring is not supported. horizontal "
569 "mirror: %d vertical mirror: %d error code: %d \n",
570 (int)stream->rotation, (int)stream->horizontal_mirror, (int)stream->vertical_mirror,
571 (int)status);
572
573 return status;
574 }
575
576 // keying
577 if (stream->enable_luma_key && stream->color_keyer.enable_color_key) {
578 vpe_log("Invalid Keying configuration. Both Luma and Color Keying Enabled\n");
579 return VPE_STATUS_INVALID_KEYER_CONFIG;
580 } else if (stream->enable_luma_key) {
581 if (!vpe->caps->color_caps.dpp.luma_key) {
582 vpe_log("Luma keying not supported\n");
583 return VPE_STATUS_LUMA_KEYING_NOT_SUPPORTED;
584 } else if (!vpe_is_yuv(surface_info->format)) {
585 vpe_log("Invalid Keying configuration. Luma Key Enabled with RGB Input\n");
586 return VPE_STATUS_INVALID_KEYER_CONFIG;
587 }
588 } else if (stream->color_keyer.enable_color_key) {
589 if (!vpe->caps->color_caps.dpp.color_key) {
590 vpe_log("color keying not supported\n");
591 return VPE_STATUS_COLOR_KEYING_NOT_SUPPORTED;
592 } else if (vpe_is_yuv(surface_info->format)) {
593 vpe_log("Invalid Keying configuration. Color Keying Enabled with YUV Input\n");
594 return VPE_STATUS_INVALID_KEYER_CONFIG;
595 }
596 }
597
598 return VPE_STATUS_OK;
599 }
600
vpe_check_tone_map_support(struct vpe * vpe,const struct vpe_stream * stream,const struct vpe_build_param * param)601 enum vpe_status vpe_check_tone_map_support(
602 struct vpe *vpe, const struct vpe_stream *stream, const struct vpe_build_param *param)
603 {
604 enum vpe_status status = VPE_STATUS_OK;
605 bool input_is_hdr = is_HDR(stream->surface_info.cs.tf);
606 bool is_3D_lut_enabled = stream->tm_params.enable_3dlut || stream->tm_params.UID;
607 bool is_hlg = stream->tm_params.shaper_tf == VPE_TF_HLG;
608 bool is_in_lum_greater_than_out_lum = stream->hdr_metadata.max_mastering > param->hdr_metadata.max_mastering;
609
610 // Check if Tone Mapping parameters are valid
611 if (is_3D_lut_enabled) {
612 if ((stream->tm_params.lut_data == NULL) ||
613 (!input_is_hdr) ||
614 (!is_hlg && !is_in_lum_greater_than_out_lum)) {
615 status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
616 }
617 } else {
618 if (is_hlg ||
619 (input_is_hdr && is_in_lum_greater_than_out_lum)) {
620 status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
621 }
622 }
623
624 if (is_3D_lut_enabled && stream->tm_params.lut_dim != LUT_DIM_9 &&
625 stream->tm_params.lut_dim != LUT_DIM_17) { /* only support 9/17 cube */
626 status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
627 }
628 return status;
629 }
630
631