| /* |
| * Copyright (c) 2009-2020, Intel Corporation |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
| * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| * OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| //! |
| //! \file vphal_common.c |
| //! \brief Definition common utilities for vphal |
| //! \details Definition common utilities for vphal including: |
| //! some macro, enum, union, structure, function |
| //! |
| #include "vphal.h" |
| #include "hal_kerneldll.h" |
| #include "mos_os.h" |
| |
| #include <math.h> |
| |
| #if EMUL || VPHAL_LIB |
| #include "support.h" |
| #endif |
| |
| //! |
| //! \brief Performs Color Space Convert for Sample 8 bit Using Specified Coeff Matrix |
| //! \details Performs Color Space Convert from Src Color Spase to Dst Color Spase |
| // Using Secified input CSC Coeff Matrix |
| //! \param [out] pOutput |
| //! Pointer to VPHAL_COLOR_SAMPLE_8 |
| //! \param [in] pInput |
| //! Pointer to VPHAL_COLOR_SAMPLE_8 |
| //! \param [in] srcCspace |
| //! Source Color Space |
| //! \param [in] dstCspace |
| //! Dest Color Space |
| //! \param [in] piCscMatrix |
| //! input CSC coeff Matrxi |
| //! \return bool |
| //! Return true if successful, otherwise false |
| //! |
| bool VpHal_CSC( |
| VPHAL_COLOR_SAMPLE_8 *pOutput, |
| VPHAL_COLOR_SAMPLE_8 *pInput, |
| VPHAL_CSPACE srcCspace, |
| VPHAL_CSPACE dstCspace, |
| int32_t* piCscMatrix) |
| { |
| bool bResult; |
| int32_t A, R, G, B; |
| int32_t Y1, U1, V1; |
| |
| bResult = true; |
| |
| Y1 = R = pInput->YY; |
| U1 = G = pInput->Cb; |
| V1 = B = pInput->Cr; |
| A = pInput->Alpha; |
| |
| if (srcCspace == dstCspace) |
| { |
| // no conversion needed |
| if ((dstCspace == CSpace_sRGB) || (dstCspace == CSpace_stRGB) || IS_COLOR_SPACE_BT2020_RGB(dstCspace)) |
| { |
| pOutput->A = (uint8_t)A; |
| pOutput->R = (uint8_t)R; |
| pOutput->G = (uint8_t)G; |
| pOutput->B = (uint8_t)B; |
| } |
| else |
| { |
| pOutput->a = (uint8_t)A; |
| pOutput->Y = (uint8_t)Y1; |
| pOutput->U = (uint8_t)U1; |
| pOutput->V = (uint8_t)V1; |
| } |
| } |
| else |
| { |
| // conversion needed |
| R = (Y1 * piCscMatrix[0] + U1 * piCscMatrix[1] + |
| V1 * piCscMatrix[2] + piCscMatrix[3] + 0x00080000) >> 20; |
| G = (Y1 * piCscMatrix[4] + U1 * piCscMatrix[5] + |
| V1 * piCscMatrix[6] + piCscMatrix[7] + 0x00080000) >> 20; |
| B = (Y1 * piCscMatrix[8] + U1 * piCscMatrix[9] + |
| V1 * piCscMatrix[10] + piCscMatrix[11] + 0x00080000) >> 20; |
| |
| switch (dstCspace) |
| { |
| case CSpace_sRGB: |
| pOutput->A = (uint8_t)A; |
| pOutput->R = MOS_MIN(MOS_MAX(0,R),255); |
| pOutput->G = MOS_MIN(MOS_MAX(0,G),255); |
| pOutput->B = MOS_MIN(MOS_MAX(0,B),255); |
| break; |
| |
| case CSpace_stRGB: |
| pOutput->A = (uint8_t)A; |
| pOutput->R = MOS_MIN(MOS_MAX(16,R),235); |
| pOutput->G = MOS_MIN(MOS_MAX(16,G),235); |
| pOutput->B = MOS_MIN(MOS_MAX(16,B),235); |
| break; |
| |
| case CSpace_BT601: |
| case CSpace_BT709: |
| pOutput->a = (uint8_t)A; |
| pOutput->Y = MOS_MIN(MOS_MAX(16,R),235); |
| pOutput->U = MOS_MIN(MOS_MAX(16,G),240); |
| pOutput->V = MOS_MIN(MOS_MAX(16,B),240); |
| break; |
| |
| case CSpace_xvYCC601: |
| case CSpace_xvYCC709: |
| case CSpace_BT601_FullRange: |
| case CSpace_BT709_FullRange: |
| pOutput->a = (uint8_t)A; |
| pOutput->Y = MOS_MIN(MOS_MAX(0,R),255); |
| pOutput->U = MOS_MIN(MOS_MAX(0,G),255); |
| pOutput->V = MOS_MIN(MOS_MAX(0,B),255); |
| break; |
| |
| default: |
| VPHAL_PUBLIC_ASSERTMESSAGE("Unsupported Output ColorSpace."); |
| bResult = false; |
| break; |
| } |
| } |
| |
| return bResult; |
| } |
| |
| //! |
| //! \brief Performs Color Space Convert for Sample 8 bit |
| //! \details Performs Color Space Convert from Src Color Spase to Dst Color Spase |
| //! \param [out] pOutput |
| //! Pointer to VPHAL_COLOR_SAMPLE_8 |
| //! \param [in] pInput |
| //! Pointer to VPHAL_COLOR_SAMPLE_8 |
| //! \param [in] srcCspace |
| //! Source Color Space |
| //! \param [in] dstCspace |
| //! Dest Color Space |
| //! \return bool |
| //! Return true if successful, otherwise false |
| //! |
| bool VpHal_CSC_8( |
| VPHAL_COLOR_SAMPLE_8 *pOutput, |
| VPHAL_COLOR_SAMPLE_8 *pInput, |
| VPHAL_CSPACE srcCspace, |
| VPHAL_CSPACE dstCspace) |
| { |
| float pfCscMatrix[12] = {0}; |
| int32_t piCscMatrix[12] = {0}; |
| bool bResult; |
| int32_t i; |
| |
| KernelDll_GetCSCMatrix(srcCspace, dstCspace, pfCscMatrix); |
| |
| // convert float to fixed point format for the 3x4 matrix |
| for (i = 0; i < 12; i++) |
| { |
| // multiply by 2^20 and round up |
| piCscMatrix[i] = (int32_t)((pfCscMatrix[i] * 1048576.0f) + 0.5f); |
| } |
| |
| bResult = VpHal_CSC(pOutput, pInput, srcCspace, dstCspace, piCscMatrix); |
| |
| return bResult; |
| } |
| |
| //! |
| //! \brief Get CSC matrix in a form usable by Vebox, SFC and IECP kernels |
| //! \param [in] SrcCspace |
| //! Source Cspace |
| //! \param [in] DstCspace |
| //! Destination Cspace |
| //! \param [out] pfCscCoeff |
| //! [3x3] Coefficients matrix |
| //! \param [out] pfCscInOffset |
| //! [3x1] Input Offset matrix |
| //! \param [out] pfCscOutOffset |
| //! [3x1] Output Offset matrix |
| //! \return void |
| //! |
| void VpHal_GetCscMatrix( |
| VPHAL_CSPACE SrcCspace, // [in] Source Cspace |
| VPHAL_CSPACE DstCspace, // [in] Destination Cspace |
| float* pfCscCoeff, // [out] [3x3] Coefficients matrix |
| float* pfCscInOffset, // [out] [3x1] Input Offset matrix |
| float* pfCscOutOffset) // [out] [3x1] Output Offset matrix |
| { |
| float fCscMatrix[12] = {0}; |
| int32_t i; |
| |
| KernelDll_GetCSCMatrix( |
| SrcCspace, |
| DstCspace, |
| fCscMatrix); |
| |
| // Copy [3x3] into Coeff |
| for (i = 0; i < 3; i++) |
| { |
| MOS_SecureMemcpy( |
| &pfCscCoeff[i*3], |
| sizeof(float) * 3, |
| &fCscMatrix[i*4], |
| sizeof(float) * 3); |
| } |
| |
| // Get the input offsets |
| switch(SrcCspace) |
| { |
| CASE_YUV_CSPACE_LIMITEDRANGE: |
| pfCscInOffset[0] = -16.0F; |
| pfCscInOffset[1] = -128.0F; |
| pfCscInOffset[2] = -128.0F; |
| break; |
| |
| CASE_YUV_CSPACE_FULLRANGE: |
| pfCscInOffset[0] = 0.0F; |
| pfCscInOffset[1] = -128.0F; |
| pfCscInOffset[2] = -128.0F; |
| break; |
| |
| case CSpace_sRGB: |
| pfCscInOffset[0] = 0.0F; |
| pfCscInOffset[1] = 0.0F; |
| pfCscInOffset[2] = 0.0F; |
| break; |
| |
| case CSpace_stRGB: |
| pfCscInOffset[0] = -16.0F; |
| pfCscInOffset[1] = -16.0F; |
| pfCscInOffset[2] = -16.0F; |
| break; |
| |
| //BT2020 YUV->RGB |
| case CSpace_BT2020: |
| pfCscInOffset[0] = -16.0F; |
| pfCscInOffset[1] = -128.0F; |
| pfCscInOffset[2] = -128.0F; |
| break; |
| |
| case CSpace_BT2020_FullRange: |
| pfCscInOffset[0] = 0.0F; |
| pfCscInOffset[1] = -128.0F; |
| pfCscInOffset[2] = -128.0F; |
| break; |
| |
| //BT2020 RGB->YUV |
| case CSpace_BT2020_RGB: |
| pfCscInOffset[0] = 0.0F; |
| pfCscInOffset[1] = 0.0F; |
| pfCscInOffset[2] = 0.0F; |
| break; |
| |
| //BT2020 RGB->YUV |
| case CSpace_BT2020_stRGB: |
| pfCscInOffset[0] = -16.0F; |
| pfCscInOffset[1] = -16.0F; |
| pfCscInOffset[2] = -16.0F; |
| break; |
| |
| default: |
| VPHAL_PUBLIC_ASSERTMESSAGE("Unsupported Input ColorSpace for Vebox."); |
| } |
| |
| // Get the output offsets |
| switch(DstCspace) |
| { |
| CASE_YUV_CSPACE_LIMITEDRANGE: |
| pfCscOutOffset[0] = 16.0F; |
| pfCscOutOffset[1] = 128.0F; |
| pfCscOutOffset[2] = 128.0F; |
| break; |
| |
| CASE_YUV_CSPACE_FULLRANGE: |
| pfCscOutOffset[0] = 0.0F; |
| pfCscOutOffset[1] = 128.0F; |
| pfCscOutOffset[2] = 128.0F; |
| break; |
| |
| case CSpace_sRGB: |
| pfCscOutOffset[0] = 0.0F; |
| pfCscOutOffset[1] = 0.0F; |
| pfCscOutOffset[2] = 0.0F; |
| break; |
| |
| case CSpace_stRGB: |
| pfCscOutOffset[0] = 16.0F; |
| pfCscOutOffset[1] = 16.0F; |
| pfCscOutOffset[2] = 16.0F; |
| break; |
| |
| //BT2020 RGB->YUV |
| case CSpace_BT2020: |
| pfCscOutOffset[0] = 16.0F; |
| pfCscOutOffset[1] = 128.0F; |
| pfCscOutOffset[2] = 128.0F; |
| break; |
| |
| case CSpace_BT2020_FullRange: |
| pfCscOutOffset[0] = 0.0F; |
| pfCscOutOffset[1] = 128.0F; |
| pfCscOutOffset[2] = 128.0F; |
| break; |
| |
| case CSpace_BT2020_RGB: |
| pfCscOutOffset[0] = 0.0F; |
| pfCscOutOffset[1] = 0.0F; |
| pfCscOutOffset[2] = 0.0F; |
| break; |
| |
| case CSpace_BT2020_stRGB: |
| pfCscOutOffset[0] = 16.0F; |
| pfCscOutOffset[1] = 16.0F; |
| pfCscOutOffset[2] = 16.0F; |
| break; |
| |
| default: |
| VPHAL_PUBLIC_ASSERTMESSAGE("Unsupported Output ColorSpace for Vebox."); |
| } |
| } |
| |
| //! |
| //! \brief sinc |
| //! \details Calculate sinc(x) |
| //! \param [in] x |
| //! float |
| //! \return float |
| //! sinc(x) |
| //! |
| float VpHal_Sinc(float x) |
| { |
| return (VPHAL_ABS(x) < 1e-9f) ? 1.0F : (float)(sin(x) / x); |
| } |
| |
| //! |
| //! \brief Lanczos |
| //! \details Calculate lanczos(x) |
| //! Basic formula is: lanczos(x)= VpHal_Sinc(x) * VpHal_Sinc(x / fLanczosT) |
| //! \param [in] x |
| //! float |
| //! \param [in] dwNumEntries |
| //! dword |
| //! \param [in] fLanczosT |
| //! |
| //! \return float |
| //! lanczos(x) |
| //! |
| float VpHal_Lanczos(float x, uint32_t dwNumEntries, float fLanczosT) |
| { |
| uint32_t dwNumHalfEntries; |
| |
| dwNumHalfEntries = dwNumEntries >> 1; |
| if (fLanczosT < dwNumHalfEntries) |
| { |
| fLanczosT = (float)dwNumHalfEntries; |
| } |
| |
| if (VPHAL_ABS(x) >= dwNumHalfEntries) |
| { |
| return 0.0; |
| } |
| |
| x *= VPHAL_PI; |
| |
| return VpHal_Sinc(x) * VpHal_Sinc(x / fLanczosT); |
| } |
| |
| bool isSyncFreeNeededForMMCSurface(PVPHAL_SURFACE pSurface, PMOS_INTERFACE pOsInterface) |
| { |
| if (nullptr == pSurface || nullptr == pOsInterface) |
| { |
| return false; |
| } |
| |
| //Compressed surface aux table update is after resource dealloction, aux table update need wait the WLs complete |
| //the sync deallocation flag will make sure deallocation API return after all surface related WL been completed and resource been destroyed by OS |
| auto *pSkuTable = pOsInterface->pfnGetSkuTable(pOsInterface); |
| if (pSkuTable && |
| MEDIA_IS_SKU(pSkuTable, FtrE2ECompression) && //Compression enabled platform |
| !MEDIA_IS_SKU(pSkuTable, FtrFlatPhysCCS) && //NOT DGPU compression |
| ((pSurface->bCompressible) && (pSurface->CompressionMode != MOS_MMC_DISABLED))) //Compressed enabled surface |
| { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| //! |
| //! \brief Allocates the Surface |
| //! \details Allocates the Surface |
| //! - if the surface is not already allocated OR |
| //! - resource dimenisions OR format changed |
| //! \param [in] pOsInterface |
| //! Pointer to MOS_INTERFACE |
| //! \param [in,out] pSurface |
| //! Pointer to VPHAL_SURFACE |
| //! \param [in] pSurfaceName |
| //! Pointer to surface name |
| //! \param [in] Format |
| //! Expected MOS_FORMAT |
| //! \param [in] DefaultResType |
| //! Expected Resource Type |
| //! \param [in] DefaultTileType |
| //! Expected Surface Tile Type |
| //! \param [in] dwWidth |
| //! Expected Surface Width |
| //! \param [in] dwHeight |
| //! Expected Surface Height |
| //! \param [in] bCompressible |
| //! Surface being compressible or not |
| //! \param [in] CompressionMode |
| //! Compression Mode |
| //! \param [out] pbAllocated |
| //! true if allocated, false for not |
| //! \param [in] resUsageType |
| //! resource usage type for caching |
| //! \param [in] tileModeByForce |
| //! Forced tile mode |
| //! \param [in] memType |
| //! vidoe memory location |
| //! \param [in] isNotLockable |
| //! true if surface not lockable |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success. Error code otherwise |
| //! |
| MOS_STATUS 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) |
| { |
| MOS_STATUS eStatus; |
| VPHAL_GET_SURFACE_INFO Info; |
| MOS_ALLOC_GFXRES_PARAMS AllocParams; |
| MOS_GFXRES_FREE_FLAGS resFreeFlags = {0}; |
| |
| //--------------------------------- |
| VPHAL_PUBLIC_ASSERT(pOsInterface); |
| VPHAL_PUBLIC_ASSERT(&pSurface->OsResource); |
| //--------------------------------- |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| *pbAllocated = false; |
| |
| // bCompressible should be compared with bCompressible since it is inited by bCompressible in previous call |
| // TileType of surface should be compared since we need to reallocate surface if TileType changes |
| if (!Mos_ResourceIsNull(&pSurface->OsResource) && |
| (pSurface->dwWidth == dwWidth) && |
| (pSurface->dwHeight == dwHeight) && |
| (pSurface->Format == Format) && |
| (pSurface->bCompressible == bCompressible) && |
| (pSurface->CompressionMode == CompressionMode) && |
| (pSurface->TileType == DefaultTileType)) |
| { |
| goto finish; |
| } |
| |
| MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS)); |
| |
| VpHal_AllocParamsInitType(&AllocParams, pSurface, DefaultResType, DefaultTileType); |
| |
| AllocParams.dwWidth = dwWidth; |
| AllocParams.dwHeight = dwHeight; |
| AllocParams.Format = Format; |
| AllocParams.bIsCompressible = bCompressible; |
| AllocParams.CompressionMode = CompressionMode; |
| AllocParams.pBufName = pSurfaceName; |
| AllocParams.dwArraySize = 1; |
| AllocParams.ResUsageType = resUsageType; |
| AllocParams.m_tileModeByForce = tileModeByForce; |
| AllocParams.dwMemType = memType; |
| AllocParams.Flags.bNotLockable = isNotLockable; |
| |
| // Delete resource if already allocated |
| //if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update |
| if (isSyncFreeNeededForMMCSurface(pSurface, pOsInterface)) |
| { |
| resFreeFlags.SynchronousDestroy = 1; |
| VPHAL_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource %s", pSurfaceName); |
| } |
| pOsInterface->pfnFreeResourceWithFlag(pOsInterface, &(pSurface->OsResource), resFreeFlags.Value); |
| |
| // Allocate surface |
| VPHAL_PUBLIC_CHK_STATUS(pOsInterface->pfnAllocateResource( |
| pOsInterface, |
| &AllocParams, |
| &pSurface->OsResource)); |
| |
| // Get surface information |
| MOS_ZeroMemory(&Info, sizeof(VPHAL_GET_SURFACE_INFO)); |
| |
| // Pre-set to get surface info |
| pSurface->Format = Format; |
| |
| VPHAL_PUBLIC_CHK_STATUS(VpHal_GetSurfaceInfo(pOsInterface, &Info, pSurface)); |
| |
| *pbAllocated = true; |
| |
| finish: |
| VPHAL_PUBLIC_ASSERT(eStatus == MOS_STATUS_SUCCESS); |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Reads the Surface contents and copy to the Dst Buffer |
| //! \details Reads the Surface contents and copy to the Dst Buffer |
| //! - 1 lock surface |
| //! - 2 copy surface data to pDst |
| //! - 3 unlock surface |
| //! \param [in] pOsInterface |
| //! Pointer to MOS_INTERFACE |
| //! \param [in] pSurface |
| //! Pointer to VPHAL_SURFACE |
| //! \param [in] uBpp |
| //! bit per pixel of surface contents |
| //! \param [out] pDst |
| //! output buffer to store Surface contents |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success. Error code otherwise |
| //! |
| MOS_STATUS VpHal_ReadSurface ( |
| PMOS_INTERFACE pOsInterface, |
| PVPHAL_SURFACE pSurface, |
| uint32_t uBpp, |
| uint8_t* pDst) |
| { |
| MOS_STATUS eStatus; |
| uint8_t* pSrc; |
| uint8_t* pTempSrc; |
| uint8_t* pTempDst; |
| uint32_t uSize; |
| uint32_t uWidthInBytes; |
| uint32_t uY; |
| uint32_t uZ; |
| MOS_LOCK_PARAMS LockFlags; |
| |
| //---------------------------------------------- |
| VPHAL_PUBLIC_ASSERT(pSurface); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwWidth > 0); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwHeight > 0); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwDepth > 0); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwPitch >= pSurface->dwWidth); |
| VPHAL_PUBLIC_ASSERT(uBpp > 0); |
| VPHAL_PUBLIC_ASSERT(pDst); |
| VPHAL_PUBLIC_ASSERT(!Mos_ResourceIsNull(&pSurface->OsResource)); |
| //---------------------------------------------- |
| |
| MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS)); |
| |
| LockFlags.ReadOnly = 1; |
| |
| pSrc = (uint8_t*)pOsInterface->pfnLockResource( |
| pOsInterface, |
| &pSurface->OsResource, |
| &LockFlags); |
| VPHAL_PUBLIC_CHK_NULL(pSrc); |
| |
| // Calculate Size in Bytes |
| uSize = pSurface->dwWidth * pSurface->dwHeight * pSurface->dwDepth * uBpp/8; |
| uWidthInBytes = pSurface->dwWidth * uBpp / 8; |
| if (pSurface->dwPitch == uWidthInBytes) |
| { |
| MOS_SecureMemcpy(pDst, uSize, pSrc, uSize); |
| } |
| else |
| { |
| pTempSrc = pSrc; |
| pTempDst = pDst; |
| |
| for (uZ = 0; uZ < pSurface->dwDepth; uZ++) |
| { |
| for (uY = 0; uY < pSurface->dwHeight; uY++) |
| { |
| MOS_SecureMemcpy(pTempDst, uWidthInBytes, pTempSrc, uWidthInBytes); |
| pTempSrc += pSurface->dwPitch; |
| pTempDst += uWidthInBytes; |
| } |
| } |
| } |
| |
| VPHAL_PUBLIC_CHK_STATUS(pOsInterface->pfnUnlockResource(pOsInterface, &pSurface->OsResource)); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Copy Data from input Buffer to the Surface contents |
| //! \details Copy Data from input Buffer to the Surface contents |
| //! - 1 lock surface |
| //! - 2 copy data from pSrc to Surface |
| //! - 3 unlock surface |
| //! \param [in] pOsInterface |
| //! Pointer to MOS_INTERFACE |
| //! \param [out] pSurface |
| //! Pointer to VPHAL_SURFACE |
| //! \param [in] uBpp |
| //! bit per pixel of input buffer |
| //! \param [in] pSrc |
| //! Input buffer to store Surface contents |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success. Error code otherwise |
| //! |
| MOS_STATUS VpHal_WriteSurface ( |
| PMOS_INTERFACE pOsInterface, |
| PVPHAL_SURFACE pSurface, |
| uint32_t uBpp, |
| const uint8_t* pSrc) |
| { |
| MOS_STATUS eStatus; |
| uint8_t* pDst; |
| uint8_t* pTempSrc; |
| uint8_t* pTempDst; |
| uint32_t uWidthInBytes; |
| uint32_t uSize; |
| uint32_t uY; |
| uint32_t uZ; |
| MOS_LOCK_PARAMS LockFlags; |
| |
| //---------------------------------------------- |
| VPHAL_PUBLIC_ASSERT(pSurface); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwWidth > 0); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwHeight > 0); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwDepth > 0); |
| VPHAL_PUBLIC_ASSERT(pSurface->dwPitch >= pSurface->dwWidth); |
| VPHAL_PUBLIC_ASSERT(uBpp > 0); |
| VPHAL_PUBLIC_ASSERT(pSrc); |
| VPHAL_PUBLIC_ASSERT(!Mos_ResourceIsNull(&pSurface->OsResource)); |
| //---------------------------------------------- |
| |
| MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS)); |
| |
| LockFlags.WriteOnly = 1; |
| |
| pDst = (uint8_t*)pOsInterface->pfnLockResource( |
| pOsInterface, |
| &pSurface->OsResource, |
| &LockFlags); |
| VPHAL_PUBLIC_CHK_NULL(pDst); |
| |
| // Calculate Size in Bytes |
| uSize = pSurface->dwWidth * pSurface->dwHeight * pSurface->dwDepth * uBpp/8; |
| uWidthInBytes = pSurface->dwWidth * uBpp/8; |
| |
| if (pSurface->dwPitch == uWidthInBytes) |
| { |
| MOS_SecureMemcpy(pDst, uSize, pSrc, uSize); |
| } |
| else |
| { |
| pTempSrc = (uint8_t*)pSrc; |
| pTempDst = pDst; |
| |
| for (uZ = 0; uZ < pSurface->dwDepth; uZ++) |
| { |
| for (uY = 0; uY < pSurface->dwHeight; uY++) |
| { |
| MOS_SecureMemcpy(pTempDst, uWidthInBytes, pTempSrc, uWidthInBytes); |
| pTempSrc += uWidthInBytes; |
| pTempDst += pSurface->dwPitch; |
| } |
| } |
| } |
| |
| VPHAL_PUBLIC_CHK_STATUS(pOsInterface->pfnUnlockResource(pOsInterface, &pSurface->OsResource)); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Get the color pack type of a surface |
| //! \details Map mos surface format to color pack format and return. |
| //! For unknown format return VPHAL_COLORPACK_UNKNOWN |
| //! \param [in] Format |
| //! MOS_FORMAT of a surface |
| //! \return VPHAL_COLORPACK |
| //! Color pack type of the surface |
| //! |
| VPHAL_COLORPACK VpHal_GetSurfaceColorPack ( |
| MOS_FORMAT Format) |
| { |
| VPHAL_COLORPACK ColorPack; |
| |
| ColorPack = VPHAL_COLORPACK_UNKNOWN; |
| |
| switch (Format) |
| { |
| case Format_Y8: |
| case Format_Y16S: |
| case Format_Y16U: |
| ColorPack = VPHAL_COLORPACK_400; |
| break; |
| |
| case Format_IMC1: |
| case Format_IMC2: |
| case Format_IMC3: |
| case Format_IMC4: |
| case Format_NV12: |
| case Format_NV21: |
| case Format_YV12: |
| case Format_I420: |
| case Format_IYUV: |
| case Format_P010: |
| case Format_P016: |
| ColorPack = VPHAL_COLORPACK_420; |
| break; |
| |
| case Format_YUY2: |
| case Format_YUYV: |
| case Format_YVYU: |
| case Format_UYVY: |
| case Format_VYUY: |
| case Format_P208: |
| case Format_422H: |
| case Format_422V: |
| case Format_Y210: |
| case Format_Y216: |
| ColorPack = VPHAL_COLORPACK_422; |
| break; |
| |
| case Format_A8R8G8B8: |
| case Format_X8R8G8B8: |
| case Format_A8B8G8R8: |
| case Format_X8B8G8R8: |
| case Format_A16B16G16R16: |
| case Format_A16R16G16B16: |
| case Format_R5G6B5: |
| case Format_R8G8B8: |
| case Format_RGBP: |
| case Format_BGRP: |
| case Format_Y416: |
| case Format_Y410: |
| case Format_AYUV: |
| case Format_AUYV: |
| case Format_444P: |
| case Format_R10G10B10A2: |
| case Format_B10G10R10A2: |
| case Format_A16B16G16R16F: |
| case Format_A16R16G16B16F: |
| ColorPack = VPHAL_COLORPACK_444; |
| break; |
| |
| case Format_400P: |
| ColorPack = VPHAL_COLORPACK_400; |
| break; |
| |
| case Format_411P: |
| ColorPack = VPHAL_COLORPACK_411; |
| break; |
| |
| default: |
| VPHAL_PUBLIC_ASSERTMESSAGE("Input format color pack unknown."); |
| ColorPack = VPHAL_COLORPACK_UNKNOWN; |
| break; |
| } |
| |
| return ColorPack; |
| } |
| |
| //! |
| //! \brief Decide whether Chroma up sampling is needed |
| //! \param [in] pSource |
| //! Pointer to Source Surface |
| //! \param [in] pTarget |
| //! Pointer to Target Surface |
| //! \return bool |
| //! Return true if Chroma up sampling is needed, otherwise false |
| //! |
| bool VpHal_IsChromaUpSamplingNeeded( |
| PVPHAL_SURFACE pSource, |
| PVPHAL_SURFACE pTarget) |
| { |
| bool bChromaUpSampling; |
| VPHAL_COLORPACK srcColorPack, dstColorPack; |
| |
| VPHAL_PUBLIC_ASSERT(pSource); |
| VPHAL_PUBLIC_ASSERT(pTarget); |
| |
| bChromaUpSampling = false; |
| |
| srcColorPack = VpHal_GetSurfaceColorPack(pSource->Format); |
| dstColorPack = VpHal_GetSurfaceColorPack(pTarget->Format); |
| |
| if ((srcColorPack == VPHAL_COLORPACK_420 && |
| (dstColorPack == VPHAL_COLORPACK_422 || dstColorPack == VPHAL_COLORPACK_444)) || |
| (srcColorPack == VPHAL_COLORPACK_422 && dstColorPack == VPHAL_COLORPACK_444)) |
| { |
| bChromaUpSampling = true; |
| } |
| |
| return bChromaUpSampling; |
| } |
| |
| //! |
| //! \brief Decide whether Chroma down sampling is needed |
| //! \param [in] pSource |
| //! Pointer to Source Surface |
| //! \param [in] pTarget |
| //! Pointer to Target Surface |
| //! \return bool |
| //! Return true if Chroma down sampling is needed, otherwise false |
| //! |
| bool VpHal_IsChromaDownSamplingNeeded( |
| PVPHAL_SURFACE pSource, |
| PVPHAL_SURFACE pTarget) |
| { |
| bool bChromaDownSampling; |
| VPHAL_COLORPACK srcColorPack, dstColorPack; |
| |
| VPHAL_PUBLIC_ASSERT(pSource); |
| VPHAL_PUBLIC_ASSERT(pTarget); |
| |
| bChromaDownSampling = false; |
| |
| srcColorPack = VpHal_GetSurfaceColorPack(pSource->Format); |
| dstColorPack = VpHal_GetSurfaceColorPack(pTarget->Format); |
| |
| if ((srcColorPack == VPHAL_COLORPACK_444 && |
| (dstColorPack == VPHAL_COLORPACK_422 || dstColorPack == VPHAL_COLORPACK_420)) || |
| (srcColorPack == VPHAL_COLORPACK_422 && dstColorPack == VPHAL_COLORPACK_420)) |
| { |
| bChromaDownSampling = true; |
| } |
| |
| return bChromaDownSampling; |
| } |
| |
| //! \brief Get the bit depth of a surface |
| //! \details Get bit depth of input mos surface format and return. |
| //! For unknown format return 0 |
| //! \param [in] Format |
| //! MOS_FORMAT of a surface |
| //! \return uint32_t |
| //! Bit depth of the surface |
| //! |
| uint32_t VpHal_GetSurfaceBitDepth ( |
| MOS_FORMAT Format) |
| { |
| uint32_t uBitDepth; |
| |
| uBitDepth = 0; |
| |
| switch (Format) |
| { |
| case Format_IMC1: |
| case Format_IMC2: |
| case Format_IMC3: |
| case Format_IMC4: |
| case Format_NV12: |
| case Format_NV21: |
| case Format_YV12: |
| case Format_I420: |
| case Format_IYUV: |
| case Format_YUY2: |
| case Format_YUYV: |
| case Format_YVYU: |
| case Format_UYVY: |
| case Format_VYUY: |
| case Format_P208: |
| case Format_422H: |
| case Format_422V: |
| case Format_R5G6B5: |
| case Format_R8G8B8: |
| case Format_A8R8G8B8: |
| case Format_X8R8G8B8: |
| case Format_A8B8G8R8: |
| case Format_X8B8G8R8: |
| case Format_444P: |
| case Format_AYUV: |
| case Format_AUYV: |
| case Format_RGBP: |
| case Format_BGRP: |
| uBitDepth = 8; |
| break; |
| |
| case Format_P010: |
| case Format_R10G10B10A2: |
| case Format_B10G10R10A2: |
| case Format_Y210: |
| case Format_Y410: |
| case Format_P210: |
| uBitDepth = 10; |
| break; |
| |
| case Format_A16B16G16R16: |
| case Format_A16R16G16B16: |
| case Format_A16B16G16R16F: |
| case Format_A16R16G16B16F: |
| case Format_P016: |
| case Format_Y416: |
| case Format_Y216: |
| case Format_P216: |
| uBitDepth = 16; |
| break; |
| |
| default: |
| VPHAL_PUBLIC_ASSERTMESSAGE("Input format color pack unknown."); |
| uBitDepth = 0; |
| break; |
| } |
| |
| return uBitDepth; |
| } |
| |
| //! |
| //! \brief Get the scale ratio |
| //! \details Get the scale ratio from input surface to output surface |
| //! \param [in] pSource |
| //! Pointer to input Surface |
| //! \param [in] pTarget |
| //! Pointer to output Surface |
| //! \param [out] pfScaleX |
| //! Pointer to scaling ratio x |
| //! \param [out] pfScaleY |
| //! Pointer to scaling ratio y |
| //! \return void |
| //! |
| void VpHal_GetScalingRatio( |
| PVPHAL_SURFACE pSource, |
| PVPHAL_SURFACE pTarget, |
| float* pfScaleX, |
| float* pfScaleY) |
| { |
| MOS_UNUSED(pTarget); |
| |
| VPHAL_PUBLIC_ASSERT(pSource); |
| VPHAL_PUBLIC_ASSERT(pTarget); |
| VPHAL_PUBLIC_ASSERT(pfScaleX); |
| VPHAL_PUBLIC_ASSERT(pfScaleY); |
| |
| float fScaleX = 0.0; |
| float fScaleY = 0.0; |
| |
| // Source rectangle is pre-rotated, destination rectangle is post-rotated. |
| if (pSource->Rotation == VPHAL_ROTATION_IDENTITY || |
| pSource->Rotation == VPHAL_ROTATION_180 || |
| pSource->Rotation == VPHAL_MIRROR_HORIZONTAL || |
| pSource->Rotation == VPHAL_MIRROR_VERTICAL) |
| { |
| fScaleX = (float)(pSource->rcDst.right - pSource->rcDst.left) / |
| (float)(pSource->rcSrc.right - pSource->rcSrc.left); |
| fScaleY = (float)(pSource->rcDst.bottom - pSource->rcDst.top) / |
| (float)(pSource->rcSrc.bottom - pSource->rcSrc.top); |
| } |
| else |
| { |
| // VPHAL_ROTATION_90 || VPHAL_ROTATION_270 || |
| // VPHAL_ROTATE_90_MIRROR_HORIZONTAL || VPHAL_ROTATE_90_MIRROR_VERTICAL |
| fScaleX = (float)(pSource->rcDst.bottom - pSource->rcDst.top) / |
| (float)(pSource->rcSrc.right - pSource->rcSrc.left); |
| fScaleY = (float)(pSource->rcDst.right - pSource->rcDst.left) / |
| (float)(pSource->rcSrc.bottom - pSource->rcSrc.top); |
| } |
| |
| *pfScaleX = fScaleX; |
| *pfScaleY = fScaleY; |
| } |
| |
| //! \brief Transfer float type to half precision float type |
| //! \details Transfer float type to half precision float (16bit) type |
| //! \param [in] fInput |
| //! input FP32 number |
| //! \return uint16_t |
| //! half precision float value in bit |
| //! |
| uint16_t VpHal_FloatToHalfFloat( |
| float fInput) |
| { |
| bool Sign; |
| int32_t Exp; |
| bool ExpSign; |
| uint32_t Mantissa; |
| uint32_t dwInput; |
| VPHAL_HALF_PRECISION_FLOAT outFloat; |
| |
| dwInput = *((uint32_t *) (&fInput)); |
| Sign = (dwInput >> 31) & 0x01; |
| Exp = (dwInput >> 23) & 0x0FF; |
| Mantissa = dwInput & 0x07FFFFF; |
| |
| outFloat.Sign = Sign; |
| outFloat.Mantissa = (Mantissa >> 13) & 0x03ff; // truncate to zero |
| |
| if (Exp == 0) |
| { |
| outFloat.Exponent = 0; |
| } |
| else if (Exp == 0xff) |
| { |
| outFloat.Exponent = 31; |
| } |
| else |
| { |
| // Transfer 15-bit exponent to 4-bit exponent |
| Exp -= 0x7f; |
| Exp += 0xf; |
| |
| if (Exp < 1) |
| { |
| Exp = 1; |
| } |
| else if (Exp > 30) |
| { |
| Exp = 30; |
| } |
| |
| outFloat.Exponent = Exp; |
| } |
| |
| return outFloat.value; |
| } |
| |
| MOS_SURFACE VpHal_ConvertVphalSurfaceToMosSurface(PVPHAL_SURFACE pSurface) |
| { |
| VPHAL_PUBLIC_ASSERT(pSurface); |
| |
| MOS_SURFACE outSurface; |
| MOS_ZeroMemory(&outSurface, sizeof(MOS_SURFACE)); |
| outSurface.OsResource = pSurface->OsResource; |
| outSurface.Format = pSurface->Format; |
| outSurface.dwWidth = pSurface->dwWidth; |
| outSurface.dwHeight = pSurface->dwHeight; |
| outSurface.TileType = pSurface->TileType; |
| outSurface.TileModeGMM = pSurface->TileModeGMM; |
| outSurface.bGMMTileEnabled = pSurface->bGMMTileEnabled; |
| outSurface.dwDepth = pSurface->dwDepth; |
| outSurface.dwPitch = pSurface->dwPitch; |
| outSurface.dwSlicePitch = pSurface->dwSlicePitch; |
| outSurface.dwOffset = pSurface->dwOffset; |
| outSurface.bCompressible = pSurface->bCompressible; |
| outSurface.bIsCompressed = pSurface->bIsCompressed; |
| outSurface.CompressionMode = pSurface->CompressionMode; |
| outSurface.CompressionFormat = pSurface->CompressionFormat; |
| |
| return outSurface; |
| } |