| /* |
| * 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; |
| } |