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