/*
* 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     mos_graphicsresource_specific_next.cpp
//! \brief   Container class for the linux/Android specfic graphic resource
//!

#include "mos_defs.h"
#include "mos_util_debug_next.h"

#include "mos_graphicsresource_specific_next.h"
#include "mos_context_specific_next.h"
#include "mos_os_specific_next.h"
#include "memory_policy_manager.h"

GraphicsResourceSpecificNext::GraphicsResourceSpecificNext()
{
    MOS_OS_FUNCTION_ENTER;
}

GraphicsResourceSpecificNext::~GraphicsResourceSpecificNext()
{
    MOS_OS_FUNCTION_ENTER;
}

bool GraphicsResourceSpecificNext::ResourceIsNull()
{
    return ((m_bo == nullptr)
#if (_DEBUG || _RELEASE_INTERNAL)
         && ((m_pData == nullptr) )
#endif // (_DEBUG || _RELEASE_INTERNAL)
    );

}

GMM_RESOURCE_FORMAT GraphicsResourceSpecificNext::ConvertMosFmtToGmmFmt(MOS_FORMAT format)
{
    switch (format)
    {
        case Format_Buffer      : return GMM_FORMAT_GENERIC_8BIT;
        case Format_Buffer_2D   : return GMM_FORMAT_GENERIC_8BIT;
        case Format_L8          : return GMM_FORMAT_GENERIC_8BIT;
        case Format_L16         : return GMM_FORMAT_L16_UNORM_TYPE;
        case Format_STMM        : return GMM_FORMAT_R8_UNORM_TYPE;
        case Format_AI44        : return GMM_FORMAT_GENERIC_8BIT;
        case Format_IA44        : return GMM_FORMAT_GENERIC_8BIT;
        case Format_R5G6B5      : return GMM_FORMAT_B5G6R5_UNORM_TYPE;
        case Format_X8R8G8B8    : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE;
        case Format_A8R8G8B8    : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE;
        case Format_X8B8G8R8    : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE;
        case Format_A8B8G8R8    : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE;
        case Format_R32F        : return GMM_FORMAT_R32_FLOAT_TYPE;
        case Format_V8U8        : return GMM_FORMAT_GENERIC_16BIT;              // matching size as format
        case Format_YUY2        : return GMM_FORMAT_YUY2;
        case Format_UYVY        : return GMM_FORMAT_UYVY;
        case Format_P8          : return GMM_FORMAT_RENDER_8BIT_TYPE;           // matching size as format
        case Format_A8          : return GMM_FORMAT_A8_UNORM_TYPE;
        case Format_AYUV        : return GMM_FORMAT_R8G8B8A8_UINT_TYPE;
        case Format_NV12        : return GMM_FORMAT_NV12_TYPE;
        case Format_NV21        : return GMM_FORMAT_NV21_TYPE;
        case Format_YV12        : return GMM_FORMAT_YV12_TYPE;
        case Format_R32U        : return GMM_FORMAT_R32_UINT_TYPE;
        case Format_R32S        : return GMM_FORMAT_R32_SINT_TYPE;
        case Format_RAW         : return GMM_FORMAT_GENERIC_8BIT;
        case Format_444P        : return GMM_FORMAT_MFX_JPEG_YUV444_TYPE;
        case Format_422H        : return GMM_FORMAT_MFX_JPEG_YUV422H_TYPE;
        case Format_422V        : return GMM_FORMAT_MFX_JPEG_YUV422V_TYPE;
        case Format_IMC3        : return GMM_FORMAT_IMC3_TYPE;
        case Format_411P        : return GMM_FORMAT_MFX_JPEG_YUV411_TYPE;
        case Format_411R        : return GMM_FORMAT_MFX_JPEG_YUV411R_TYPE;
        case Format_RGBP        : return GMM_FORMAT_RGBP_TYPE;
        case Format_BGRP        : return GMM_FORMAT_BGRP_TYPE;
        case Format_R8U         : return GMM_FORMAT_R8_UINT_TYPE;
        case Format_R8UN        : return GMM_FORMAT_R8_UNORM;
        case Format_R16U        : return GMM_FORMAT_R16_UINT_TYPE;
        case Format_R16F        : return GMM_FORMAT_R16_FLOAT_TYPE;
        case Format_P010        : return GMM_FORMAT_P010_TYPE;
        case Format_P016        : return GMM_FORMAT_P016_TYPE;
        case Format_Y216        : return GMM_FORMAT_Y216_TYPE;
        case Format_Y416        : return GMM_FORMAT_Y416_TYPE;
        case Format_P208        : return GMM_FORMAT_P208_TYPE;
        case Format_A16B16G16R16: return GMM_FORMAT_R16G16B16A16_UNORM_TYPE;
        case Format_Y210        : return GMM_FORMAT_Y210_TYPE;
        case Format_Y410        : return GMM_FORMAT_Y410_TYPE;
        case Format_R10G10B10A2 : return GMM_FORMAT_R10G10B10A2_UNORM_TYPE;
        case Format_A16B16G16R16F: return GMM_FORMAT_R16G16B16A16_FLOAT;
        case Format_R32G32B32A32F: return GMM_FORMAT_R32G32B32A32_FLOAT;
        default                 : return GMM_FORMAT_INVALID;
    }
}

MOS_STATUS GraphicsResourceSpecificNext::Allocate(OsContextNext* osContextPtr, CreateParams& params)
{
    MOS_OS_FUNCTION_ENTER;

    if (osContextPtr == nullptr)
    {
        MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
        return MOS_STATUS_INVALID_HANDLE;
    }

    if (osContextPtr->GetOsContextValid() == false)
    {
        MOS_OS_ASSERTMESSAGE("The OS context got is not valid.");
        return MOS_STATUS_INVALID_HANDLE;
    }

    OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);
    if (pOsContextSpecific == nullptr)
    {
        MOS_OS_ASSERTMESSAGE("Convert OsContextSpecific failed.");
        return MOS_STATUS_INVALID_HANDLE;
    }

    MOS_STATUS         status          = MOS_STATUS_SUCCESS;
    uint32_t           tileFormatLinux = I915_TILING_NONE;
    uint32_t           alignedHeight   = params.m_height;
    uint32_t           bufHeight       = params.m_height;
    GMM_RESOURCE_TYPE  resourceType    = RESOURCE_2D;
    int32_t            mem_type        = MOS_MEMPOOL_VIDEOMEMORY;

    GMM_RESCREATE_PARAMS    gmmParams;
    MosUtilities::MosZeroMemory(&gmmParams, sizeof(gmmParams));

    switch (params.m_type)
    {
        case MOS_GFXRES_BUFFER:
        case MOS_GFXRES_SCRATCH:
          gmmParams.Type = RESOURCE_BUFFER;
          gmmParams.Flags.Gpu.State = true;
          alignedHeight = 1;
          break;

        case MOS_GFXRES_2D:
            gmmParams.Type = RESOURCE_2D;
            gmmParams.Flags.Gpu.Video = true;
            break;

        case MOS_GFXRES_VOLUME:
            gmmParams.Type = RESOURCE_3D;
            gmmParams.Flags.Gpu.Video = true;
            gmmParams.Depth = params.m_depth;
            break;

        default:
            MOS_OS_ASSERTMESSAGE("Unknown surface type");
            return MOS_STATUS_UNKNOWN;
    }

    // Create GmmResourceInfo
    gmmParams.Format = ConvertMosFmtToGmmFmt(params.m_format);
    if (gmmParams.Format == GMM_FORMAT_INVALID)
    {
        MOS_OS_ASSERTMESSAGE("Unsupported format");
        return MOS_STATUS_UNIMPLEMENTED;
    }
    gmmParams.BaseWidth = params.m_width;
    gmmParams.BaseHeight = alignedHeight;
    gmmParams.ArraySize = 1;

    MOS_TILE_TYPE tileformat = params.m_tileType;
    switch (tileformat)
    {
        case MOS_TILE_Y:
            tileFormatLinux               = I915_TILING_Y;
            if (params.m_isCompressible && MEDIA_IS_SKU(pOsContextSpecific->GetSkuTable(), FtrE2ECompression))
            {
                gmmParams.Flags.Gpu.MMC  = 1;
                gmmParams.Flags.Info.MediaCompressed = 1;
                gmmParams.Flags.Gpu.CCS = 1;
                gmmParams.Flags.Gpu.UnifiedAuxSurface = 1;
                gmmParams.Flags.Gpu.RenderTarget = 1;

                if(MEDIA_IS_SKU(pOsContextSpecific->GetSkuTable(), FtrFlatPhysCCS))
                {
                    gmmParams.Flags.Gpu.UnifiedAuxSurface = 0;
                }
            }
            break;
        case MOS_TILE_X:
            gmmParams.Flags.Info.TiledX   = true;
            tileFormatLinux               = I915_TILING_X;
            break;
        default:
            gmmParams.Flags.Info.Linear   = true;
            tileFormatLinux               = I915_TILING_NONE;
    }

    if (nullptr != params.m_pSystemMemory)
    {
        // If user provides a system memory pointer, the gfx resource is backed
        // by the system memory pages. The resource is required to be linear.
        gmmParams.Flags.Info.Linear     = true;
        gmmParams.Flags.Info.Cacheable  = true;
        gmmParams.NoGfxMemory           = true;
        GMM_RESOURCE_INFO *tmpGmmResInfoPtr = pOsContextSpecific
                ->GetGmmClientContext()->CreateResInfoObject(&gmmParams);
        if (tmpGmmResInfoPtr == nullptr)
        {
            MOS_OS_ASSERTMESSAGE("Create GmmResInfo failed");
            return MOS_STATUS_UNKNOWN;
        }

        gmmParams.ExistingSysMemSize = GFX_ULONG_CAST(tmpGmmResInfoPtr->GetSizeSurface());
        gmmParams.pExistingSysMem = (GMM_VOIDPTR64)params.m_pSystemMemory;
        gmmParams.NoGfxMemory = false;
        gmmParams.Flags.Info.ExistingSysMem = true;

        pOsContextSpecific->GetGmmClientContext()
                ->DestroyResInfoObject(tmpGmmResInfoPtr);
    }
    else
    {
        gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(pOsContextSpecific->GetSkuTable(), FtrLocalMemory);
    }

    GMM_RESOURCE_INFO*  gmmResourceInfoPtr = pOsContextSpecific->GetGmmClientContext()->CreateResInfoObject(&gmmParams);

    if (gmmResourceInfoPtr == nullptr)
    {
        MOS_OS_ASSERTMESSAGE("Get gmmResourceInfoPtr failed.");
        return MOS_STATUS_INVALID_PARAMETER;
    }

    switch (gmmResourceInfoPtr->GetTileType())
    {
        case GMM_TILED_X:
            tileformat      = MOS_TILE_X;
            tileFormatLinux = I915_TILING_X;
            break;
        case GMM_TILED_Y:
            tileformat      = MOS_TILE_Y;
            tileFormatLinux = I915_TILING_Y;
            break;
        case GMM_NOT_TILED:
            tileformat      = MOS_TILE_LINEAR;
            tileFormatLinux = I915_TILING_NONE;
            break;
        default:
            tileformat      = MOS_TILE_Y;
            tileFormatLinux = I915_TILING_Y;
            break;
    }

    if (params.m_tileType== MOS_TILE_Y)
    {
        gmmResourceInfoPtr->SetMmcMode((GMM_RESOURCE_MMC_INFO)params.m_compressionMode, 0);
    }

    if(!params.m_pSystemMemory)
    {
        MemoryPolicyParameter memPolicyPar;
        MOS_ZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter));

        memPolicyPar.skuTable         = pOsContextSpecific->GetSkuTable();
        memPolicyPar.waTable          = pOsContextSpecific->GetWaTable();
        memPolicyPar.resInfo          = gmmResourceInfoPtr;
        memPolicyPar.resName          = params.m_name.c_str();
        memPolicyPar.preferredMemType = params.m_memType;

        mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar);
    }

    uint32_t bufPitch        = GFX_ULONG_CAST(gmmResourceInfoPtr->GetRenderPitch());
    uint32_t bufSize         = GFX_ULONG_CAST(gmmResourceInfoPtr->GetSizeSurface());
    bufHeight                = gmmResourceInfoPtr->GetBaseHeight();
    unsigned long linuxPitch = 0;
    MOS_LINUX_BO* boPtr      = nullptr;

    char bufName[m_maxBufNameLength];
    MosUtilities::MosSecureStrcpy(bufName, m_maxBufNameLength, params.m_name.c_str());

    MOS_TraceEventExt(EVENT_RESOURCE_ALLOCATE, EVENT_TYPE_START, nullptr, 0, nullptr, 0);
    if (nullptr != params.m_pSystemMemory)
    {
        boPtr = mos_bo_alloc_userptr(pOsContextSpecific->m_bufmgr,
                                      bufName,
                                      params.m_pSystemMemory,
                                      tileFormatLinux,
                                      bufPitch,
                                      bufSize,
                                      0);
    }
    // Only Linear and Y TILE supported
    else if (tileFormatLinux == I915_TILING_NONE)
    {
        boPtr = mos_bo_alloc(pOsContextSpecific->m_bufmgr, bufName, bufSize, 4096, mem_type);
    }
    else
    {
        boPtr = mos_bo_alloc_tiled(pOsContextSpecific->m_bufmgr,
                        bufName,
                        bufPitch,
                        bufSize/bufPitch,
                        1,
                        &tileFormatLinux,
                        &linuxPitch,
                        0,
                        mem_type);
        bufPitch = (uint32_t)linuxPitch;
    }

    m_mapped = false;
    if (boPtr)
    {
        m_format   = params.m_format;
        m_width    = params.m_width;
        m_height   = bufHeight;
        m_pitch    = bufPitch;
        m_count    = 0;
        m_bo       = boPtr;
        m_name     = params.m_name;
        m_pData    = (uint8_t*) boPtr->virt;

        m_gmmResInfo    = gmmResourceInfoPtr;
        m_mapped        = false;
        m_mmapOperation = MOS_MMAP_OPERATION_NONE;

        m_arraySize = 1;
        m_depth     = MOS_MAX(1, gmmResourceInfoPtr->GetBaseDepth());
        m_size      = (uint32_t)gmmResourceInfoPtr->GetSizeSurface();
        m_tileType  = tileformat;
        m_tileModeGMM           = (MOS_TILE_MODE_GMM)gmmResourceInfoPtr->GetTileModeSurfaceState();
        m_isGMMTileEnabled      = true;

        m_compressible    = gmmParams.Flags.Gpu.MMC ?
            (gmmResourceInfoPtr->GetMmcHint(0) == GMM_MMC_HINT_ON) : false;
        m_isCompressed    = gmmResourceInfoPtr->IsMediaMemoryCompressed(0);
        m_compressionMode = (MOS_RESOURCE_MMC_MODE)gmmResourceInfoPtr->GetMmcMode(0);

        MOS_OS_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource).",bufSize, params.m_width, bufHeight);

        struct {
            uint32_t m_handle;
            uint32_t m_resFormat;
            uint32_t m_baseWidth;
            uint32_t m_baseHeight;
            uint32_t m_pitch;
            uint32_t m_size;
            uint32_t m_resTileType;
            GMM_RESOURCE_FLAG m_resFlag;
            uint32_t          m_reserve;
        } eventData;

        eventData.m_handle       = boPtr->handle;
        eventData.m_baseWidth    = m_width;
        eventData.m_baseHeight   = m_height;
        eventData.m_pitch        = m_pitch;
        eventData.m_size         = m_size;
        eventData.m_resFormat    = m_format;
        eventData.m_resTileType  = m_tileType;
        eventData.m_resFlag      = gmmResourceInfoPtr->GetResFlags();
        eventData.m_reserve      = 0;
        MOS_TraceEventExt(EVENT_RESOURCE_ALLOCATE,
            EVENT_TYPE_INFO,
            &eventData,
            sizeof(eventData),
            params.m_name.c_str(),
            params.m_name.size() + 1);
    }
    else
    {
        MOS_OS_ASSERTMESSAGE("Fail to Alloc %7d bytes (%d x %d resource).",bufSize, params.m_width, params.m_height);
        status = MOS_STATUS_NO_SPACE;
    }
    MOS_TraceEventExt(EVENT_RESOURCE_ALLOCATE, EVENT_TYPE_END, &status, sizeof(status), nullptr, 0);

    m_memAllocCounterGfx++;
    return  status;
}

void GraphicsResourceSpecificNext::Free(OsContextNext* osContextPtr, uint32_t  freeFlag)
{
    MOS_OS_FUNCTION_ENTER;

    MOS_UNUSED(osContextPtr);
    MOS_UNUSED(freeFlag);

    OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);

    MOS_LINUX_BO* boPtr = m_bo;

    if (boPtr)
    {
        AuxTableMgr *auxTableMgr = pOsContextSpecific->GetAuxTableMgr();
        if (auxTableMgr)
        {
            auxTableMgr->UnmapResource(m_gmmResInfo, boPtr);
        }
        mos_bo_unreference(boPtr);
        m_bo = nullptr;
        if (nullptr != m_gmmResInfo)
        {
            pOsContextSpecific->GetGmmClientContext()->DestroyResInfoObject(m_gmmResInfo);
            m_gmmResInfo = nullptr;
            m_memAllocCounterGfx--;
        }
    }
    return;
}

bool GraphicsResourceSpecificNext::IsEqual(GraphicsResourceNext* toCompare)
{
    if  (toCompare == nullptr)
    {
        return false;
    }

    GraphicsResourceSpecificNext *resSpecificPtr = static_cast<GraphicsResourceSpecificNext *>(toCompare);

    return (m_bo == resSpecificPtr->m_bo);
}

bool GraphicsResourceSpecificNext::IsValid()
{
    return (m_bo != nullptr);
}

MOS_STATUS GraphicsResourceSpecificNext::ConvertToMosResource(MOS_RESOURCE* pMosResource)
{
    if (pMosResource == nullptr)
    {
        return MOS_STATUS_INVALID_PARAMETER;
    }

    pMosResource->Format   = m_format;
    pMosResource->iWidth   = m_width;
    pMosResource->iHeight  = m_height;
    pMosResource->iPitch   = m_pitch;
    pMosResource->iDepth   = m_depth;
    pMosResource->TileType = m_tileType;
    pMosResource->TileModeGMM = m_tileModeGMM;
    pMosResource->bGMMTileEnabled = m_isGMMTileEnabled;
    pMosResource->iCount   = 0;
    pMosResource->pData    = m_pData;
    pMosResource->bufname  = m_name.c_str();
    pMosResource->bo       = m_bo;
    pMosResource->bMapped  = m_mapped;
    pMosResource->MmapOperation = m_mmapOperation;
    pMosResource->pGmmResInfo   = m_gmmResInfo;

    pMosResource->user_provided_va    = m_userProvidedVA;

    pMosResource->pGfxResourceNext    = this;

    return  MOS_STATUS_SUCCESS;
}

void* GraphicsResourceSpecificNext::Lock(OsContextNext* osContextPtr, LockParams& params)
{
    MOS_OS_FUNCTION_ENTER;

    if (osContextPtr == nullptr)
    {
        MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
        return nullptr;
    }

    if (osContextPtr ->GetOsContextValid() == false)
    {
        MOS_OS_ASSERTMESSAGE("The OS context got is not valid.");
        return nullptr;
    }

    OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);

    void*   dataPtr     = nullptr;
    MOS_LINUX_BO* boPtr = m_bo;

    if (boPtr)
    {
        // Do decompression for a compressed surface before lock
        const auto pGmmResInfo = m_gmmResInfo;
        MOS_OS_ASSERT(pGmmResInfo);
        GMM_RESOURCE_FLAG GmmFlags = pGmmResInfo->GetResFlags();

        if (!params.m_noDecompress &&
            (((GmmFlags.Gpu.MMC || GmmFlags.Gpu.CCS) && GmmFlags.Info.MediaCompressed) ||
             pGmmResInfo->IsMediaMemoryCompressed(0)))
        {
            MOS_RESOURCE mosResource = {};
            ConvertToMosResource(&mosResource);

            MosDecompression *mosDecompression = pOsContextSpecific->GetMosDecompression();
            if (nullptr == mosDecompression)
            {
                MOS_OS_ASSERTMESSAGE("mosDecompression is NULL.");
                return nullptr;
            }
            mosDecompression->MemoryDecompress(&mosResource);
        }

        if(false == m_mapped)
        {
            if (pOsContextSpecific->IsAtomSoc())
            {
                mos_gem_bo_map_gtt(boPtr);
            }
            else
            {
                if (m_tileType != MOS_TILE_LINEAR && !params.m_tileAsTiled)
                {
                    if (pOsContextSpecific->UseSwSwizzling())
                    {
                        mos_bo_map(boPtr, ( OSKM_LOCKFLAG_WRITEONLY & params.m_writeRequest ));
                        m_mmapOperation = MOS_MMAP_OPERATION_MMAP;
                        if (m_systemShadow == nullptr)
                        {
                            m_systemShadow = (uint8_t *)MOS_AllocMemory(boPtr->size);
                            MOS_OS_CHECK_CONDITION((m_systemShadow == nullptr), "Failed to allocate shadow surface", nullptr);
                        }
                        if (m_systemShadow)
                        {
                            int32_t flags = pOsContextSpecific->GetTileYFlag() ? 0 : 1;
                            uint64_t surfSize = m_gmmResInfo->GetSizeMainSurface();
                            MOS_OS_CHECK_CONDITION((m_tileType != MOS_TILE_Y), "Unsupported tile type", nullptr);
                            MOS_OS_CHECK_CONDITION((boPtr->size <= 0 || m_pitch <= 0), "Invalid BO size or pitch", nullptr);
                            MosUtilities::MosSwizzleData((uint8_t*)boPtr->virt, m_systemShadow,
                                            MOS_TILE_Y, MOS_TILE_LINEAR,
                                            (int32_t)(surfSize / m_pitch), m_pitch, flags);
                        }
                    }
                    else
                    {
                        mos_gem_bo_map_gtt(boPtr);
                        m_mmapOperation = MOS_MMAP_OPERATION_MMAP_GTT;
                    }
                }
                else if (params.m_uncached)
                {
                    mos_gem_bo_map_wc(boPtr);
                    m_mmapOperation = MOS_MMAP_OPERATION_MMAP_WC;
                }
                else
                {
                    mos_bo_map(boPtr, ( OSKM_LOCKFLAG_WRITEONLY & params.m_writeRequest ));
                    m_mmapOperation = MOS_MMAP_OPERATION_MMAP;
                }
            }
            m_mapped = true;
            m_pData  = m_systemShadow ? m_systemShadow : (uint8_t *)boPtr->virt;
        }

        dataPtr = m_pData;
    }

    MOS_OS_ASSERT(dataPtr);
    return dataPtr;
}

MOS_STATUS GraphicsResourceSpecificNext::Unlock(OsContextNext* osContextPtr)
{
    MOS_OS_FUNCTION_ENTER;

    if (osContextPtr == nullptr)
    {
        MOS_OS_ASSERTMESSAGE("Unable to get the active OS context.");
        return MOS_STATUS_INVALID_HANDLE;
    }

    if (osContextPtr ->GetOsContextValid() == false)
    {
        MOS_OS_ASSERTMESSAGE("The OS context got is not valid.");
        return MOS_STATUS_INVALID_HANDLE;
    }

    OsContextSpecificNext *pOsContextSpecific = static_cast<OsContextSpecificNext *>(osContextPtr);

    MOS_LINUX_BO* boPtr = m_bo;
    if (boPtr)
    {
        if (m_mapped)
        {
           if (pOsContextSpecific->IsAtomSoc())
           {
               mos_gem_bo_unmap_gtt(boPtr);
           }
           else
           {

               if (m_systemShadow)
               {
                   int32_t flags = pOsContextSpecific->GetTileYFlag() ? 0 : 1;
                   uint64_t surfSize = m_gmmResInfo->GetSizeMainSurface();
                   MosUtilities::MosSwizzleData(m_systemShadow, (uint8_t*)boPtr->virt,
                                   MOS_TILE_LINEAR, MOS_TILE_Y,
                                   (int32_t)(surfSize / m_pitch), m_pitch, flags);
                   MOS_FreeMemory(m_systemShadow);
                   m_systemShadow = nullptr;
               }

               switch(m_mmapOperation)
               {
                   case MOS_MMAP_OPERATION_MMAP_GTT:
                        mos_gem_bo_unmap_gtt(boPtr);
                        break;
                   case MOS_MMAP_OPERATION_MMAP_WC:
                        mos_gem_bo_unmap_wc(boPtr);
                        break;
                   case MOS_MMAP_OPERATION_MMAP:
                        mos_bo_unmap(boPtr);
                        break;
                   default:
                        MOS_OS_ASSERTMESSAGE("Invalid mmap operation type");
                        break;
               }
            }

            m_mapped           = false;
            m_mmapOperation    = MOS_MMAP_OPERATION_NONE;

            boPtr->virt        = nullptr;
            m_bo = boPtr;
        }

        m_pData = nullptr;
    }

    return MOS_STATUS_SUCCESS;
}

MOS_STATUS GraphicsResourceSpecificNext::AllocateExternalResource(
    MOS_STREAM_HANDLE streamState,
    PMOS_ALLOC_GFXRES_PARAMS params,
    MOS_RESOURCE_HANDLE& resource)
{
    MOS_OS_FUNCTION_ENTER;

    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
    
    MOS_OS_CHK_NULL_RETURN(resource);
    MOS_OS_CHK_NULL_RETURN(streamState);
    MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext);
    
    const char *bufname = params->pBufName;;
    int32_t iSize = 0;
    int32_t iPitch = 0;
    unsigned long ulPitch = 0;
    MOS_LINUX_BO *bo = nullptr;
    MOS_TILE_TYPE tileformat = params->TileType;
    uint32_t tileformat_linux = I915_TILING_NONE;
    int32_t iHeight = params->dwHeight;
    int32_t iAlignedHeight = 0;
    GMM_RESCREATE_PARAMS gmmParams;
    GMM_RESOURCE_INFO *gmmResourceInfo = nullptr;
    GMM_RESOURCE_TYPE resourceType = RESOURCE_2D;

    MosUtilities::MosZeroMemory(&gmmParams, sizeof(gmmParams));

    MOS_OS_CHK_NULL_RETURN(streamState->perStreamParameters);
    auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;

    if (nullptr == perStreamParameters)
    {
        MOS_OS_ASSERTMESSAGE("input parameter perStreamParameters is NULL.");
        return MOS_STATUS_INVALID_PARAMETER;
    }
    switch (params->Format)
    {
    case Format_Buffer:
    case Format_RAW:
        resourceType   = RESOURCE_BUFFER;
        iAlignedHeight = 1;
        //indicate buffer Restriction is Vertex.
        gmmParams.Flags.Gpu.State = true;
        break;
    case Format_L8:
    case Format_L16:
    case Format_STMM:
    case Format_AI44:
    case Format_IA44:
    case Format_R5G6B5:
    case Format_R8G8B8:
    case Format_X8R8G8B8:
    case Format_A8R8G8B8:
    case Format_X8B8G8R8:
    case Format_A8B8G8R8:
    case Format_R32S:
    case Format_R32F:
    case Format_V8U8:
    case Format_YUY2:
    case Format_UYVY:
    case Format_P8:
    case Format_A8:
    case Format_AYUV:
    case Format_NV12:
    case Format_NV21:
    case Format_YV12:
    case Format_Buffer_2D:
    case Format_R32U:
    case Format_444P:
    case Format_422H:
    case Format_422V:
    case Format_IMC3:
    case Format_411P:
    case Format_411R:
    case Format_RGBP:
    case Format_BGRP:
    case Format_R16U:
    case Format_R8U:
    case Format_R8UN:
    case Format_P010:
    case Format_P016:
    case Format_Y216:
    case Format_Y416:
    case Format_P208:
    case Format_Y210:
    case Format_Y410:
    case Format_R16F:
        resourceType = RESOURCE_2D;
        //indicate buffer Restriction is Planar surface restrictions.
        gmmParams.Flags.Gpu.Video = true;
        break;
    default:
        MOS_OS_ASSERTMESSAGE("Unsupported format");
        eStatus = MOS_STATUS_UNIMPLEMENTED;
        return eStatus;
    }

    // Create GmmResourceInfo
    gmmParams.BaseWidth  = params->dwWidth;
    gmmParams.BaseHeight = iAlignedHeight;
    gmmParams.ArraySize  = 1;
    gmmParams.Type       = resourceType;
    gmmParams.Format     = MosOsSpecificNext::Mos_Specific_ConvertMosFmtToGmmFmt(params->Format);

    MOS_OS_CHECK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID,
        "Unsupported format",
        MOS_STATUS_UNKNOWN);

    switch (tileformat)
    {
    case MOS_TILE_Y:
        gmmParams.Flags.Gpu.MMC = params->bIsCompressible;
        tileformat_linux        = I915_TILING_Y;
        break;
    case MOS_TILE_X:
        gmmParams.Flags.Info.TiledX = true;
        tileformat_linux            = I915_TILING_X;
        break;
    default:
        gmmParams.Flags.Info.Linear = true;
        tileformat_linux            = I915_TILING_NONE;
    }
    gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&perStreamParameters->SkuTable, FtrLocalMemory);

    resource->pGmmResInfo = gmmResourceInfo = perStreamParameters->pGmmClientContext->CreateResInfoObject(&gmmParams);

    MOS_OS_CHK_NULL_RETURN(gmmResourceInfo);

    switch (gmmResourceInfo->GetTileType())
    {
    case GMM_TILED_X:
        tileformat       = MOS_TILE_X;
        tileformat_linux = I915_TILING_X;
        break;
    case GMM_TILED_Y:
        tileformat       = MOS_TILE_Y;
        tileformat_linux = I915_TILING_Y;
        break;
    case GMM_NOT_TILED:
        tileformat       = MOS_TILE_LINEAR;
        tileformat_linux = I915_TILING_NONE;
        break;
    default:
        tileformat       = MOS_TILE_Y;
        tileformat_linux = I915_TILING_Y;
        break;
    }

    if (params->TileType == MOS_TILE_Y)
    {
        gmmResourceInfo->SetMmcMode((GMM_RESOURCE_MMC_INFO)params->CompressionMode, 0);
    }

    iPitch  = GFX_ULONG_CAST(gmmResourceInfo->GetRenderPitch());
    iSize   = GFX_ULONG_CAST(gmmResourceInfo->GetSizeSurface());
    iHeight = gmmResourceInfo->GetBaseHeight();

    // Only Linear and Y TILE supported
    if (tileformat_linux == I915_TILING_NONE)
    {
        bo = mos_bo_alloc(perStreamParameters->bufmgr, bufname, iSize, 4096, MOS_MEMPOOL_VIDEOMEMORY);
    }
    else
    {
        bo = mos_bo_alloc_tiled(perStreamParameters->bufmgr,
                        bufname,
                        iPitch,
                        iSize / iPitch,
                        1,
                        &tileformat_linux,
                        &ulPitch,
                        0,
                        MOS_MEMPOOL_VIDEOMEMORY);
        iPitch = (int32_t)ulPitch;
    }

    resource->bMapped = false;
    if (bo)
    {
        resource->Format   = params->Format;
        resource->iWidth   = params->dwWidth;
        resource->iHeight  = iHeight;
        resource->iPitch   = iPitch;
        resource->iCount   = 0;
        resource->bufname  = bufname;
        resource->bo       = bo;
        resource->TileType = tileformat;
        resource->TileModeGMM     = (MOS_TILE_MODE_GMM)gmmResourceInfo->GetTileModeSurfaceState();
        resource->bGMMTileEnabled = true;
        resource->pData    = (uint8_t *)bo->virt;  //It is useful for batch buffer to fill commands
        MOS_OS_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource).", iSize, params->dwWidth, iHeight);
    }
    else
    {
        MOS_OS_ASSERTMESSAGE("Fail to Alloc %7d bytes (%d x %d resource).", iSize, params->dwWidth, params->dwHeight);
        eStatus = MOS_STATUS_NO_SPACE;
    }

    return eStatus;
}

MOS_STATUS GraphicsResourceSpecificNext::FreeExternalResource(
    MOS_STREAM_HANDLE   streamState,
    MOS_RESOURCE_HANDLE resource,
    uint32_t            flag)
{
    MOS_OS_FUNCTION_ENTER;

    MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
    
    MOS_OS_CHK_NULL_RETURN(resource);
    MOS_OS_CHK_NULL_RETURN(streamState);
    MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext);
    
    if (resource && resource->bo)
    {
        OsContextSpecificNext *osCtx = static_cast<OsContextSpecificNext *>(streamState->osDeviceContext);
        if (osCtx == nullptr)
        {
            MOS_OS_ASSERTMESSAGE("osCtx is nullptr!");
            return MOS_STATUS_NULL_POINTER;
        }
        else
        {
            AuxTableMgr *auxTableMgr = osCtx->GetAuxTableMgr();

            // Unmap Resource from Aux Table
            if (auxTableMgr)
            {
                auxTableMgr->UnmapResource(resource->pGmmResInfo, resource->bo);
            }
        }

        mos_bo_unreference((MOS_LINUX_BO *)(resource->bo));

        MOS_OS_CHK_NULL_RETURN(streamState->perStreamParameters);
        auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;

        if (perStreamParameters != nullptr && perStreamParameters->contextOffsetList.size())
        {
            MOS_CONTEXT *pOsCtx   = perStreamParameters;
            auto         item_ctx = pOsCtx->contextOffsetList.begin();

            for (; item_ctx != pOsCtx->contextOffsetList.end();)
            {
                if (item_ctx->target_bo == resource->bo)
                {
                    item_ctx = pOsCtx->contextOffsetList.erase(item_ctx);
                }
                else
                {
                    item_ctx++;
                }
            }
        }

        resource->bo = nullptr;
    }
    
    return eStatus;
}

void* GraphicsResourceSpecificNext::LockExternalResource(
    MOS_STREAM_HANDLE   streamState,
    MOS_RESOURCE_HANDLE resource,
    PMOS_LOCK_PARAMS    flags)
{
    MOS_OS_FUNCTION_ENTER;

    void *pData = nullptr;
    if (nullptr == streamState)
    {
        MOS_OS_ASSERTMESSAGE("input parameter streamState is NULL.");
        return nullptr;
    }

    if (nullptr == resource)
    {
        MOS_OS_ASSERTMESSAGE("input parameter resource is NULL.");
        return nullptr;
    }
    
    if (streamState->perStreamParameters == nullptr)
    {
        MOS_OS_ASSERTMESSAGE("perStreamParameters is nullptr, skip lock");
        return nullptr;
    }
    auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;
    if (resource && resource->bo && resource->pGmmResInfo)
    {
        MOS_LINUX_BO *bo = resource->bo;
        GMM_RESOURCE_FLAG GmmFlags = resource->pGmmResInfo->GetResFlags();

        // Do decompression for a compressed surface before lock
        if (!flags->NoDecompress &&
            (((GmmFlags.Gpu.MMC || GmmFlags.Gpu.CCS) && GmmFlags.Info.MediaCompressed) ||
            resource->pGmmResInfo->IsMediaMemoryCompressed(0)))
        {
            OsContextNext *osCtx = streamState->osDeviceContext;
            if (nullptr == osCtx)
            {
                MOS_OS_ASSERTMESSAGE("osCtx is NULL.");
                return nullptr;
            }
            MosDecompression *mosDecompression = osCtx->GetMosDecompression();
            if (nullptr == mosDecompression)
            {
                MOS_OS_ASSERTMESSAGE("mosDecompression is NULL.");
                return nullptr;
            }
            mosDecompression->MemoryDecompress(resource);
        }

        if (false == resource->bMapped)
        {
            if (perStreamParameters->bIsAtomSOC)
            {
                mos_gem_bo_map_gtt(bo);
            }
            else
            {
                if (resource->TileType != MOS_TILE_LINEAR && !flags->TiledAsTiled)
                {
                    if (perStreamParameters->bUseSwSwizzling)
                    {
                        mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY & flags->WriteOnly));
                        resource->MmapOperation = MOS_MMAP_OPERATION_MMAP;
                        if (resource->pSystemShadow == nullptr)
                        {
                            resource->pSystemShadow = (uint8_t *)MOS_AllocMemory(bo->size);
                            MOS_OS_CHECK_CONDITION((resource->pSystemShadow == nullptr), "Failed to allocate shadow surface", nullptr);
                        }
                        if (resource->pSystemShadow)
                        {
                            int32_t swizzleflags = perStreamParameters->bTileYFlag ? 0 : 1;
                            MOS_OS_CHECK_CONDITION((resource->TileType != MOS_TILE_Y), "Unsupported tile type", nullptr);
                            MOS_OS_CHECK_CONDITION((bo->size <= 0 || resource->iPitch <= 0), "Invalid BO size or pitch", nullptr);
                            MosUtilities::MosSwizzleData((uint8_t *)bo->virt, resource->pSystemShadow, MOS_TILE_Y, MOS_TILE_LINEAR, bo->size / resource->iPitch, resource->iPitch, swizzleflags);
                        }
                    }
                    else
                    {
                        mos_gem_bo_map_gtt(bo);
                        resource->MmapOperation = MOS_MMAP_OPERATION_MMAP_GTT;
                    }
                }
                else if (flags->Uncached)
                {
                    mos_gem_bo_map_wc(bo);
                    resource->MmapOperation = MOS_MMAP_OPERATION_MMAP_WC;
                }
                else
                {
                    mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY & flags->WriteOnly));
                    resource->MmapOperation = MOS_MMAP_OPERATION_MMAP;
                }
            }
            resource->pData   = resource->pSystemShadow ? resource->pSystemShadow : (uint8_t *)bo->virt;
            resource->bMapped = true;
        }

        pData = resource->pData;
    }

    MOS_OS_ASSERT(pData);
    return pData;
}

MOS_STATUS GraphicsResourceSpecificNext::UnlockExternalResource(
    MOS_STREAM_HANDLE   streamState,
    MOS_RESOURCE_HANDLE resource)
{
    MOS_OS_FUNCTION_ENTER;
    
    MOS_OS_CHK_NULL_RETURN(resource);
    MOS_OS_CHK_NULL_RETURN(streamState);
    MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext);
    
    MOS_OS_CHK_NULL_RETURN(streamState->perStreamParameters);
    auto perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters;

    if (resource->bo)
    {
        if (true == resource->bMapped)
        {
            if (perStreamParameters->bIsAtomSOC)
            {
                mos_gem_bo_unmap_gtt(resource->bo);
            }
            else
            {
                if (resource->pSystemShadow)
                {
                    int32_t flags = perStreamParameters->bTileYFlag ? 0 : 1;
                    MosUtilities::MosSwizzleData(resource->pSystemShadow, (uint8_t *)resource->bo->virt, MOS_TILE_LINEAR, MOS_TILE_Y, resource->bo->size / resource->iPitch, resource->iPitch, flags);
                    MOS_FreeMemory(resource->pSystemShadow);
                    resource->pSystemShadow = nullptr;
                }

                switch (resource->MmapOperation)
                {
                case MOS_MMAP_OPERATION_MMAP_GTT:
                    mos_gem_bo_unmap_gtt(resource->bo);
                    break;
                case MOS_MMAP_OPERATION_MMAP_WC:
                    mos_gem_bo_unmap_wc(resource->bo);
                    break;
                case MOS_MMAP_OPERATION_MMAP:
                    mos_bo_unmap(resource->bo);
                    break;
                default:
                    MOS_OS_ASSERTMESSAGE("Invalid mmap operation type");
                    break;
                }
            }
            resource->bo->virt = nullptr;
            resource->bMapped  = false;
        }
        resource->pData = nullptr;
    }

    return MOS_STATUS_SUCCESS;
}
