xref: /aosp_15_r20/external/mesa3d/src/amd/vpelib/src/core/common.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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 = &param->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, &params, &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, &params, &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