• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &param->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, &params, &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, &params, &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