blob: 0071d3fdc6a6056101770f27dd4e9f6d586e51ea [file] [log] [blame]
/*
* Copyright (c) 2019-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 vp_allocator.cpp
//! \brief Defines the interface for vp resouce allocate
//! \details vp allocator will allocate and destory buffers, the caller
//! can use directly
//!
#include "vp_allocator.h"
#include "vp_utils.h"
using namespace vp;
VpAllocator::VpAllocator(PMOS_INTERFACE osInterface, VPMediaMemComp *mmc) :
m_osInterface(osInterface),
m_mmc(mmc)
{
m_allocator = MOS_New(Allocator, m_osInterface);
VP_PUBLIC_CHK_NULL_NO_STATUS_RETURN(m_allocator);
}
VpAllocator::~VpAllocator()
{
if (m_allocator)
{
m_allocator->DestroyAllResources();
MOS_Delete(m_allocator);
}
}
//Paried with DestroyResource or DestroyAllResources
MOS_RESOURCE* VpAllocator::AllocateResource(MOS_ALLOC_GFXRES_PARAMS &param, bool zeroOnAllocate)
{
if (!m_allocator)
return nullptr;
return m_allocator->AllocateResource(param, zeroOnAllocate, COMPONENT_VPCommon);
}
MOS_STATUS VpAllocator::DestroyResource(MOS_RESOURCE *resource)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return m_allocator->DestroyResource(resource);
}
MOS_STATUS VpAllocator::DestroyAllResources()
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return m_allocator->DestroyAllResources();
}
//Paried with FreeResource
MOS_STATUS VpAllocator::AllocateResource(MOS_RESOURCE *res, MOS_ALLOC_GFXRES_PARAMS &param)
{
if (!m_allocator)
return MOS_STATUS_NULL_POINTER;
return m_allocator->AllocateResource(res, param);
}
MOS_STATUS VpAllocator::FreeResource(MOS_RESOURCE *resource)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return m_allocator->FreeResource(resource);
}
void VpAllocator::UpdateSurfacePlaneOffset(MOS_SURFACE &surf)
{
// dwOffset/YPlaneOffset/UPlaneOffset/VPlaneOffset will not be initialized during GetSurfaceInfo.
// Initialize them with RenderOffset when needed.
if (IS_RGB32_FORMAT(surf.Format) ||
IS_RGB16_FORMAT(surf.Format) ||
IS_RGB64_FORMAT(surf.Format) ||
surf.Format == Format_RGB ||
surf.Format == Format_Y410)
{
surf.dwOffset = surf.RenderOffset.RGB.BaseOffset;
surf.YPlaneOffset.iSurfaceOffset = surf.RenderOffset.RGB.BaseOffset;
surf.YPlaneOffset.iXOffset = surf.RenderOffset.RGB.XOffset;
surf.YPlaneOffset.iYOffset = surf.RenderOffset.RGB.YOffset;
}
else // YUV or PL3_RGB
{
// Get Y plane information (plane offset, X/Y offset)
surf.dwOffset = surf.RenderOffset.YUV.Y.BaseOffset;
surf.YPlaneOffset.iSurfaceOffset = surf.RenderOffset.YUV.Y.BaseOffset;
surf.YPlaneOffset.iXOffset = surf.RenderOffset.YUV.Y.XOffset;
surf.YPlaneOffset.iYOffset = surf.RenderOffset.YUV.Y.YOffset;
surf.YPlaneOffset.iLockSurfaceOffset = surf.LockOffset.YUV.Y;
// Get U/UV plane information (plane offset, X/Y offset)
surf.UPlaneOffset.iSurfaceOffset = surf.RenderOffset.YUV.U.BaseOffset;
surf.UPlaneOffset.iXOffset = surf.RenderOffset.YUV.U.XOffset;
surf.UPlaneOffset.iYOffset = surf.RenderOffset.YUV.U.YOffset;
surf.UPlaneOffset.iLockSurfaceOffset = surf.LockOffset.YUV.U;
// Get V plane information (plane offset, X/Y offset)
surf.VPlaneOffset.iSurfaceOffset = surf.RenderOffset.YUV.V.BaseOffset;
surf.VPlaneOffset.iXOffset = surf.RenderOffset.YUV.V.XOffset;
surf.VPlaneOffset.iYOffset = surf.RenderOffset.YUV.V.YOffset;
surf.VPlaneOffset.iLockSurfaceOffset = surf.LockOffset.YUV.V;
}
}
//Paried with AllocateSurface
MOS_SURFACE* VpAllocator::AllocateSurface(MOS_ALLOC_GFXRES_PARAMS &param, bool zeroOnAllocate)
{
if (!m_allocator)
return nullptr;
MOS_SURFACE* surf = m_allocator->AllocateSurface(param, zeroOnAllocate, COMPONENT_VPCommon);
if (surf)
{
// Format is not initialized in Allocator::AllocateSurface. Remove it after
// it being fixed in Allocator::AllocateSurface.
surf->Format = param.Format;
if (MOS_FAILED(SetMmcFlags(*surf)))
{
VP_PUBLIC_ASSERTMESSAGE("Set mmc flags failed during AllocateSurface!");
m_allocator->DestroySurface(surf);
return nullptr;
}
UpdateSurfacePlaneOffset(*surf);
}
return surf;
}
MOS_STATUS VpAllocator::DestroySurface(MOS_SURFACE *surface, MOS_GFXRES_FREE_FLAGS flags)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return m_allocator->DestroySurface(surface, flags);
}
VP_SURFACE* VpAllocator::AllocateVpSurface(MOS_ALLOC_GFXRES_PARAMS &param, bool zeroOnAllocate, VPHAL_CSPACE ColorSpace, uint32_t ChromaSiting)
{
VP_SURFACE *surface = MOS_New(VP_SURFACE);
if (nullptr == surface)
{
return nullptr;
}
MOS_ZeroMemory(surface, sizeof(VP_SURFACE));
// Only used for Buffer surface
uint32_t bufferWidth = 0;
uint32_t bufferHeight = 0;
if (param.Format == Format_Buffer)
{
bufferWidth = param.dwWidth;
bufferHeight = param.dwHeight;
param.dwWidth = param.dwWidth * param.dwHeight;
param.dwHeight = 1;
}
surface->osSurface = AllocateSurface(param, zeroOnAllocate);
if (nullptr == surface->osSurface)
{
MOS_Delete(surface);
return nullptr;
}
surface->isResourceOwner = true;
surface->ColorSpace = ColorSpace;
surface->ChromaSiting = ChromaSiting;
surface->SampleType = SAMPLE_PROGRESSIVE; // Hardcode to SAMPLE_PROGRESSIVE for intermedia surface. Set to correct value for DI later.
surface->rcSrc.left = surface->rcSrc.top = 0;
surface->rcSrc.right = surface->osSurface->dwWidth;
surface->rcSrc.bottom = surface->osSurface->dwHeight;
surface->rcDst = surface->rcSrc;
surface->rcMaxSrc = surface->rcSrc;
if (param.Format == Format_Buffer)
{
surface->bufferWidth = bufferWidth;
surface->bufferHeight = bufferHeight;
}
return surface;
}
// Allocate vp surface from vphalSurf. Reuse the resource in vphalSurf.
VP_SURFACE *VpAllocator::AllocateVpSurface(VPHAL_SURFACE &vphalSurf)
{
if (Mos_ResourceIsNull(&vphalSurf.OsResource))
{
return nullptr;
}
VP_SURFACE *surf = MOS_New(VP_SURFACE);
if (nullptr == surf)
{
return nullptr;
}
surf->osSurface = MOS_New(MOS_SURFACE);
if (nullptr == surf->osSurface)
{
MOS_Delete(surf);
return nullptr;
}
surf->isResourceOwner = false;
surf->Clean();
// Initialize the mos surface in vp surface structure.
MOS_SURFACE &osSurface = *surf->osSurface;
MOS_ZeroMemory(&osSurface, sizeof(MOS_SURFACE));
// Set input parameters dwArraySlice, dwMipSlice and S3dChannel if needed later.
osSurface.Format = vphalSurf.Format;
osSurface.OsResource = vphalSurf.OsResource;
if (MOS_FAILED(m_allocator->GetSurfaceInfo(&osSurface.OsResource, &osSurface)))
{
MOS_Delete(surf->osSurface);
MOS_Delete(surf);
return nullptr;
}
// Align the format with vphal surface. Some format need be remapped in vphal surface.
// For example, format_420O is mapped to Format_NV12 in VpHal.
// But it is mapped to several different Formats in CodecHal under different conditions.
osSurface.Format = vphalSurf.Format;
// dwOffset/YPlaneOffset/UPlaneOffset/VPlaneOffset will not be initialized during GetSurfaceInfo
// Just align them with vphal surface.
// Align Y plane information (plane offset, X/Y offset)
osSurface.dwOffset = vphalSurf.dwOffset;
osSurface.YPlaneOffset.iLockSurfaceOffset = vphalSurf.YPlaneOffset.iLockSurfaceOffset;
osSurface.YPlaneOffset.iSurfaceOffset = vphalSurf.YPlaneOffset.iSurfaceOffset;
osSurface.YPlaneOffset.iXOffset = vphalSurf.YPlaneOffset.iXOffset;
osSurface.YPlaneOffset.iYOffset = vphalSurf.YPlaneOffset.iYOffset;
// Align U/UV plane information (plane offset, X/Y offset)
osSurface.UPlaneOffset.iLockSurfaceOffset = vphalSurf.UPlaneOffset.iLockSurfaceOffset;
osSurface.UPlaneOffset.iSurfaceOffset = vphalSurf.UPlaneOffset.iSurfaceOffset;
osSurface.UPlaneOffset.iXOffset = vphalSurf.UPlaneOffset.iXOffset;
osSurface.UPlaneOffset.iYOffset = vphalSurf.UPlaneOffset.iYOffset;
// Align V plane information (plane offset, X/Y offset)
osSurface.VPlaneOffset.iLockSurfaceOffset = vphalSurf.VPlaneOffset.iLockSurfaceOffset;
osSurface.VPlaneOffset.iSurfaceOffset = vphalSurf.VPlaneOffset.iSurfaceOffset;
osSurface.VPlaneOffset.iXOffset = vphalSurf.VPlaneOffset.iXOffset;
osSurface.VPlaneOffset.iYOffset = vphalSurf.VPlaneOffset.iYOffset;
// Initialize other parameters in vp surface according to vphal surface.
surf->ColorSpace = vphalSurf.ColorSpace;
surf->ExtendedGamut = vphalSurf.ExtendedGamut;
surf->Palette = vphalSurf.Palette;
surf->bQueryVariance = vphalSurf.bQueryVariance;
surf->FrameID = vphalSurf.FrameID;
surf->uFwdRefCount = vphalSurf.uFwdRefCount;
surf->uBwdRefCount = vphalSurf.uBwdRefCount;
surf->pFwdRef = vphalSurf.pFwdRef;
surf->pBwdRef = vphalSurf.pBwdRef;
surf->SurfType = vphalSurf.SurfType;
surf->SampleType = vphalSurf.SampleType;
surf->ChromaSiting = vphalSurf.ChromaSiting;
surf->rcSrc = vphalSurf.rcSrc;
surf->rcDst = vphalSurf.rcDst;
surf->rcMaxSrc = vphalSurf.rcMaxSrc;
if (MOS_FAILED(SetMmcFlags(osSurface)))
{
VP_PUBLIC_ASSERTMESSAGE("Set mmc flags failed during AllocateVpSurface!");
DestroyVpSurface(surf);
return nullptr;
}
return surf;
}
// Allocate vp surface from vpSurfSrc. Reuse the resource in vpSurfSrc.
VP_SURFACE *VpAllocator::AllocateVpSurface(VP_SURFACE &vpSurfSrc)
{
if (nullptr == vpSurfSrc.osSurface || Mos_ResourceIsNull(&vpSurfSrc.osSurface->OsResource))
{
return nullptr;
}
VP_SURFACE *surf = MOS_New(VP_SURFACE);
if (nullptr == surf)
{
return nullptr;
}
MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
if (nullptr == osSurface)
{
MOS_Delete(surf);
return nullptr;
}
*osSurface = *vpSurfSrc.osSurface;
*surf = vpSurfSrc;
surf->osSurface = osSurface;
surf->isResourceOwner = false;
return surf;
}
// Allocate vp surface from osSurf. Reuse the resource in osSurf.
VP_SURFACE *VpAllocator::AllocateVpSurface(MOS_SURFACE &osSurf,
VPHAL_CSPACE colorSpace, uint32_t chromaSiting, RECT rcSrc, RECT rcDst, VPHAL_SURFACE_TYPE SurfType, bool updatePlaneOffset)
{
if (Mos_ResourceIsNull(&osSurf.OsResource))
{
return nullptr;
}
VP_SURFACE *surf = MOS_New(VP_SURFACE);
if (nullptr == surf)
{
return nullptr;
}
MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
if (nullptr == osSurface)
{
MOS_Delete(surf);
return nullptr;
}
*osSurface = osSurf;
if (updatePlaneOffset)
{
UpdateSurfacePlaneOffset(*osSurface);
}
MOS_ZeroMemory(surf, sizeof(VP_SURFACE));
surf->osSurface = osSurface;
surf->isResourceOwner = false;
surf->ColorSpace = colorSpace; //!< Color Space
surf->ChromaSiting = chromaSiting; //!< ChromaSiting
surf->rcSrc = rcSrc; //!< Source rectangle
surf->rcDst = rcDst; //!< Destination rectangle
surf->rcMaxSrc = rcSrc; //!< Max source rectangle
surf->SurfType = SurfType; //!< Surface type (context). Not in use for internal surface
surf->SampleType = SAMPLE_PROGRESSIVE; //!< Interlaced/Progressive sample type.
return surf;
}
// Allocate empty vp surface.
VP_SURFACE *VpAllocator::AllocateVpSurface()
{
// Allocate VpSurface without resource.
VP_SURFACE *surf = MOS_New(VP_SURFACE);
if (nullptr == surf)
{
return nullptr;
}
MOS_SURFACE *osSurface = MOS_New(MOS_SURFACE);
if (nullptr == osSurface)
{
MOS_Delete(surf);
return nullptr;
}
surf->osSurface = osSurface;
surf->isResourceOwner = false;
surf->Clean();
return surf;
}
// Copy surface info from src to dst. dst shares the resource of src.
MOS_STATUS VpAllocator::CopyVpSurface(VP_SURFACE &dst, VP_SURFACE &src)
{
if (nullptr == dst.osSurface || nullptr == src.osSurface || dst.isResourceOwner)
{
return MOS_STATUS_INVALID_PARAMETER;
}
MOS_SURFACE &osSurface = *dst.osSurface;
osSurface = *src.osSurface;
dst = src;
dst.osSurface = &osSurface;
dst.isResourceOwner = false;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::DestroyVpSurface(VP_SURFACE* &surface, MOS_GFXRES_FREE_FLAGS flags)
{
MOS_STATUS status = MOS_STATUS_SUCCESS;
if (nullptr == surface)
{
return status;
}
if (surface && nullptr == surface->osSurface)
{
// VP_SURFACE should always be allocated by interface in VpAllocator,
// which will ensure nullptr != surface->osSurface.
VP_PUBLIC_NORMALMESSAGE("Surfaces already been deleted, return status!");
return status;
}
if (surface->isResourceOwner)
{
status = DestroySurface(surface->osSurface, flags);
}
else
{
MOS_Delete(surface->osSurface);
}
MOS_Delete(surface);
return status;
}
void* VpAllocator::Lock(MOS_RESOURCE* resource, MOS_LOCK_PARAMS *lockFlag)
{
if (!m_allocator)
return nullptr;
return m_allocator->Lock(resource, lockFlag);
}
void* VpAllocator::LockResouceForWrite(MOS_RESOURCE *resource)
{
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;
if (!m_allocator)
return nullptr;
return m_allocator->Lock(resource, &lockFlags);
}
void* VpAllocator::LockResouceWithNoOverwrite(MOS_RESOURCE *resource)
{
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.WriteOnly = 1;
lockFlags.NoOverWrite = 1;
if (!m_allocator)
return nullptr;
return m_allocator->Lock(resource, &lockFlags);
}
void* VpAllocator::LockResouceForRead(MOS_RESOURCE *resource)
{
MOS_LOCK_PARAMS lockFlags;
MOS_ZeroMemory(&lockFlags, sizeof(MOS_LOCK_PARAMS));
lockFlags.ReadOnly = 1;
if (!m_allocator)
return nullptr;
return m_allocator->Lock(resource, &lockFlags);
}
MOS_STATUS VpAllocator::UnLock(MOS_RESOURCE *resource)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return m_allocator->UnLock(resource);
}
MOS_STATUS VpAllocator::SkipResourceSync(MOS_RESOURCE *resource)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return m_allocator->SkipResourceSync(resource);
}
MOS_STATUS VpAllocator::GetSurfaceInfo(VPHAL_SURFACE *surface, VPHAL_GET_SURFACE_INFO &info)
{
MOS_MEMCOMP_STATE mmcMode = MOS_MEMCOMP_DISABLED;
MOS_SURFACE resDetails;
VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
VP_PUBLIC_CHK_NULL_RETURN(surface);
VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
MOS_ZeroMemory(&resDetails, sizeof(MOS_SURFACE));
resDetails.dwArraySlice = info.ArraySlice;
resDetails.dwMipSlice = info.MipSlice;
resDetails.S3dChannel = info.S3dChannel;
resDetails.Format = surface->Format;
VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->GetSurfaceInfo(&surface->OsResource, &resDetails));
// Format_420O is mapped to Format_NV12 in VpHal here.
// But it is mapped to several different Formats in CodecHal under different conditions.
if (resDetails.Format == Format_420O)
{
resDetails.Format = Format_NV12;
}
// Get resource information
surface->dwWidth = resDetails.dwWidth;
surface->dwHeight = resDetails.dwHeight;
surface->dwPitch = resDetails.dwPitch;
surface->dwSlicePitch = resDetails.dwSlicePitch;
surface->dwDepth = resDetails.dwDepth;
surface->TileType = resDetails.TileType;
surface->TileModeGMM = resDetails.TileModeGMM;
surface->bGMMTileEnabled = resDetails.bGMMTileEnabled;
surface->bOverlay = resDetails.bOverlay ? true : false;
surface->bFlipChain = resDetails.bFlipChain ? true : false;
surface->Format = resDetails.Format;
surface->bCompressible = resDetails.bCompressible ? true : false;
surface->bIsCompressed = resDetails.bIsCompressed ? true : false;
if (IS_RGB32_FORMAT(surface->Format) ||
IS_RGB16_FORMAT(surface->Format) ||
IS_RGB64_FORMAT(surface->Format) ||
surface->Format == Format_RGB ||
surface->Format == Format_Y410)
{
surface->dwOffset = resDetails.RenderOffset.RGB.BaseOffset;
surface->YPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.RGB.BaseOffset;
surface->YPlaneOffset.iXOffset = resDetails.RenderOffset.RGB.XOffset;
surface->YPlaneOffset.iYOffset = resDetails.RenderOffset.RGB.YOffset;
}
else // YUV or PL3_RGB
{
// Get Y plane information (plane offset, X/Y offset)
surface->dwOffset = resDetails.RenderOffset.YUV.Y.BaseOffset;
surface->YPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.Y.BaseOffset;
surface->YPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.Y.XOffset;
surface->YPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.Y.YOffset;
surface->YPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.Y;
// Get U/UV plane information (plane offset, X/Y offset)
surface->UPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.U.BaseOffset;
surface->UPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.U.XOffset;
surface->UPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.U.YOffset;
surface->UPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.U;
// Get V plane information (plane offset, X/Y offset)
surface->VPlaneOffset.iSurfaceOffset = resDetails.RenderOffset.YUV.V.BaseOffset;
surface->VPlaneOffset.iXOffset = resDetails.RenderOffset.YUV.V.XOffset;
surface->VPlaneOffset.iYOffset = resDetails.RenderOffset.YUV.V.YOffset;
surface->VPlaneOffset.iLockSurfaceOffset = resDetails.LockOffset.YUV.V;
}
VP_PUBLIC_CHK_STATUS_RETURN(m_mmc->GetResourceMmcState(&surface->OsResource, mmcMode));
if (mmcMode &&
(surface->TileType == MOS_TILE_Y ||
surface->TileType == MOS_TILE_YS))
{
surface->bCompressible = true;
surface->CompressionMode = (MOS_RESOURCE_MMC_MODE)mmcMode;
}
else
{
surface->CompressionMode = MOS_MMC_DISABLED;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::AllocParamsInitType(
MOS_ALLOC_GFXRES_PARAMS &allocParams,
PVPHAL_SURFACE surface,
MOS_GFXRES_TYPE defaultResType,
MOS_TILE_TYPE defaultTileType)
{
VP_PUBLIC_CHK_NULL_RETURN(surface);
#if !EMUL && !LINUX
// Need to reallocate surface according to expected tiletype instead of tiletype of the surface what we have
if ( surface != nullptr &&
surface->OsResource.pGmmResInfo != nullptr &&
surface->TileType == defaultTileType)
{
// Reallocate but use same tile type and resource type as current
allocParams.TileType = surface->OsResource.TileType;
allocParams.Type = surface->OsResource.ResType;
}
else
#endif
{
// First time allocation. Caller must specify default params
allocParams.Type = defaultResType;
allocParams.TileType = defaultTileType;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::AllocParamsInitType(
MOS_ALLOC_GFXRES_PARAMS &allocParams,
VP_SURFACE *surface,
MOS_GFXRES_TYPE defaultResType,
MOS_TILE_TYPE defaultTileType)
{
// Need to reallocate surface according to expected tiletype instead of tiletype of the surface what we have
if (surface != nullptr &&
surface->osSurface != nullptr &&
surface->osSurface->OsResource.pGmmResInfo != nullptr &&
surface->osSurface->TileType == defaultTileType)
{
// Reallocate but use same tile type and resource type as current
allocParams.TileType = surface->osSurface->TileType;
allocParams.Type = surface->osSurface->Type;
}
else
{
// First time allocation. Caller must specify default params
allocParams.Type = defaultResType;
allocParams.TileType = defaultTileType;
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::ReAllocateSurface(
VP_SURFACE *&surface,
PCCHAR surfaceName,
MOS_FORMAT format,
MOS_GFXRES_TYPE defaultResType,
MOS_TILE_TYPE defaultTileType,
uint32_t width,
uint32_t height,
bool compressible,
MOS_RESOURCE_MMC_MODE compressionMode,
bool &allocated,
bool zeroOnAllocate,
MOS_HW_RESOURCE_DEF resUsageType,
MOS_TILE_MODE_GMM tileModeByForce)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MOS_ALLOC_GFXRES_PARAMS allocParams = {};
MOS_GFXRES_FREE_FLAGS resFreeFlags = {0};
allocated = false;
//---------------------------------
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
//---------------------------------
// compressible 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 (surface &&
surface->osSurface &&
!Mos_ResourceIsNull(&surface->osSurface->OsResource) &&
(surface->osSurface->Format == format) &&
((surface->osSurface->bCompressible != 0) == compressible) &&
(surface->osSurface->CompressionMode == compressionMode) &&
(surface->osSurface->TileType == defaultTileType) &&
((Format_Buffer == format &&
surface->bufferWidth == width &&
surface->bufferHeight == height) ||
(Format_Buffer != format &&
surface->osSurface->dwWidth == width &&
surface->osSurface->dwHeight == height)) )
{
return eStatus;
}
if (surface && nullptr == surface->osSurface)
{
// VP_SURFACE should always be allocated by interface in VpAllocator,
// which will ensure nullptr != surface->osSurface.
VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
}
//if free the compressed surface, need set the sync dealloc flag as 1 for sync dealloc for aux table update
if (surface && isSyncFreeNeededForMMCSurface(surface->osSurface))
{
resFreeFlags.SynchronousDestroy = 1;
VP_PUBLIC_NORMALMESSAGE("Set SynchronousDestroy flag for compressed resource %s", surfaceName);
}
VP_PUBLIC_CHK_STATUS_RETURN(DestroyVpSurface(surface, resFreeFlags));
AllocParamsInitType(allocParams, surface, defaultResType, defaultTileType);
allocParams.dwWidth = width;
allocParams.dwHeight = height;
allocParams.Format = format;
allocParams.bIsCompressible = compressible;
allocParams.CompressionMode = compressionMode;
allocParams.pBufName = surfaceName;
allocParams.dwArraySize = 1;
allocParams.ResUsageType = resUsageType;
allocParams.m_tileModeByForce = tileModeByForce;
surface = AllocateVpSurface(allocParams, zeroOnAllocate);
VP_PUBLIC_CHK_NULL_RETURN(surface);
allocated = true;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::OsFillResource(
PMOS_RESOURCE osResource,
uint32_t size,
uint8_t value)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return m_allocator->OsFillResource(osResource, size, value);
}
MOS_STATUS VpAllocator::ReadSurface (
PVPHAL_SURFACE surface,
uint32_t bpp,
uint8_t *dst)
{
uint8_t *src = nullptr;
uint8_t *tempSrc = nullptr;
uint8_t *tempDst = nullptr;
uint32_t size = 0;
uint32_t widthInBytes = 0;
uint32_t y = 0;
uint32_t z = 0;
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
//----------------------------------------------
VP_PUBLIC_ASSERT(surface);
VP_PUBLIC_ASSERT(surface->dwWidth > 0);
VP_PUBLIC_ASSERT(surface->dwHeight > 0);
VP_PUBLIC_ASSERT(surface->dwDepth > 0);
VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
VP_PUBLIC_ASSERT(bpp > 0);
VP_PUBLIC_ASSERT(dst);
VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
//----------------------------------------------
src = (uint8_t*)LockResouceForRead(&surface->OsResource);
VP_PUBLIC_CHK_NULL_RETURN(src);
// Calculate Size in Bytes
size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp/8;
widthInBytes = surface->dwWidth * bpp / 8;
if (surface->dwPitch == widthInBytes)
{
MOS_SecureMemcpy(dst, size, src, size);
}
else
{
tempSrc = src;
tempDst = dst;
for (z = 0; z < surface->dwDepth; z++)
{
for (y = 0; y < surface->dwHeight; y++)
{
MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
tempSrc += surface->dwPitch;
tempDst += widthInBytes;
}
}
}
VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::WriteSurface (
PVPHAL_SURFACE surface,
uint32_t bpp,
const uint8_t *src)
{
uint8_t *dst = nullptr;
uint8_t *tempSrc = nullptr;
uint8_t *tempDst = nullptr;
uint32_t widthInBytes = 0;
uint32_t size = 0;
uint32_t y = 0;
uint32_t z = 0;
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
//----------------------------------------------
VP_PUBLIC_ASSERT(surface);
VP_PUBLIC_ASSERT(surface->dwWidth > 0);
VP_PUBLIC_ASSERT(surface->dwHeight > 0);
VP_PUBLIC_ASSERT(surface->dwDepth > 0);
VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
VP_PUBLIC_ASSERT(bpp > 0);
VP_PUBLIC_ASSERT(src);
VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
//----------------------------------------------
dst = (uint8_t*)LockResouceForWrite(&surface->OsResource);
VP_PUBLIC_CHK_NULL_RETURN(dst);
// Calculate Size in Bytes
size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp/8;
widthInBytes = surface->dwWidth * bpp/8;
if (surface->dwPitch == widthInBytes)
{
MOS_SecureMemcpy(dst, size, src, size);
}
else
{
tempSrc = (uint8_t*)src;
tempDst = dst;
for (z = 0; z < surface->dwDepth; z++)
{
for (y = 0; y < surface->dwHeight; y++)
{
MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
tempSrc += widthInBytes;
tempDst += surface->dwPitch;
}
}
}
VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::WriteSurface(VP_SURFACE* vpsurface, uint32_t bpp, const uint8_t* src)
{
uint8_t* dst = nullptr;
uint8_t* tempSrc = nullptr;
uint8_t* tempDst = nullptr;
uint32_t widthInBytes = 0;
uint32_t size = 0;
uint32_t y = 0;
uint32_t z = 0;
MOS_SURFACE* surface;
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
//----------------------------------------------
VP_PUBLIC_ASSERT(vpsurface);
surface = vpsurface->osSurface;
VP_PUBLIC_ASSERT(surface);
VP_PUBLIC_ASSERT(surface->dwWidth > 0);
VP_PUBLIC_ASSERT(surface->dwHeight > 0);
VP_PUBLIC_ASSERT(surface->dwDepth > 0);
VP_PUBLIC_ASSERT(surface->dwPitch >= surface->dwWidth);
VP_PUBLIC_ASSERT(bpp > 0);
VP_PUBLIC_ASSERT(src);
VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&surface->OsResource));
//----------------------------------------------
dst = (uint8_t*)LockResouceForWrite(&surface->OsResource);
VP_PUBLIC_CHK_NULL_RETURN(dst);
// Calculate Size in Bytes
size = surface->dwWidth * surface->dwHeight * surface->dwDepth * bpp / 8;
widthInBytes = surface->dwWidth * bpp / 8;
if (surface->dwPitch == widthInBytes)
{
MOS_SecureMemcpy(dst, size, src, size);
}
else
{
tempSrc = (uint8_t*)src;
tempDst = dst;
for (z = 0; z < surface->dwDepth; z++)
{
for (y = 0; y < surface->dwHeight; y++)
{
MOS_SecureMemcpy(tempDst, widthInBytes, tempSrc, widthInBytes);
tempSrc += widthInBytes;
tempDst += surface->dwPitch;
}
}
}
VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::Write1DSurface(VP_SURFACE* vpsurface, const uint8_t* src, uint32_t srcSize)
{
VP_PUBLIC_CHK_NULL_RETURN(vpsurface);
VP_PUBLIC_CHK_NULL_RETURN(vpsurface->osSurface);
VP_PUBLIC_CHK_NULL_RETURN(src);
VP_PUBLIC_CHK_VALUE_RETURN(srcSize > 0, true);
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
VP_PUBLIC_CHK_VALUE_RETURN(vpsurface->osSurface->dwSize > 0, true);
#if MOS_MEDIASOLO_SUPPORTED
if (!m_osInterface->bSoloInUse)
#endif
{
VP_PUBLIC_CHK_VALUE_RETURN(vpsurface->osSurface->Type, MOS_GFXRES_BUFFER);
}
VP_PUBLIC_ASSERT(!Mos_ResourceIsNull(&vpsurface->osSurface->OsResource));
MOS_SURFACE* surface = vpsurface->osSurface;
uint8_t* dst = (uint8_t*)LockResouceForWrite(&surface->OsResource);
VP_PUBLIC_CHK_NULL_RETURN(dst);
MOS_STATUS status = MOS_SecureMemcpy(dst, surface->dwSize, src, srcSize);
VP_PUBLIC_CHK_STATUS_RETURN(m_allocator->UnLock(&surface->OsResource));
return status;
}
MOS_STATUS VpAllocator::SyncOnResource(
PMOS_RESOURCE osResource,
bool bWriteOperation)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return (m_allocator->SyncOnResource(osResource, bWriteOperation));
}
MOS_STATUS VpAllocator::UpdateResourceUsageType(
PMOS_RESOURCE osResource,
MOS_HW_RESOURCE_DEF resUsageType)
{
VP_PUBLIC_CHK_NULL_RETURN(m_allocator);
return (m_allocator->UpdateResourceUsageType(osResource, resUsageType));
}
bool VpAllocator::isSyncFreeNeededForMMCSurface(PMOS_SURFACE pOsSurface)
{
if (nullptr == pOsSurface)
{
return false;
}
return (m_allocator->isSyncFreeNeededForMMCSurface(pOsSurface));
}
bool VP_SURFACE::IsEmpty()
{
return nullptr == osSurface || Mos_ResourceIsNull(&osSurface->OsResource);
}
MOS_STATUS VP_SURFACE::Clean()
{
// The vp surface, which owns the resource, cannot be cleaned.
if (isResourceOwner)
{
VP_PUBLIC_CHK_STATUS_RETURN(MOS_STATUS_INVALID_PARAMETER);
}
if (osSurface)
{
MOS_ZeroMemory(osSurface, sizeof(MOS_SURFACE));
}
isResourceOwner = false;
ColorSpace = CSpace_Any;
ChromaSiting = 0;
bQueryVariance = 0;
FrameID = 0;
ExtendedGamut = false;
SurfType = SURF_NONE;
uFwdRefCount = 0;
uBwdRefCount = 0;
pFwdRef = nullptr;
pBwdRef = nullptr;
SampleType = SAMPLE_PROGRESSIVE;
MOS_ZeroMemory(&Palette, sizeof(Palette));
MOS_ZeroMemory(&rcSrc, sizeof(rcSrc));
MOS_ZeroMemory(&rcDst, sizeof(rcDst));
MOS_ZeroMemory(&rcMaxSrc, sizeof(rcMaxSrc));
bVEBOXCroppingUsed = false;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS VpAllocator::SetMmcFlags(MOS_SURFACE &osSurface)
{
VP_PUBLIC_CHK_NULL_RETURN(m_mmc);
// Init MMC related flags.
m_mmc->SetSurfaceMmcMode(&osSurface);
if (osSurface.CompressionMode &&
(osSurface.TileType == MOS_TILE_Y ||
osSurface.TileType == MOS_TILE_YS))
{
uint32_t mmcFormat = 0;
osSurface.bCompressible = true;
osSurface.bIsCompressed = true;
m_mmc->GetSurfaceMmcFormat(&osSurface, &mmcFormat);
osSurface.CompressionFormat = mmcFormat;
}
else
{
// Do not modify the bCompressible flag even MmcMode is disable, since the surface size/pitch may be different
// between Compressible and Uncompressible, which will affect the DN surface allocation.
osSurface.bIsCompressed = false;
osSurface.CompressionMode = MOS_MMC_DISABLED;
osSurface.CompressionFormat = 0;
}
return MOS_STATUS_SUCCESS;
}