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_rgb8(enum vpe_surface_pixel_format format)77 bool vpe_is_rgb8(enum vpe_surface_pixel_format format)
78 {
79 switch (format) {
80 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
81 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
82 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
83 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
84 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
85 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
86 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
87 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
88 return true;
89 default:
90 return false;
91 }
92 }
93
vpe_is_rgb10(enum vpe_surface_pixel_format format)94 bool vpe_is_rgb10(enum vpe_surface_pixel_format format)
95 {
96 switch (format) {
97 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
98 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
99 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
100 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
101 return true;
102 default:
103 return false;
104 }
105 }
106
vpe_is_fp16(enum vpe_surface_pixel_format format)107 bool vpe_is_fp16(enum vpe_surface_pixel_format format)
108 {
109 switch (format) {
110 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
111 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
112 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
113 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
114 return true;
115 default:
116 return false;
117 }
118 }
119
vpe_is_yuv420_8(enum vpe_surface_pixel_format format)120 bool vpe_is_yuv420_8(enum vpe_surface_pixel_format format)
121 {
122 switch (format) {
123 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
124 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
125 return true;
126 default:
127 return false;
128 }
129 }
130
vpe_is_yuv420_10(enum vpe_surface_pixel_format format)131 bool vpe_is_yuv420_10(enum vpe_surface_pixel_format format)
132 {
133 switch (format) {
134 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
135 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
136 return true;
137 default:
138 return false;
139 }
140 }
vpe_is_yuv420_16(enum vpe_surface_pixel_format format)141 bool vpe_is_yuv420_16(enum vpe_surface_pixel_format format)
142 {
143 switch (format) {
144 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_16bpc_YCrCb:
145 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_16bpc_YCbCr:
146 return true;
147 default:
148 return false;
149 }
150 }
151
vpe_is_yuv420(enum vpe_surface_pixel_format format)152 bool vpe_is_yuv420(enum vpe_surface_pixel_format format)
153 {
154 return (vpe_is_yuv420_8(format) || vpe_is_yuv420_10(format) || vpe_is_yuv420_16(format));
155 }
156
vpe_is_yuv444_8(enum vpe_surface_pixel_format format)157 bool vpe_is_yuv444_8(enum vpe_surface_pixel_format format)
158 {
159 switch (format) {
160 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
161 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
162 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
163 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
164 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
165 return true;
166 default:
167 return false;
168 }
169 }
170
vpe_is_yuv444_10(enum vpe_surface_pixel_format format)171 bool vpe_is_yuv444_10(enum vpe_surface_pixel_format format)
172 {
173 switch (format) {
174 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
175 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
176 return true;
177 default:
178 return false;
179 }
180 }
181
vpe_is_yuv444(enum vpe_surface_pixel_format format)182 bool vpe_is_yuv444(enum vpe_surface_pixel_format format)
183 {
184 return (vpe_is_yuv444_8(format) || vpe_is_yuv444_10(format));
185 }
186
vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format,int plane_idx)187 static uint8_t vpe_get_element_size_in_bytes(enum vpe_surface_pixel_format format, int plane_idx)
188 {
189 switch (format) {
190 // nv12/21
191 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
192 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
193 if (plane_idx == 0)
194 return 1;
195 else
196 return 2;
197 // P010
198 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
199 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
200 if (plane_idx == 0)
201 return 2;
202 else
203 return 4;
204 // 64bpp
205 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
206 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
207 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
208 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
209 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
210 return 8;
211 default:
212 break;
213 }
214 // default 32bpp packed format
215 return 4;
216 }
217
vpe_get_color_depth(enum vpe_surface_pixel_format format)218 enum color_depth vpe_get_color_depth(enum vpe_surface_pixel_format format)
219 {
220 enum color_depth c_depth;
221 switch (format) {
222 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
223 c_depth = COLOR_DEPTH_666;
224 break;
225 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
226 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
227 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
228 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
229 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
230 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
231 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
232 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
233 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
234 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
235 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
236 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
237 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
238 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
239 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
240 c_depth = COLOR_DEPTH_888;
241 break;
242 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
243 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
244 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
245 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
246 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
247 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
248 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
249 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
250 c_depth = COLOR_DEPTH_101010;
251 break;
252 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
253 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
254 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
255 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
256 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
257 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_16bpc_YCrCb:
258 c_depth = COLOR_DEPTH_161616;
259 break;
260 default:
261 c_depth = COLOR_DEPTH_888;
262 }
263
264 return c_depth;
265 }
266
vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format)267 bool vpe_has_per_pixel_alpha(enum vpe_surface_pixel_format format)
268 {
269 bool alpha = true;
270
271 switch (format) {
272 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB1555:
273 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB8888:
274 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR8888:
275 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA8888:
276 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA8888:
277 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010:
278 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010:
279 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA1010102:
280 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA1010102:
281 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616:
282 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F:
283 case VPE_SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F:
284 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBA16161616F:
285 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRA16161616F:
286 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA:
287 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010:
288 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102:
289 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888:
290 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_YCrCbA8888:
291 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb8888:
292 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA8888:
293 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_AYCbCr8888:
294 alpha = true;
295 break;
296 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB565:
297 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX:
298 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX:
299 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT:
300 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT:
301 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBE:
302 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr:
303 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb:
304 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr:
305 case VPE_SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb:
306 case VPE_SURFACE_PIXEL_FORMAT_GRPH_RGBX8888:
307 case VPE_SURFACE_PIXEL_FORMAT_GRPH_BGRX8888:
308 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XRGB8888:
309 case VPE_SURFACE_PIXEL_FORMAT_GRPH_XBGR8888:
310 default:
311 alpha = false;
312 break;
313 }
314
315 return alpha;
316 }
317
318 // Note there is another function vpe_is_hdr that performs the same function but with the translated
319 // internal VPE enums, not the api enums as done below. C does not support function overloading so
320 // another function is needed here.
is_HDR(enum vpe_transfer_function tf)321 static bool is_HDR(enum vpe_transfer_function tf)
322 {
323 return (tf == VPE_TF_PQ || tf == VPE_TF_G10 || tf == VPE_TF_HLG);
324 }
325
vpe_check_output_support(struct vpe * vpe,const struct vpe_build_param * param)326 enum vpe_status vpe_check_output_support(struct vpe *vpe, const struct vpe_build_param *param)
327 {
328 struct vpe_priv *vpe_priv = container_of(vpe, struct vpe_priv, pub);
329 struct vpec *vpec;
330 struct dpp *dpp;
331 struct cdc *cdc;
332 const struct vpe_surface_info *surface_info = ¶m->dst_surface;
333 struct vpe_dcc_surface_param params;
334 struct vpe_surface_dcc_cap cap;
335 bool support;
336
337 vpec = &vpe_priv->resource.vpec;
338 dpp = vpe_priv->resource.dpp[0];
339 cdc = vpe_priv->resource.cdc[0];
340
341 // swizzle mode
342 support = vpec->funcs->check_swmode_support(vpec, surface_info->swizzle);
343 if (!support) {
344 vpe_log("output swizzle mode not supported %d\n", surface_info->swizzle);
345 return VPE_STATUS_SWIZZLE_NOT_SUPPORTED;
346 }
347
348 // pitch
349 if ((uint32_t)(surface_info->plane_size.surface_size.x +
350 (int32_t)surface_info->plane_size.surface_size.width) >
351 surface_info->plane_size.surface_pitch) {
352 vpe_log("pitch alignment not supported %lu. %lu\n", surface_info->plane_size.surface_pitch,
353 vpe->caps->plane_caps.pitch_alignment);
354 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
355 }
356
357 // target rect shouldn't exceed width/height
358 if ((param->target_rect.x < surface_info->plane_size.surface_size.x ||
359 param->target_rect.x + (int32_t)param->target_rect.width >
360 surface_info->plane_size.surface_size.x +
361 (int32_t)surface_info->plane_size.surface_size.width)) {
362 vpe_log("target rect exceed surface boundary, target x= %d, width = %u, surface x = %d, "
363 "width = %u\n",
364 param->target_rect.x, param->target_rect.width, surface_info->plane_size.surface_size.x,
365 surface_info->plane_size.surface_size.width);
366 return VPE_STATUS_PARAM_CHECK_ERROR;
367 }
368
369 if ((param->target_rect.y < surface_info->plane_size.surface_size.y ||
370 param->target_rect.y + (int32_t)param->target_rect.height >
371 surface_info->plane_size.surface_size.y +
372 (int32_t)surface_info->plane_size.surface_size.height)) {
373 vpe_log(
374 "target rect exceed surface boundary, y= %d, height = %u, surface x = %d, width = %u\n",
375 param->target_rect.y, param->target_rect.height,
376 surface_info->plane_size.surface_size.y, surface_info->plane_size.surface_size.height);
377 return VPE_STATUS_PARAM_CHECK_ERROR;
378 }
379
380 if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
381 if ((uint32_t)(surface_info->plane_size.chroma_size.x +
382 (int32_t)surface_info->plane_size.chroma_size.width) >
383 surface_info->plane_size.chroma_pitch) {
384 vpe_log("chroma pitch alignment not supported %u. %u\n",
385 surface_info->plane_size.chroma_pitch, vpe->caps->plane_caps.pitch_alignment);
386 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
387 }
388 }
389
390 // output dcc
391 if (surface_info->dcc.enable) {
392
393 params.surface_size.width = surface_info->plane_size.surface_size.width;
394 params.surface_size.height = surface_info->plane_size.surface_size.height;
395 params.format = surface_info->format;
396 params.swizzle_mode = surface_info->swizzle;
397 params.scan = VPE_SCAN_PATTERN_0_DEGREE;
398 support = vpe->cap_funcs->get_dcc_compression_output_cap(vpe, ¶ms, &cap);
399 if (!support) {
400 vpe_log("output dcc not supported\n");
401 return VPE_STATUS_OUTPUT_DCC_NOT_SUPPORTED;
402 }
403 }
404
405 // pixel format
406 support = cdc->funcs->check_output_format(cdc, surface_info->format);
407 if (!support) {
408 vpe_log("output pixel format not supported %d\n", (int)surface_info->format);
409 return VPE_STATUS_PIXEL_FORMAT_NOT_SUPPORTED;
410 }
411
412 // color space value
413 support = vpe_priv->resource.check_output_color_space(
414 vpe_priv, surface_info->format, &surface_info->cs);
415 if (!support) {
416 vpe_log("output color space not supported fmt: %d, "
417 "encoding: %d, cositing: %d, gamma: %d, range: %d, primaries: %d\n",
418 (int)surface_info->format, (int)surface_info->cs.encoding,
419 (int)surface_info->cs.cositing, (int)surface_info->cs.tf, (int)surface_info->cs.range,
420 (int)surface_info->cs.primaries);
421 return VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED;
422 }
423
424 return VPE_STATUS_OK;
425 }
426
vpe_check_input_support(struct vpe * vpe,const struct vpe_stream * stream)427 enum vpe_status vpe_check_input_support(struct vpe *vpe, const struct vpe_stream *stream)
428 {
429 struct vpe_priv *vpe_priv = container_of(vpe, struct vpe_priv, pub);
430 struct vpec *vpec;
431 struct dpp *dpp;
432 struct cdc *cdc;
433 const struct vpe_surface_info *surface_info = &stream->surface_info;
434 struct vpe_dcc_surface_param params;
435 struct vpe_surface_dcc_cap cap;
436 bool support;
437 const PHYSICAL_ADDRESS_LOC *addrloc;
438 bool use_adj = vpe_use_csc_adjust(&stream->color_adj);
439
440 vpec = &vpe_priv->resource.vpec;
441 dpp = vpe_priv->resource.dpp[0];
442 cdc = vpe_priv->resource.cdc[0];
443
444 // swizzle mode
445 support = vpec->funcs->check_swmode_support(vpec, surface_info->swizzle);
446 if (!support) {
447 vpe_log("input swizzle mode not supported %d\n", surface_info->swizzle);
448 return VPE_STATUS_SWIZZLE_NOT_SUPPORTED;
449 }
450
451 // pitch & address
452 if ((uint32_t)(surface_info->plane_size.surface_size.x +
453 (int32_t)surface_info->plane_size.surface_size.width) >
454 surface_info->plane_size.surface_pitch) {
455
456 vpe_log("pitch alignment not supported %d. %d\n", surface_info->plane_size.surface_pitch,
457 vpe->caps->plane_caps.pitch_alignment);
458 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
459 }
460
461 if (surface_info->address.type == VPE_PLN_ADDR_TYPE_VIDEO_PROGRESSIVE) {
462
463 addrloc = &surface_info->address.video_progressive.luma_addr;
464 if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
465 vpe_log("failed. addr not aligned to 256 bytes\n");
466 return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
467 }
468
469 if (vpe_is_dual_plane_format(surface_info->format)) {
470 if ((uint32_t)(surface_info->plane_size.chroma_size.x +
471 (int32_t)surface_info->plane_size.chroma_size.width) >
472 surface_info->plane_size.chroma_pitch) {
473 vpe_log("chroma pitch alignment not supported %d. %d\n",
474 surface_info->plane_size.chroma_pitch, vpe->caps->plane_caps.pitch_alignment);
475 return VPE_STATUS_PITCH_ALIGNMENT_NOT_SUPPORTED;
476 }
477
478 addrloc = &surface_info->address.video_progressive.chroma_addr;
479 if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
480 vpe_log("failed. addr not aligned to 256 bytes\n");
481 return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
482 }
483 }
484 } else {
485 addrloc = &surface_info->address.grph.addr;
486 if (addrloc->u.low_part % vpe->caps->plane_caps.addr_alignment) {
487 vpe_log("failed. addr not aligned to 256 bytes\n");
488 return VPE_STATUS_PLANE_ADDR_NOT_SUPPORTED;
489 }
490 }
491
492 // input dcc
493 if (surface_info->dcc.enable) {
494
495 params.surface_size.width = surface_info->plane_size.surface_size.width;
496 params.surface_size.height = surface_info->plane_size.surface_size.height;
497 params.format = surface_info->format;
498 params.swizzle_mode = surface_info->swizzle;
499
500 support = vpe->cap_funcs->get_dcc_compression_input_cap(vpe, ¶ms, &cap);
501 //only support non dual plane formats
502 if (!support) {
503 vpe_log("input internal dcc not supported\n");
504 return VPE_STATUS_INPUT_DCC_NOT_SUPPORTED;
505 }
506 }
507
508 // pixel format
509 support = cdc->funcs->check_input_format(cdc, surface_info->format);
510 if (!support) {
511 vpe_log("input pixel format not supported %d\n", (int)surface_info->format);
512 return VPE_STATUS_PIXEL_FORMAT_NOT_SUPPORTED;
513 }
514
515 // color space value
516 support = vpe_priv->resource.check_input_color_space(
517 vpe_priv, surface_info->format, &surface_info->cs);
518 if (!support) {
519 vpe_log("input color space not supported fmt: %d, "
520 "encoding: %d, cositing: %d, gamma: %d, range: %d, primaries: %d\n",
521 (int)surface_info->format, (int)surface_info->cs.encoding,
522 (int)surface_info->cs.cositing, (int)surface_info->cs.tf, (int)surface_info->cs.range,
523 (int)surface_info->cs.primaries);
524 return VPE_STATUS_COLOR_SPACE_VALUE_NOT_SUPPORTED;
525 }
526
527 // TODO: Add support
528 // adjustments
529 if (surface_info->cs.primaries == VPE_PRIMARIES_BT2020 &&
530 surface_info->cs.encoding == VPE_PIXEL_ENCODING_RGB && use_adj) {
531 // for BT2020 + RGB input with adjustments, it is expected not working.
532 vpe_log("for BT2020 + RGB input with adjustments, it is expected not working\n");
533 return VPE_STATUS_ADJUSTMENT_NOT_SUPPORTED;
534 }
535
536 // rotation
537 if ((stream->rotation != VPE_ROTATION_ANGLE_0) && !vpe->caps->rotation_support) {
538 vpe_log("rotation not supported\n");
539 return VPE_STATUS_ROTATION_NOT_SUPPORTED;
540 }
541
542 // luma keying
543 if (stream->enable_luma_key && !vpe->caps->color_caps.dpp.luma_key) {
544 vpe_log("luma keying not supported\n");
545 return VPE_STATUS_LUMA_KEYING_NOT_SUPPORTED;
546 }
547
548 if (stream->horizontal_mirror && !vpe->caps->h_mirror_support) {
549 vpe_log("output horizontal mirroring not supported h:%d\n", (int)stream->horizontal_mirror);
550 return VPE_STATUS_MIRROR_NOT_SUPPORTED;
551 }
552
553 if (stream->vertical_mirror && !vpe->caps->v_mirror_support) {
554 vpe_log("output vertical mirroring not supported v:%d\n", (int)stream->vertical_mirror);
555 return VPE_STATUS_MIRROR_NOT_SUPPORTED;
556 }
557
558 return VPE_STATUS_OK;
559 }
560
vpe_check_tone_map_support(struct vpe * vpe,const struct vpe_stream * stream,const struct vpe_build_param * param)561 enum vpe_status vpe_check_tone_map_support(
562 struct vpe *vpe, const struct vpe_stream *stream, const struct vpe_build_param *param)
563 {
564 enum vpe_status status = VPE_STATUS_OK;
565 bool input_is_hdr = is_HDR(stream->surface_info.cs.tf);
566 bool is_3D_lut_enabled = stream->tm_params.enable_3dlut || stream->tm_params.UID;
567 bool is_hlg = stream->tm_params.shaper_tf == VPE_TF_HLG;
568 bool is_in_lum_greater_than_out_lum = stream->hdr_metadata.max_mastering > param->hdr_metadata.max_mastering;
569
570 // Check if Tone Mapping parameters are valid
571 if (is_3D_lut_enabled) {
572 if ((stream->tm_params.lut_data == NULL) ||
573 (!input_is_hdr) ||
574 (!is_hlg && !is_in_lum_greater_than_out_lum)) {
575 status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
576 }
577 } else {
578 if (is_hlg ||
579 (input_is_hdr && is_in_lum_greater_than_out_lum)) {
580 status = VPE_STATUS_BAD_TONE_MAP_PARAMS;
581 }
582 }
583
584 return status;
585 }
586