xref: /aosp_15_r20/external/intel-media-driver/media_driver/agnostic/common/vp/hal/vphal_common.c (revision ba62d9d3abf0e404f2022b4cd7a85e107f48596f)
1 /*
2 * Copyright (c) 2009-2022, 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 //! \file     vphal_common.c
24 //! \brief    Definition common utilities for vphal
25 //! \details  Definition common utilities for vphal including:
26 //!           some macro, enum, union, structure, function
27 //!
28 #include "vphal.h"
29 #include "hal_kerneldll.h"
30 #include "mos_os.h"
31 #include "vp_hal_ddi_utils.h"
32 #include <math.h>
33 
34 #if EMUL || VPHAL_LIB
35 #include "support.h"
36 #endif
37 
38 union FP32
39 {
40     uint32_t u;
41     float f;
42     struct
43     {
44         uint32_t Mantissa : 23;
45         uint32_t Exponent : 8;
46         uint32_t Sign : 1;
47     };
48 };
49 
50 union FP16
51 {
52     uint16_t u;
53     struct
54     {
55         uint16_t Mantissa : 10;
56         uint16_t Exponent : 5;
57         uint16_t Sign : 1;
58     };
59 };
60 
61 //!
62 //! \brief    sinc
63 //! \details  Calculate sinc(x)
64 //! \param    [in] x
65 //!           float
66 //! \return   float
67 //!           sinc(x)
68 //!
VpHal_Sinc(float x)69 float VpHal_Sinc(float x)
70 {
71     return (VPHAL_ABS(x) < 1e-9f) ? 1.0F : (float)(sin(x) / x);
72 }
73 
74 //!
75 //! \brief    Lanczos
76 //! \details  Calculate lanczos(x)
77 //!           Basic formula is:  lanczos(x)= VpHal_Sinc(x) * VpHal_Sinc(x / fLanczosT)
78 //! \param    [in] x
79 //!           float
80 //! \param    [in] dwNumEntries
81 //!           dword
82 //! \param    [in] fLanczosT
83 //!
84 //! \return   float
85 //!           lanczos(x)
86 //!
VpHal_Lanczos(float x,uint32_t dwNumEntries,float fLanczosT)87 float VpHal_Lanczos(float x, uint32_t dwNumEntries, float fLanczosT)
88 {
89     uint32_t dwNumHalfEntries;
90 
91     dwNumHalfEntries = dwNumEntries >> 1;
92     if (fLanczosT < dwNumHalfEntries)
93     {
94         fLanczosT = (float)dwNumHalfEntries;
95     }
96 
97     if (VPHAL_ABS(x) >= dwNumHalfEntries)
98     {
99         return 0.0;
100     }
101 
102     x *= VPHAL_PI;
103 
104     return VpHal_Sinc(x) * VpHal_Sinc(x / fLanczosT);
105 }
106 
IsSyncFreeNeededForMMCSurface(PVPHAL_SURFACE pSurface,PMOS_INTERFACE pOsInterface)107 bool IsSyncFreeNeededForMMCSurface(PVPHAL_SURFACE pSurface, PMOS_INTERFACE pOsInterface)
108 {
109     if (nullptr == pSurface || nullptr == pOsInterface)
110     {
111         return false;
112     }
113 
114     //Compressed surface aux table update is after resource dealloction, aux table update need wait the WLs complete
115     //the sync deallocation flag will make sure deallocation API return after all surface related WL been completed and resource been destroyed by OS
116     auto *pSkuTable = pOsInterface->pfnGetSkuTable(pOsInterface);
117     if (pSkuTable &&
118         MEDIA_IS_SKU(pSkuTable, FtrE2ECompression) &&                                      //Compression enabled platform
119         !MEDIA_IS_SKU(pSkuTable, FtrFlatPhysCCS) &&                                        //NOT DGPU compression
120         ((pSurface->bCompressible) && (pSurface->CompressionMode != MOS_MMC_DISABLED)))    //Compressed enabled surface
121     {
122         return true;
123     }
124 
125     return false;
126 }
127 
128 //!
129 //! \brief    Allocates the Surface
130 //! \details  Allocates the Surface
131 //!           - if the surface is not already allocated OR
132 //!           - resource dimenisions OR format changed
133 //! \param    [in] pOsInterface
134 //!           Pointer to MOS_INTERFACE
135 //! \param    [in,out] pSurface
136 //!           Pointer to VPHAL_SURFACE
137 //! \param    [in] pSurfaceName
138 //!           Pointer to surface name
139 //! \param    [in] Format
140 //!           Expected MOS_FORMAT
141 //! \param    [in] DefaultResType
142 //!           Expected Resource Type
143 //! \param    [in] DefaultTileType
144 //!           Expected Surface Tile Type
145 //! \param    [in] dwWidth
146 //!           Expected Surface Width
147 //! \param    [in] dwHeight
148 //!           Expected Surface Height
149 //! \param    [in] bCompressible
150 //!           Surface being compressible or not
151 //! \param    [in] CompressionMode
152 //!           Compression Mode
153 //! \param    [out] pbAllocated
154 //!           true if allocated, false for not
155 //! \param    [in] resUsageType
156 //!           resource usage type for caching
157 //! \param    [in] tileModeByForce
158 //!           Forced tile mode
159 //! \param    [in] memType
160 //!           vidoe memory location
161 //! \param    [in] isNotLockable
162 //!           true if surface not lockable
163 //! \return   MOS_STATUS
164 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
165 //!
VpHal_ReAllocateSurface(PMOS_INTERFACE pOsInterface,PVPHAL_SURFACE pSurface,PCCHAR pSurfaceName,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 * pbAllocated,MOS_HW_RESOURCE_DEF resUsageType,MOS_TILE_MODE_GMM tileModeByForce,Mos_MemPool memType,bool isNotLockable)166 MOS_STATUS VpHal_ReAllocateSurface(
167     PMOS_INTERFACE          pOsInterface,
168     PVPHAL_SURFACE          pSurface,
169     PCCHAR                  pSurfaceName,
170     MOS_FORMAT              Format,
171     MOS_GFXRES_TYPE         DefaultResType,
172     MOS_TILE_TYPE           DefaultTileType,
173     uint32_t                dwWidth,
174     uint32_t                dwHeight,
175     bool                    bCompressible,
176     MOS_RESOURCE_MMC_MODE   CompressionMode,
177     bool*                   pbAllocated,
178     MOS_HW_RESOURCE_DEF     resUsageType,
179     MOS_TILE_MODE_GMM       tileModeByForce,
180     Mos_MemPool             memType,
181     bool                    isNotLockable)
182 {
183     MOS_STATUS              eStatus;
184     VPHAL_GET_SURFACE_INFO  Info;
185     MOS_ALLOC_GFXRES_PARAMS AllocParams;
186     MOS_GFXRES_FREE_FLAGS   resFreeFlags = {0};
187 
188     //---------------------------------
189     VPHAL_PUBLIC_ASSERT(pOsInterface);
190     VPHAL_PUBLIC_ASSERT(pSurface);
191     //---------------------------------
192 
193     eStatus      = MOS_STATUS_SUCCESS;
194     *pbAllocated = false;
195 
196     // bCompressible should be compared with bCompressible since it is inited by bCompressible in previous call
197     // TileType of surface should be compared since we need to reallocate surface if TileType changes
198     if (!Mos_ResourceIsNull(&pSurface->OsResource)        &&
199         (pSurface->dwWidth         == dwWidth)            &&
200         (pSurface->dwHeight        == dwHeight)           &&
201         (pSurface->Format          == Format)             &&
202         (pSurface->bCompressible   == bCompressible)      &&
203         (pSurface->CompressionMode == CompressionMode)    &&
204         (pSurface->TileType        == DefaultTileType     ||
205         MOS_TILE_Y                 == DefaultTileType     &&
206         IS_Y_MAJOR_TILE_FORMAT(pSurface->TileType)))
207     {
208         goto finish;
209     }
210 
211     if (pOsInterface->bOptimizeCpuTiming                  &&
212         (DefaultResType == MOS_GFXRES_BUFFER)             &&
213         (pSurface->dwWidth  >= dwWidth))
214     {
215         goto finish;
216     }
217 
218     MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS));
219 
220     VpHal_AllocParamsInitType(&AllocParams, pSurface, DefaultResType, DefaultTileType);
221 
222     AllocParams.dwWidth         = dwWidth;
223     AllocParams.dwHeight        = dwHeight;
224     AllocParams.Format          = Format;
225     AllocParams.bIsCompressible = bCompressible;
226     AllocParams.CompressionMode = CompressionMode;
227     AllocParams.pBufName        = pSurfaceName;
228     AllocParams.dwArraySize     = 1;
229     AllocParams.ResUsageType    = resUsageType;
230     AllocParams.m_tileModeByForce = tileModeByForce;
231     AllocParams.dwMemType       = memType;
232     AllocParams.Flags.bNotLockable = isNotLockable;
233 
234     // Delete resource if already allocated
235     //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
236     if (IsSyncFreeNeededForMMCSurface(pSurface, pOsInterface))
237     {
238         resFreeFlags.SynchronousDestroy = 1;
239         VPHAL_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource %s", pSurfaceName);
240     }
241     pOsInterface->pfnFreeResourceWithFlag(pOsInterface, &(pSurface->OsResource), resFreeFlags.Value);
242 
243     // Allocate surface
244     VPHAL_PUBLIC_CHK_STATUS(pOsInterface->pfnAllocateResource(
245         pOsInterface,
246         &AllocParams,
247         &pSurface->OsResource));
248 
249     // Get surface information
250     MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO));
251 
252     // Pre-set to get surface info
253     pSurface->Format = Format;
254 
255     VPHAL_PUBLIC_CHK_STATUS(VpHal_GetSurfaceInfo(pOsInterface, &Info, pSurface));
256 
257     *pbAllocated     = true;
258 
259     MT_LOG7(MT_VP_HAL_REALLOC_SURF, MT_NORMAL, MT_VP_HAL_INTER_SURF_TYPE, pSurfaceName ? *((int64_t*)pSurfaceName) : 0,
260         MT_SURF_WIDTH, dwWidth, MT_SURF_HEIGHT, dwHeight, MT_SURF_MOS_FORMAT, Format, MT_SURF_TILE_MODE, pSurface->TileModeGMM,
261         MT_SURF_COMP_ABLE, pSurface->bCompressible, MT_SURF_COMP_MODE, pSurface->CompressionMode);
262 
263 finish:
264     VPHAL_PUBLIC_ASSERT(eStatus == MOS_STATUS_SUCCESS);
265     return eStatus;
266 }
267 
268 //!
269 //! \brief    Reads the Surface contents and copy to the Dst Buffer
270 //! \details  Reads the Surface contents and copy to the Dst Buffer
271 //!           - 1 lock surface
272 //!           - 2 copy surface data to pDst
273 //!           - 3 unlock surface
274 //! \param    [in] pOsInterface
275 //!           Pointer to MOS_INTERFACE
276 //! \param    [in] pSurface
277 //!           Pointer to VPHAL_SURFACE
278 //! \param    [in] uBpp
279 //!           bit per pixel of surface contents
280 //! \param    [out] pDst
281 //!           output buffer to store Surface contents
282 //! \return   MOS_STATUS
283 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
284 //!
VpHal_ReadSurface(PMOS_INTERFACE pOsInterface,PVPHAL_SURFACE pSurface,uint32_t uBpp,uint8_t * pDst)285 MOS_STATUS VpHal_ReadSurface (
286     PMOS_INTERFACE      pOsInterface,
287     PVPHAL_SURFACE      pSurface,
288     uint32_t            uBpp,
289     uint8_t*            pDst)
290 {
291     MOS_STATUS      eStatus;
292     uint8_t*        pSrc;
293     uint8_t*        pTempSrc;
294     uint8_t*        pTempDst;
295     uint32_t        uSize;
296     uint32_t        uWidthInBytes;
297     uint32_t        uY;
298     uint32_t        uZ;
299     MOS_LOCK_PARAMS LockFlags;
300 
301     //----------------------------------------------
302     VPHAL_PUBLIC_ASSERT(pSurface);
303     VPHAL_PUBLIC_ASSERT(pSurface->dwWidth   > 0);
304     VPHAL_PUBLIC_ASSERT(pSurface->dwHeight  > 0);
305     VPHAL_PUBLIC_ASSERT(pSurface->dwDepth   > 0);
306     VPHAL_PUBLIC_ASSERT(pSurface->dwPitch >= pSurface->dwWidth);
307     VPHAL_PUBLIC_ASSERT(uBpp > 0);
308     VPHAL_PUBLIC_ASSERT(pDst);
309     VPHAL_PUBLIC_ASSERT(!Mos_ResourceIsNull(&pSurface->OsResource));
310     //----------------------------------------------
311 
312     MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
313 
314     LockFlags.ReadOnly = 1;
315 
316     pSrc = (uint8_t*)pOsInterface->pfnLockResource(
317                     pOsInterface,
318                     &pSurface->OsResource,
319                     &LockFlags);
320     VPHAL_PUBLIC_CHK_NULL(pSrc);
321 
322     // Calculate Size in Bytes
323     uSize = pSurface->dwWidth * pSurface->dwHeight * pSurface->dwDepth * uBpp/8;
324     uWidthInBytes = pSurface->dwWidth * uBpp / 8;
325     if (pSurface->dwPitch == uWidthInBytes)
326     {
327         MOS_SecureMemcpy(pDst, uSize, pSrc, uSize);
328     }
329     else
330     {
331         pTempSrc    = pSrc;
332         pTempDst    = pDst;
333 
334         for (uZ = 0; uZ < pSurface->dwDepth; uZ++)
335         {
336             for (uY = 0; uY < pSurface->dwHeight; uY++)
337             {
338                 MOS_SecureMemcpy(pTempDst, uWidthInBytes, pTempSrc, uWidthInBytes);
339                 pTempSrc += pSurface->dwPitch;
340                 pTempDst += uWidthInBytes;
341             }
342         }
343     }
344 
345     VPHAL_PUBLIC_CHK_STATUS(pOsInterface->pfnUnlockResource(pOsInterface, &pSurface->OsResource));
346 
347 finish:
348     return eStatus;
349 }
350 
351 //!
352 //! \brief    Copy Data from input Buffer to the Surface contents
353 //! \details  Copy Data from input Buffer to the Surface contents
354 //!           - 1 lock surface
355 //!           - 2 copy data from pSrc to Surface
356 //!           - 3 unlock surface
357 //! \param    [in] pOsInterface
358 //!           Pointer to MOS_INTERFACE
359 //! \param    [out] pSurface
360 //!           Pointer to VPHAL_SURFACE
361 //! \param    [in] uBpp
362 //!           bit per pixel of input buffer
363 //! \param    [in] pSrc
364 //!           Input buffer to store Surface contents
365 //! \return   MOS_STATUS
366 //!           MOS_STATUS_SUCCESS if success. Error code otherwise
367 //!
VpHal_WriteSurface(PMOS_INTERFACE pOsInterface,PVPHAL_SURFACE pSurface,uint32_t uBpp,const uint8_t * pSrc)368 MOS_STATUS VpHal_WriteSurface (
369     PMOS_INTERFACE      pOsInterface,
370     PVPHAL_SURFACE      pSurface,
371     uint32_t            uBpp,
372     const uint8_t*      pSrc)
373 {
374     MOS_STATUS          eStatus;
375     uint8_t*            pDst;
376     uint8_t*            pTempSrc;
377     uint8_t*            pTempDst;
378     uint32_t            uWidthInBytes;
379     uint32_t            uSize;
380     uint32_t            uY;
381     uint32_t            uZ;
382     MOS_LOCK_PARAMS     LockFlags;
383 
384     //----------------------------------------------
385     VPHAL_PUBLIC_ASSERT(pSurface);
386     VPHAL_PUBLIC_ASSERT(pSurface->dwWidth   > 0);
387     VPHAL_PUBLIC_ASSERT(pSurface->dwHeight  > 0);
388     VPHAL_PUBLIC_ASSERT(pSurface->dwDepth   > 0);
389     VPHAL_PUBLIC_ASSERT(pSurface->dwPitch >= pSurface->dwWidth);
390     VPHAL_PUBLIC_ASSERT(uBpp > 0);
391     VPHAL_PUBLIC_ASSERT(pSrc);
392     VPHAL_PUBLIC_ASSERT(!Mos_ResourceIsNull(&pSurface->OsResource));
393     //----------------------------------------------
394 
395     MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS));
396 
397     LockFlags.WriteOnly = 1;
398 
399     pDst = (uint8_t*)pOsInterface->pfnLockResource(
400                 pOsInterface,
401                 &pSurface->OsResource,
402                 &LockFlags);
403     VPHAL_PUBLIC_CHK_NULL(pDst);
404 
405     // Calculate Size in Bytes
406     uSize = pSurface->dwWidth * pSurface->dwHeight * pSurface->dwDepth * uBpp/8;
407     uWidthInBytes = pSurface->dwWidth * uBpp/8;
408 
409     if (pSurface->dwPitch == uWidthInBytes)
410     {
411         MOS_SecureMemcpy(pDst, uSize, pSrc, uSize);
412     }
413     else
414     {
415         pTempSrc    = (uint8_t*)pSrc;
416         pTempDst    = pDst;
417 
418         for (uZ = 0; uZ < pSurface->dwDepth; uZ++)
419         {
420             for (uY = 0; uY < pSurface->dwHeight; uY++)
421             {
422                 MOS_SecureMemcpy(pTempDst, uWidthInBytes, pTempSrc, uWidthInBytes);
423                 pTempSrc += uWidthInBytes;
424                 pTempDst += pSurface->dwPitch;
425             }
426         }
427     }
428 
429     VPHAL_PUBLIC_CHK_STATUS(pOsInterface->pfnUnlockResource(pOsInterface, &pSurface->OsResource));
430 
431 finish:
432     return eStatus;
433 }
434 
435 //!
436 //! \brief    Decide whether Chroma up sampling is needed
437 //! \param    [in] pSource
438 //!           Pointer to Source Surface
439 //! \param    [in] pTarget
440 //!           Pointer to Target Surface
441 //! \return   bool
442 //!           Return true if Chroma up sampling is needed, otherwise false
443 //!
VpHal_IsChromaUpSamplingNeeded(PVPHAL_SURFACE pSource,PVPHAL_SURFACE pTarget)444 bool VpHal_IsChromaUpSamplingNeeded(
445     PVPHAL_SURFACE          pSource,
446     PVPHAL_SURFACE          pTarget)
447 {
448     bool                  bChromaUpSampling;
449     VPHAL_COLORPACK       srcColorPack, dstColorPack;
450 
451     VPHAL_PUBLIC_ASSERT(pSource);
452     VPHAL_PUBLIC_ASSERT(pTarget);
453 
454     bChromaUpSampling = false;
455 
456     srcColorPack = VpHalDDIUtils::GetSurfaceColorPack(pSource->Format);
457     dstColorPack = VpHalDDIUtils::GetSurfaceColorPack(pTarget->Format);
458 
459     if ((srcColorPack == VPHAL_COLORPACK_420 &&
460         (dstColorPack == VPHAL_COLORPACK_422 || dstColorPack == VPHAL_COLORPACK_444)) ||
461         (srcColorPack == VPHAL_COLORPACK_422 && dstColorPack == VPHAL_COLORPACK_444))
462     {
463         bChromaUpSampling = true;
464     }
465 
466     return bChromaUpSampling;
467 }
468 
469 //!
470 //! \brief    Decide whether Chroma down sampling is needed
471 //! \param    [in] pSource
472 //!           Pointer to Source Surface
473 //! \param    [in] pTarget
474 //!           Pointer to Target Surface
475 //! \return   bool
476 //!           Return true if Chroma down sampling is needed, otherwise false
477 //!
VpHal_IsChromaDownSamplingNeeded(PVPHAL_SURFACE pSource,PVPHAL_SURFACE pTarget)478 bool VpHal_IsChromaDownSamplingNeeded(
479     PVPHAL_SURFACE          pSource,
480     PVPHAL_SURFACE          pTarget)
481 {
482     bool                  bChromaDownSampling;
483     VPHAL_COLORPACK       srcColorPack, dstColorPack;
484 
485     VPHAL_PUBLIC_ASSERT(pSource);
486     VPHAL_PUBLIC_ASSERT(pTarget);
487 
488     bChromaDownSampling = false;
489 
490     srcColorPack = VpHalDDIUtils::GetSurfaceColorPack(pSource->Format);
491     dstColorPack = VpHalDDIUtils::GetSurfaceColorPack(pTarget->Format);
492 
493     if ((srcColorPack == VPHAL_COLORPACK_444 &&
494         (dstColorPack == VPHAL_COLORPACK_422 || dstColorPack == VPHAL_COLORPACK_420)) ||
495         (srcColorPack == VPHAL_COLORPACK_422 && dstColorPack == VPHAL_COLORPACK_420))
496     {
497         bChromaDownSampling = true;
498     }
499 
500     return bChromaDownSampling;
501 }
502 
503 //!
504 //! \brief      Get the scale ratio
505 //! \details    Get the scale ratio from input surface to output surface
506 //! \param      [in] pSource
507 //!             Pointer to input Surface
508 //! \param      [in] pTarget
509 //!             Pointer to output Surface
510 //! \param      [out] pfScaleX
511 //!             Pointer to scaling ratio x
512 //! \param      [out] pfScaleY
513 //!             Pointer to scaling ratio y
514 //! \return     void
515 //!
VpHal_GetScalingRatio(PVPHAL_SURFACE pSource,PVPHAL_SURFACE pTarget,float * pfScaleX,float * pfScaleY)516 void VpHal_GetScalingRatio(
517     PVPHAL_SURFACE              pSource,
518     PVPHAL_SURFACE              pTarget,
519     float*                      pfScaleX,
520     float*                      pfScaleY)
521 {
522     MOS_UNUSED(pTarget);
523 
524     VPHAL_PUBLIC_ASSERT(pSource);
525     VPHAL_PUBLIC_ASSERT(pTarget);
526     VPHAL_PUBLIC_ASSERT(pfScaleX);
527     VPHAL_PUBLIC_ASSERT(pfScaleY);
528 
529     float fScaleX = 0.0;
530     float fScaleY = 0.0;
531 
532     // Source rectangle is pre-rotated, destination rectangle is post-rotated.
533     if (pSource->Rotation == VPHAL_ROTATION_IDENTITY ||
534         pSource->Rotation == VPHAL_ROTATION_180 ||
535         pSource->Rotation == VPHAL_MIRROR_HORIZONTAL ||
536         pSource->Rotation == VPHAL_MIRROR_VERTICAL)
537     {
538         fScaleX = (float)(pSource->rcDst.right - pSource->rcDst.left) /
539                   (float)(pSource->rcSrc.right - pSource->rcSrc.left);
540         fScaleY = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
541                   (float)(pSource->rcSrc.bottom - pSource->rcSrc.top);
542     }
543     else
544     {
545         // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 ||
546         // VPHAL_ROTATE_90_MIRROR_HORIZONTAL || VPHAL_ROTATE_90_MIRROR_VERTICAL
547         fScaleX = (float)(pSource->rcDst.bottom - pSource->rcDst.top) /
548                   (float)(pSource->rcSrc.right - pSource->rcSrc.left);
549         fScaleY = (float)(pSource->rcDst.right - pSource->rcDst.left) /
550                   (float)(pSource->rcSrc.bottom - pSource->rcSrc.top);
551     }
552 
553     *pfScaleX = fScaleX;
554     *pfScaleY = fScaleY;
555 }
556 
557 //! \brief    Transfer float type to half precision float type
558 //! \details  Transfer float type to half precision float (16bit) type
559 //! \param    [in] fInputA
560 //!           input FP32 number
561 //! \return   uint16_t
562 //!           half precision float value in bit
563 //!
VpHal_FloatToHalfFloatA(float fInputA)564 uint16_t VpHal_FloatToHalfFloatA(float fInputA)
565 {
566 
567     FP32 fInput        = *(FP32*)(&fInputA);
568     FP16 fOutput       = { 0 };
569 
570     // Based on ISPC reference code (with minor modifications)
571     if (fInput.Exponent == 0) // Signed zero/denormal (which will underflow)
572     {
573         fOutput.Exponent = 0;
574     }
575     else if (fInput.Exponent == 255) // Inf or NaN (all exponent bits set)
576     {
577         fOutput.Exponent = 31;
578         fOutput.Mantissa = fInput.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf
579     }
580     else // Normalized number
581     {
582         // Exponent unbias the single, then bias the halfp
583         int newexp = fInput.Exponent - 127 + 15;
584         if (newexp >= 31) // Overflow, return signed infinity
585         {
586             fOutput.Exponent = 31;
587         }
588         else if (newexp <= 0) // Underflow
589         {
590             if ((14 - newexp) <= 24) // Mantissa might be non-zero
591             {
592                 uint32_t mant = fInput.Mantissa | 0x800000; // Hidden 1 bit
593                 fOutput.Mantissa = mant >> (14 - newexp);
594                 if ((mant >> (13 - newexp)) & 1) // Check for rounding
595                 {
596                     fOutput.u++; // Round, might overflow into exp bit, but this is OK
597                 }
598             }
599         }
600         else
601         {
602             fOutput.Exponent = newexp;
603             fOutput.Mantissa = fInput.Mantissa >> 13;
604             if (fInput.Mantissa & 0x1000) // Check for rounding
605             {
606                 fOutput.u++; // Round, might overflow to inf, this is OK
607             }
608         }
609     }
610 
611     fOutput.Sign = fInput.Sign;
612     uint16_t res = *(uint16_t*)(&fOutput);
613     return res;
614 }
615