xref: /aosp_15_r20/external/intel-media-driver/media_softlet/agnostic/common/vp/hal/utils/vp_utils.cpp (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2021-2023, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 
23 #include "vp_utils.h"
24 #include "vp_common.h"
25 #include "hal_kerneldll_next.h"
26 #include "mos_interface.h"
27 
ReAllocateSurface(PMOS_INTERFACE osInterface,PVPHAL_SURFACE surface,PCCHAR surfaceName,MOS_FORMAT format,MOS_GFXRES_TYPE defaultResType,MOS_TILE_TYPE defaultTileType,uint32_t dwWidth,uint32_t dwHeight,bool bCompressible,MOS_RESOURCE_MMC_MODE compressionMode,bool * bAllocated,MOS_HW_RESOURCE_DEF resUsageType,MOS_TILE_MODE_GMM tileModeByForce,Mos_MemPool memType,bool isNotLockable)28 MOS_STATUS VpUtils::ReAllocateSurface(
29     PMOS_INTERFACE        osInterface,
30     PVPHAL_SURFACE        surface,
31     PCCHAR                surfaceName,
32     MOS_FORMAT            format,
33     MOS_GFXRES_TYPE       defaultResType,
34     MOS_TILE_TYPE         defaultTileType,
35     uint32_t              dwWidth,
36     uint32_t              dwHeight,
37     bool                  bCompressible,
38     MOS_RESOURCE_MMC_MODE compressionMode,
39     bool                  *bAllocated,
40     MOS_HW_RESOURCE_DEF   resUsageType,
41     MOS_TILE_MODE_GMM     tileModeByForce,
42     Mos_MemPool           memType,
43     bool                  isNotLockable)
44 {
45     MOS_STATUS              eStatus      = MOS_STATUS_SUCCESS;
46     VPHAL_GET_SURFACE_INFO  info         = {};
47     MOS_ALLOC_GFXRES_PARAMS allocParams  = {};
48     MOS_GFXRES_FREE_FLAGS   resFreeFlags = {0};
49 
50     //---------------------------------
51     VP_PUBLIC_ASSERT(osInterface);
52     VP_PUBLIC_ASSERT(surface);
53     //---------------------------------
54 
55     *bAllocated = false;
56 
57     // bCompressible should be compared with bCompressible since it is inited by bCompressible in previous call
58     // TileType of surface should be compared since we need to reallocate surface if TileType changes
59     if (!Mos_ResourceIsNull(&surface->OsResource) &&
60         (surface->dwWidth == dwWidth) &&
61         (surface->dwHeight == dwHeight) &&
62         (surface->Format == format) &&
63         (surface->bCompressible == bCompressible) &&
64         (surface->CompressionMode == compressionMode) &&
65         (surface->TileType == defaultTileType))
66     {
67         goto finish;
68     }
69 
70     // reuse the allocated buffer if the allocated size was larger than request size when OptimizeCpuTiming is enabled
71     if (osInterface->bOptimizeCpuTiming                             &&
72         !Mos_ResourceIsNull(&surface->OsResource)                   &&
73         (Format_Buffer                        == format)            &&
74         (surface->dwWidth * surface->dwHeight >= dwWidth * dwHeight))
75     {
76         goto finish;
77     }
78 
79     MOS_ZeroMemory(&allocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
80 
81     VpHal_AllocParamsInitType(&allocParams, surface, defaultResType, defaultTileType);
82 
83     allocParams.dwWidth            = dwWidth;
84     allocParams.dwHeight           = dwHeight;
85     allocParams.Format             = format;
86     allocParams.bIsCompressible    = bCompressible;
87     allocParams.CompressionMode    = compressionMode;
88     allocParams.pBufName           = surfaceName;
89     allocParams.dwArraySize        = 1;
90     allocParams.ResUsageType       = resUsageType;
91     allocParams.m_tileModeByForce  = tileModeByForce;
92     allocParams.dwMemType          = memType;
93     allocParams.Flags.bNotLockable = isNotLockable;
94 
95     // Delete resource if already allocated
96     //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
97     if (IsSyncFreeNeededForMMCSurface(surface, osInterface))
98     {
99         resFreeFlags.SynchronousDestroy = 1;
100         VP_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource %s", surfaceName);
101     }
102     osInterface->pfnFreeResourceWithFlag(osInterface, &(surface->OsResource), resFreeFlags.Value);
103 
104     // Allocate surface
105     VP_PUBLIC_CHK_STATUS(osInterface->pfnAllocateResource(
106         osInterface,
107         &allocParams,
108         &surface->OsResource));
109 
110     // Get surface information
111     MOS_ZeroMemory(&info, sizeof(VPHAL_GET_SURFACE_INFO));
112 
113     // Pre-set to get surface info
114     surface->Format = format;
115 
116     VP_PUBLIC_CHK_STATUS(VpHal_GetSurfaceInfo(osInterface, &info, surface));
117 
118     *bAllocated = true;
119 
120     MT_LOG7(MT_VP_HAL_REALLOC_SURF, MT_NORMAL, MT_VP_HAL_INTER_SURF_TYPE, surfaceName ? *((int64_t *)surfaceName) : 0, MT_SURF_WIDTH, dwWidth, MT_SURF_HEIGHT, dwHeight, MT_SURF_MOS_FORMAT, format, MT_SURF_TILE_MODE, surface->TileModeGMM, MT_SURF_COMP_ABLE, surface->bCompressible, MT_SURF_COMP_MODE, surface->CompressionMode);
121 
122 finish:
123     VP_PUBLIC_ASSERT(eStatus == MOS_STATUS_SUCCESS);
124     return eStatus;
125 }
126 
IsVerticalRotation(VPHAL_ROTATION rotation)127 bool VpUtils::IsVerticalRotation(VPHAL_ROTATION rotation) {
128     return (rotation != VPHAL_ROTATION_IDENTITY &&
129             rotation != VPHAL_ROTATION_180 &&
130             rotation != VPHAL_MIRROR_VERTICAL &&
131             rotation != VPHAL_MIRROR_HORIZONTAL);
132 }
133 
IsSyncFreeNeededForMMCSurface(PVPHAL_SURFACE surface,PMOS_INTERFACE osInterface)134 bool VpUtils::IsSyncFreeNeededForMMCSurface(PVPHAL_SURFACE surface, PMOS_INTERFACE osInterface)
135 {
136     if (nullptr == surface || nullptr == osInterface)
137     {
138         return false;
139     }
140 
141     //Compressed surface aux table update is after resource dealloction, aux table update need wait the WLs complete
142     //the sync deallocation flag will make sure deallocation API return after all surface related WL been completed and resource been destroyed by OS
143     auto *pSkuTable = osInterface->pfnGetSkuTable(osInterface);
144     if (pSkuTable &&
145         MEDIA_IS_SKU(pSkuTable, FtrE2ECompression) &&                                    //Compression enabled platform
146         !MEDIA_IS_SKU(pSkuTable, FtrFlatPhysCCS) &&                                      //NOT DGPU compression
147         ((surface->bCompressible) && (surface->CompressionMode != MOS_MMC_DISABLED)))  //Compressed enabled surface
148     {
149         return true;
150     }
151 
152     return false;
153 }
154 
GetCscMatrixForVeSfc8Bit(VPHAL_CSPACE srcCspace,VPHAL_CSPACE dstCspace,float * fCscCoeff,float * fCscInOffset,float * fCscOutOffset)155 void VpUtils::GetCscMatrixForVeSfc8Bit(
156     VPHAL_CSPACE srcCspace,
157     VPHAL_CSPACE dstCspace,
158     float        *fCscCoeff,
159     float        *fCscInOffset,
160     float        *fCscOutOffset)
161 {
162     float   fCscMatrix[12] = {0};
163     int32_t i              =  0;
164 
165     KernelDll_GetCSCMatrix(
166         srcCspace,
167         dstCspace,
168         fCscMatrix);
169 
170     // Copy [3x3] into Coeff
171     for (i = 0; i < 3; i++)
172     {
173         MOS_SecureMemcpy(
174             &fCscCoeff[i * 3],
175             sizeof(float) * 3,
176             &fCscMatrix[i * 4],
177             sizeof(float) * 3);
178     }
179 
180     // Get the input offsets
181     switch (srcCspace)
182     {
183     CASE_YUV_CSPACE_LIMITEDRANGE:
184         fCscInOffset[0] = -16.0F;
185         fCscInOffset[1] = -128.0F;
186         fCscInOffset[2] = -128.0F;
187         break;
188 
189     CASE_YUV_CSPACE_FULLRANGE:
190         fCscInOffset[0] = 0.0F;
191         fCscInOffset[1] = -128.0F;
192         fCscInOffset[2] = -128.0F;
193         break;
194 
195     case CSpace_sRGB:
196         fCscInOffset[0] = 0.0F;
197         fCscInOffset[1] = 0.0F;
198         fCscInOffset[2] = 0.0F;
199         break;
200 
201     case CSpace_stRGB:
202         fCscInOffset[0] = -16.0F;
203         fCscInOffset[1] = -16.0F;
204         fCscInOffset[2] = -16.0F;
205         break;
206 
207     //BT2020 YUV->RGB
208     case CSpace_BT2020:
209         fCscInOffset[0] = -16.0F;
210         fCscInOffset[1] = -128.0F;
211         fCscInOffset[2] = -128.0F;
212         break;
213 
214     case CSpace_BT2020_FullRange:
215         fCscInOffset[0] = 0.0F;
216         fCscInOffset[1] = -128.0F;
217         fCscInOffset[2] = -128.0F;
218         break;
219 
220     //BT2020 RGB->YUV
221     case CSpace_BT2020_RGB:
222         fCscInOffset[0] = 0.0F;
223         fCscInOffset[1] = 0.0F;
224         fCscInOffset[2] = 0.0F;
225         break;
226 
227     //BT2020 RGB->YUV
228     case CSpace_BT2020_stRGB:
229         fCscInOffset[0] = -16.0F;
230         fCscInOffset[1] = -16.0F;
231         fCscInOffset[2] = -16.0F;
232         break;
233 
234     default:
235         VP_PUBLIC_NORMALMESSAGE("Unsupported Input ColorSpace for Vebox %d.", (uint32_t)srcCspace);
236     }
237 
238     // Get the output offsets
239     switch (dstCspace)
240     {
241     CASE_YUV_CSPACE_LIMITEDRANGE:
242         fCscOutOffset[0] = 16.0F;
243         fCscOutOffset[1] = 128.0F;
244         fCscOutOffset[2] = 128.0F;
245         break;
246 
247     CASE_YUV_CSPACE_FULLRANGE:
248         fCscOutOffset[0] = 0.0F;
249         fCscOutOffset[1] = 128.0F;
250         fCscOutOffset[2] = 128.0F;
251         break;
252 
253     case CSpace_sRGB:
254         fCscOutOffset[0] = 0.0F;
255         fCscOutOffset[1] = 0.0F;
256         fCscOutOffset[2] = 0.0F;
257         break;
258 
259     case CSpace_stRGB:
260         fCscOutOffset[0] = 16.0F;
261         fCscOutOffset[1] = 16.0F;
262         fCscOutOffset[2] = 16.0F;
263         break;
264 
265     //BT2020 RGB->YUV
266     case CSpace_BT2020:
267         fCscOutOffset[0] = 16.0F;
268         fCscOutOffset[1] = 128.0F;
269         fCscOutOffset[2] = 128.0F;
270         break;
271 
272     case CSpace_BT2020_FullRange:
273         fCscOutOffset[0] = 0.0F;
274         fCscOutOffset[1] = 128.0F;
275         fCscOutOffset[2] = 128.0F;
276         break;
277 
278     case CSpace_BT2020_RGB:
279         fCscOutOffset[0] = 0.0F;
280         fCscOutOffset[1] = 0.0F;
281         fCscOutOffset[2] = 0.0F;
282         break;
283 
284     case CSpace_BT2020_stRGB:
285         fCscOutOffset[0] = 16.0F;
286         fCscOutOffset[1] = 16.0F;
287         fCscOutOffset[2] = 16.0F;
288         break;
289 
290     default:
291         VP_PUBLIC_NORMALMESSAGE("Unsupported Output ColorSpace for Vebox %d.", (uint32_t)dstCspace);
292     }
293 }
294 
GetCscMatrixForRender8Bit(VPHAL_COLOR_SAMPLE_8 * output,VPHAL_COLOR_SAMPLE_8 * input,VPHAL_CSPACE srcCspace,VPHAL_CSPACE dstCspace)295 bool VpUtils::GetCscMatrixForRender8Bit(
296     VPHAL_COLOR_SAMPLE_8 *output,
297     VPHAL_COLOR_SAMPLE_8 *input,
298     VPHAL_CSPACE          srcCspace,
299     VPHAL_CSPACE          dstCspace)
300 {
301     float   pfCscMatrix[12] = {0};
302     int32_t iCscMatrix[12]  = {0};
303     bool    bResult         = false;
304     int32_t i               = 0;
305 
306     KernelDll_GetCSCMatrix(srcCspace, dstCspace, pfCscMatrix);
307 
308     // convert float to fixed point format for the 3x4 matrix
309     for (i = 0; i < 12; i++)
310     {
311         // multiply by 2^20 and round up
312         iCscMatrix[i] = (int32_t)((pfCscMatrix[i] * 1048576.0f) + 0.5f);
313     }
314 
315     bResult = GetCscMatrixForRender8BitWithCoeff(output, input, srcCspace, dstCspace, iCscMatrix);
316 
317     return bResult;
318 }
319 
GetCscMatrixForRender8BitWithCoeff(VPHAL_COLOR_SAMPLE_8 * output,VPHAL_COLOR_SAMPLE_8 * input,VPHAL_CSPACE srcCspace,VPHAL_CSPACE dstCspace,int32_t * iCscMatrix)320 bool VpUtils::GetCscMatrixForRender8BitWithCoeff(
321     VPHAL_COLOR_SAMPLE_8 *output,
322     VPHAL_COLOR_SAMPLE_8 *input,
323     VPHAL_CSPACE          srcCspace,
324     VPHAL_CSPACE          dstCspace,
325     int32_t              *iCscMatrix)
326 {
327     bool    bResult = true;
328     int32_t a = 0, r = 0, g = 0, b = 0;
329     int32_t y1 = 0, u1 = 0, v1 = 0;
330 
331     y1 = r = input->YY;
332     u1 = g = input->Cb;
333     v1 = b = input->Cr;
334     a      = input->Alpha;
335 
336     if (srcCspace == dstCspace)
337     {
338         // no conversion needed
339         if ((dstCspace == CSpace_sRGB) || (dstCspace == CSpace_stRGB) || IS_COLOR_SPACE_BT2020_RGB(dstCspace))
340         {
341             output->A = (uint8_t)a;
342             output->R = (uint8_t)r;
343             output->G = (uint8_t)g;
344             output->B = (uint8_t)b;
345         }
346         else
347         {
348             output->a = (uint8_t)a;
349             output->Y = (uint8_t)y1;
350             output->U = (uint8_t)u1;
351             output->V = (uint8_t)v1;
352         }
353     }
354     else
355     {
356         // conversion needed
357         r = (y1 * iCscMatrix[0] + u1 * iCscMatrix[1] +
358                 v1 * iCscMatrix[2] + iCscMatrix[3] + 0x00080000) >>
359             20;
360         g = (y1 * iCscMatrix[4] + u1 * iCscMatrix[5] +
361                 v1 * iCscMatrix[6] + iCscMatrix[7] + 0x00080000) >>
362             20;
363         b = (y1 * iCscMatrix[8] + u1 * iCscMatrix[9] +
364                 v1 * iCscMatrix[10] + iCscMatrix[11] + 0x00080000) >>
365             20;
366 
367         switch (dstCspace)
368         {
369         case CSpace_sRGB:
370             output->A = (uint8_t)a;
371             output->R = MOS_MIN(MOS_MAX(0, r), 255);
372             output->G = MOS_MIN(MOS_MAX(0, g), 255);
373             output->B = MOS_MIN(MOS_MAX(0, b), 255);
374             break;
375 
376         case CSpace_stRGB:
377             output->A = (uint8_t)a;
378             output->R = MOS_MIN(MOS_MAX(16, r), 235);
379             output->G = MOS_MIN(MOS_MAX(16, g), 235);
380             output->B = MOS_MIN(MOS_MAX(16, b), 235);
381             break;
382 
383         case CSpace_BT601:
384         case CSpace_BT709:
385             output->a = (uint8_t)a;
386             output->Y = MOS_MIN(MOS_MAX(16, r), 235);
387             output->U = MOS_MIN(MOS_MAX(16, g), 240);
388             output->V = MOS_MIN(MOS_MAX(16, b), 240);
389             break;
390 
391         case CSpace_xvYCC601:
392         case CSpace_xvYCC709:
393         case CSpace_BT601_FullRange:
394         case CSpace_BT709_FullRange:
395             output->a = (uint8_t)a;
396             output->Y = MOS_MIN(MOS_MAX(0, r), 255);
397             output->U = MOS_MIN(MOS_MAX(0, g), 255);
398             output->V = MOS_MIN(MOS_MAX(0, b), 255);
399             break;
400 
401         default:
402             VP_PUBLIC_NORMALMESSAGE("Unsupported Output ColorSpace %d.", (uint32_t)dstCspace);
403             bResult = false;
404             break;
405         }
406     }
407 
408     return bResult;
409 }
410