| /* |
| * Copyright (c) 2021-2022, 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 media_libva_util_next.cpp |
| //! \brief libva util next implementaion. |
| //! |
| #include <sys/time.h> |
| #include "inttypes.h" |
| #include "media_libva_util_next.h" |
| #include "mos_utilities.h" |
| #include "mos_os.h" |
| #include "mos_defs.h" |
| #include "hwinfo_linux.h" |
| #include "ddi_decode_base_specific.h" |
| #include "media_ddi_encode_base.h" |
| //#include "ddi_libva_decoder_specific.h" |
| #include "media_libva_decoder.h" |
| #include "media_libva_encoder.h" |
| #include "memory_policy_manager.h" |
| #include "drm_fourcc.h" |
| |
| // will remove when mtl open source |
| #define INTEL_PRELIM_ID_FLAG (1ULL << 55) |
| |
| #define intel_prelim_fourcc_mod_code(val) \ |
| (fourcc_mod_code(INTEL, (val)) | INTEL_PRELIM_ID_FLAG) |
| |
| /* this definition is to avoid duplicate drm_fourcc.h this file is updated seldom */ |
| #ifndef I915_FORMAT_MOD_4_TILED_MTL_MC_CCS |
| #define I915_FORMAT_MOD_4_TILED_MTL_MC_CCS fourcc_mod_code(INTEL, 14) |
| #endif |
| #ifndef I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC |
| #define I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC fourcc_mod_code(INTEL, 15) |
| #endif |
| |
| // default protected surface tag |
| #define PROTECTED_SURFACE_TAG 0x3000f |
| |
| int32_t MediaLibvaUtilNext::m_frameCountFps = -1; |
| struct timeval MediaLibvaUtilNext::m_tv1 = {}; |
| pthread_mutex_t MediaLibvaUtilNext::m_fpsMutex = PTHREAD_MUTEX_INITIALIZER; |
| int32_t MediaLibvaUtilNext::m_vaFpsSampleSize = 100; |
| bool MediaLibvaUtilNext::m_isMediaFpsPrintFpsEnabled = false; |
| |
| VAStatus MediaLibvaUtilNext::SetDefaultTileFormat( |
| DDI_MEDIA_FORMAT format, |
| uint32_t surfaceUsageHint, |
| MEDIA_FEATURE_TABLE *skuTable, |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms |
| ) |
| { |
| VAStatus status = VA_STATUS_SUCCESS; |
| uint32_t tileFormat = I915_TILING_Y; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(skuTable, "skuTable is nullptr", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| switch (format) |
| { |
| case Media_Format_X8R8G8B8: |
| case Media_Format_X8B8G8R8: |
| case Media_Format_A8B8G8R8: |
| case Media_Format_R8G8B8A8: |
| case Media_Format_R5G6B5: |
| case Media_Format_R8G8B8: |
| case Media_Format_R10G10B10A2: |
| case Media_Format_B10G10R10A2: |
| case Media_Format_R10G10B10X2: |
| case Media_Format_B10G10R10X2: |
| case Media_Format_A16R16G16B16: |
| case Media_Format_A16B16G16R16: |
| case Media_Format_YV12: |
| case Media_Format_I420: |
| case Media_Format_IYUV: |
| if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint && |
| !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE)) |
| { |
| tileFormat = I915_TILING_NONE; |
| } |
| break; |
| case Media_Format_RGBP: |
| case Media_Format_BGRP: |
| if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint && |
| !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE)) |
| { |
| if(!(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_DECODER)) |
| { |
| tileFormat = I915_TILING_NONE; |
| break; |
| } |
| //Planar type surface align 32 to improve performance. |
| params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32); |
| } |
| params.alignedWidth = MOS_ALIGN_CEIL(params.width, 8); |
| if (surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE) |
| { |
| if (format == Media_Format_RGBP) |
| { |
| //Planar type surface align 32 to improve performance. |
| params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32); |
| } |
| } |
| tileFormat = I915_TILING_Y; |
| break; |
| case Media_Format_A8R8G8B8: |
| if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint && |
| !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_DECODER) && |
| !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE) && |
| !(MEDIA_IS_SKU(skuTable, FtrRenderCompressionOnly) && |
| MEDIA_IS_SKU(skuTable, FtrE2ECompression))) |
| { |
| tileFormat = I915_TILING_NONE; |
| } |
| break; |
| case Media_Format_NV12: |
| case Media_Format_NV21: |
| case Media_Format_444P: |
| case Media_Format_422H: |
| case Media_Format_411P: |
| case Media_Format_422V: |
| case Media_Format_IMC3: |
| case Media_Format_400P: |
| case Media_Format_P010: |
| case Media_Format_P012: |
| case Media_Format_P016: |
| case Media_Format_YUY2: |
| case Media_Format_Y210: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y212: |
| #endif |
| case Media_Format_Y216: |
| case Media_Format_AYUV: |
| #if VA_CHECK_VERSION(1, 13, 0) |
| case Media_Format_XYUV: |
| #endif |
| case Media_Format_Y410: |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y412: |
| #endif |
| case Media_Format_Y416: |
| case Media_Format_Y8: |
| case Media_Format_Y16S: |
| case Media_Format_Y16U: |
| case Media_Format_VYUY: |
| case Media_Format_YVYU: |
| case Media_Format_UYVY: |
| if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER != surfaceUsageHint && |
| !(surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE)) |
| { |
| //Planar type surface align 32 to improve performance. |
| params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32); |
| } |
| params.alignedWidth = MOS_ALIGN_CEIL(params.width, 8); |
| if (surfaceUsageHint & VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE) |
| { |
| if ((format == Media_Format_NV12) || (format == Media_Format_P010)) |
| { |
| //Planar type surface align 32 to improve performance. |
| params.alignedHeight = MOS_ALIGN_CEIL(params.height, 32); |
| } |
| } |
| tileFormat = I915_TILING_Y; |
| break; |
| case Media_Format_Buffer: |
| tileFormat = I915_TILING_NONE; |
| break; |
| default: |
| tileFormat = I915_TILING_NONE; |
| DDI_ASSERTMESSAGE("Unsupported format"); |
| status = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| |
| if (VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER & surfaceUsageHint) |
| { |
| params.alignedWidth = MOS_ALIGN_CEIL(params.alignedWidth, 16); |
| params.alignedHeight = MOS_ALIGN_CEIL(params.alignedHeight, 16); |
| } |
| params.tileFormat = tileFormat; |
| return status; |
| } |
| |
| void MediaLibvaUtilNext::InitSurfaceAllocateParams( |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms, |
| int32_t width, |
| int32_t height, |
| DDI_MEDIA_FORMAT format, |
| int memType, |
| uint32_t surfaceUsageHint) |
| { |
| DDI_FUNC_ENTER; |
| params.pitch = 0; |
| params.tileFormat = I915_TILING_NONE; |
| params.alignedWidth = params.width = width; |
| params.alignedHeight = params.height = height; |
| params.format = format; |
| params.cpTag = 0; |
| params.memType = memType; |
| #ifdef _MMC_SUPPORTED |
| params.bMemCompEnable = true; |
| #else |
| params.bMemCompEnable = false; |
| #endif |
| params.bMemCompRC = false; |
| return; |
| } |
| |
| VAStatus MediaLibvaUtilNext::SetSurfaceParameterFromModifier( |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms, |
| uint64_t modifier) |
| { |
| DDI_FUNC_ENTER; |
| switch (modifier) |
| { |
| case I915_FORMAT_MOD_4_TILED: |
| params.tileFormat = I915_TILING_Y; |
| params.bMemCompEnable = false; |
| break; |
| case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC: |
| params.tileFormat = I915_TILING_Y; |
| params.bMemCompEnable = true; |
| params.bMemCompRC = true; |
| break; |
| case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: |
| params.tileFormat = I915_TILING_Y; |
| params.bMemCompEnable = true; |
| params.bMemCompRC = false; |
| break; |
| case DRM_FORMAT_MOD_LINEAR: |
| params.tileFormat = I915_TILING_NONE; |
| params.bMemCompEnable = false; |
| break; |
| case I915_FORMAT_MOD_X_TILED: |
| params.tileFormat = I915_TILING_X; |
| params.bMemCompEnable = false; |
| break; |
| case I915_FORMAT_MOD_Y_TILED: |
| case I915_FORMAT_MOD_Yf_TILED: |
| params.tileFormat = I915_TILING_Y; |
| params.bMemCompEnable = false; |
| break; |
| case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: |
| params.tileFormat = I915_TILING_Y; |
| params.bMemCompEnable = true; |
| params.bMemCompRC = true; |
| break; |
| case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: |
| params.tileFormat = I915_TILING_Y; |
| params.bMemCompEnable = true; |
| params.bMemCompRC = false; |
| break; |
| default: |
| DDI_ASSERTMESSAGE("Unsupported modifier."); |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus MediaLibvaUtilNext::GenerateGmmParamsForNoneCompressionExternalSurface( |
| GMM_RESCREATE_CUSTOM_PARAMS &gmmCustomParams, |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms, |
| PDDI_MEDIA_SURFACE mediaSurface) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(mediaSurface, "mediaSurface is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaSurface->pSurfDesc, "mediaSurface desc is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| int32_t baseHeight = 0; |
| DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiPlanes == 0, |
| "Invalid plane number.", |
| VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| if (mediaSurface->pSurfDesc->uiPlanes == 1) |
| { |
| DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiSize == 0, |
| "Invalid Size.", |
| VA_STATUS_ERROR_INVALID_PARAMETER); |
| baseHeight = mediaSurface->pSurfDesc->uiSize / params.pitch; |
| } |
| else |
| { |
| DDI_CHK_CONDITION(mediaSurface->pSurfDesc->uiOffsets[1] == 0, |
| "Invalid offset.", |
| VA_STATUS_ERROR_INVALID_PARAMETER); |
| baseHeight = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch; |
| } |
| |
| // Create GmmResourceInfo |
| MosUtilities::MosZeroMemory(&gmmCustomParams, sizeof(gmmCustomParams)); |
| gmmCustomParams.Type = RESOURCE_2D; |
| gmmCustomParams.Format = ConvertMediaFmtToGmmFmt(params.format); |
| gmmCustomParams.BaseWidth64 = params.width; |
| gmmCustomParams.BaseHeight = baseHeight; |
| gmmCustomParams.Pitch = params.pitch; |
| gmmCustomParams.Size = mediaSurface->pSurfDesc->uiSize; |
| gmmCustomParams.BaseAlignment = 4096; |
| gmmCustomParams.NoOfPlanes = mediaSurface->pSurfDesc->uiPlanes; |
| gmmCustomParams.CpTag = params.cpTag; |
| switch (params.tileFormat) |
| { |
| case I915_TILING_Y: |
| gmmCustomParams.Flags.Info.TiledY = true; |
| break; |
| case I915_TILING_X: |
| gmmCustomParams.Flags.Info.TiledX = true; |
| break; |
| case I915_TILING_NONE: |
| default: |
| gmmCustomParams.Flags.Info.Linear = true; |
| } |
| |
| switch (mediaSurface->pSurfDesc->uiPlanes) |
| { |
| case 1: |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch; |
| break; |
| case 2: |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch; |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch; |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch; |
| break; |
| case 3: |
| if (mediaSurface->format == Media_Format_YV12) |
| { |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch; |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch; |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch; |
| } |
| else |
| { |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_Y] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_Y] = mediaSurface->pSurfDesc->uiOffsets[0] / params.pitch; |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_U] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_U] = mediaSurface->pSurfDesc->uiOffsets[1] / params.pitch; |
| gmmCustomParams.PlaneOffset.X[GMM_PLANE_V] = 0; |
| gmmCustomParams.PlaneOffset.Y[GMM_PLANE_V] = mediaSurface->pSurfDesc->uiOffsets[2] / params.pitch; |
| } |
| break; |
| default: |
| DDI_ASSERTMESSAGE("Invalid plane number."); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus MediaLibvaUtilNext::GenerateGmmParamsForCompressionExternalSurface( |
| GMM_RESCREATE_PARAMS &gmmParams, |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms, |
| PDDI_MEDIA_CONTEXT mediaDrvCtx) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(mediaDrvCtx, "media context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| MosUtilities::MosZeroMemory(&gmmParams, sizeof(gmmParams)); |
| gmmParams.BaseWidth = params.width; |
| gmmParams.BaseHeight = params.height; |
| gmmParams.ArraySize = 1; |
| gmmParams.Type = RESOURCE_2D; |
| gmmParams.CpTag = params.cpTag; |
| gmmParams.Format = ConvertMediaFmtToGmmFmt(params.format); |
| |
| DDI_CHK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID, "Unsupported format", VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT); |
| |
| switch (params.tileFormat) |
| { |
| case I915_TILING_Y: |
| gmmParams.Flags.Gpu.MMC = false; |
| if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrE2ECompression) && |
| (!MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableVPMmc) && |
| !MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableCodecMmc)) && |
| params.bMemCompEnable) |
| { |
| gmmParams.Flags.Gpu.MMC = true; |
| gmmParams.Flags.Info.MediaCompressed = 1; |
| gmmParams.Flags.Info.RenderCompressed = 0; |
| gmmParams.Flags.Gpu.CCS = 1; |
| gmmParams.Flags.Gpu.RenderTarget = 1; |
| gmmParams.Flags.Gpu.UnifiedAuxSurface = 1; |
| |
| if (params.bMemCompRC) |
| { |
| gmmParams.Flags.Info.MediaCompressed = 0; |
| gmmParams.Flags.Info.RenderCompressed = 1; |
| } |
| |
| if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrRenderCompressionOnly)) |
| { |
| gmmParams.Flags.Info.MediaCompressed = 0; |
| |
| if (params.format == Media_Format_X8R8G8B8 || |
| params.format == Media_Format_X8B8G8R8 || |
| params.format == Media_Format_A8B8G8R8 || |
| params.format == Media_Format_A8R8G8B8 || |
| params.format == Media_Format_R8G8B8A8) |
| { |
| gmmParams.Flags.Info.MediaCompressed = 0; |
| gmmParams.Flags.Info.RenderCompressed = 1; |
| } |
| } |
| |
| if(MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrFlatPhysCCS)) |
| { |
| gmmParams.Flags.Gpu.UnifiedAuxSurface = 0; |
| } |
| } |
| break; |
| case I915_TILING_X: |
| gmmParams.Flags.Info.TiledX = true; |
| break; |
| case I915_TILING_NONE: |
| default: |
| gmmParams.Flags.Info.Linear = true; |
| } |
| gmmParams.Flags.Gpu.Video = true; |
| gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrLocalMemory); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus MediaLibvaUtilNext::CreateExternalSurface( |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms, |
| PDDI_MEDIA_SURFACE mediaSurface, |
| PDDI_MEDIA_CONTEXT mediaDrvCtx) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(mediaSurface, "mediaSurface is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaSurface->pSurfDesc, "mediaSurface desc is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaDrvCtx, "media context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaDrvCtx->pDrmBufMgr, "drm buffer mgr is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaDrvCtx->pGmmClientContext, "gmm context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| GMM_RESOURCE_INFO *gmmResourceInfo = nullptr; |
| MOS_LINUX_BO *bo = nullptr; |
| uint32_t swizzle_mode; |
| VAStatus status = VA_STATUS_SUCCESS; |
| |
| // Default set as compression not supported, surface compression import only support from Memory Type VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 |
| params.bMemCompEnable = false; |
| params.bMemCompRC = false; |
| params.pitch = mediaSurface->pSurfDesc->uiPitches[0]; |
| DDI_CHK_CONDITION(params.pitch == 0, "Invalid pich.", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| // DRM buffer allocated by Application, No need to re-allocate new DRM buffer |
| switch (mediaSurface->pSurfDesc->uiVaMemType) |
| { |
| case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: |
| bo = mos_bo_gem_create_from_name(mediaDrvCtx->pDrmBufMgr, "MEDIA", mediaSurface->pSurfDesc->ulBuffer); |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: |
| bo = mos_bo_gem_create_from_prime(mediaDrvCtx->pDrmBufMgr, mediaSurface->pSurfDesc->ulBuffer, mediaSurface->pSurfDesc->uiSize); |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2: |
| bo = mos_bo_gem_create_from_prime(mediaDrvCtx->pDrmBufMgr, mediaSurface->pSurfDesc->ulBuffer, mediaSurface->pSurfDesc->uiSize); |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR: |
| #ifdef DRM_IOCTL_I915_GEM_USERPTR |
| bo = mos_bo_alloc_userptr(mediaDrvCtx->pDrmBufMgr, "SysSurface", (void *)mediaSurface->pSurfDesc->ulBuffer, mediaSurface->pSurfDesc->uiTile, |
| params.pitch, mediaSurface->pSurfDesc->uiBuffserSize, I915_USERPTR_UNSYNCHRONIZED); |
| #else |
| bo = mos_bo_alloc_vmap(mediaDrvCtx->pDrmBufMgr, "SysSurface", (void *)mediaSurface->pSurfDesc->ulBuffer, mediaSurface->pSurfDesc->uiTile, |
| params.pitch, mediaSurface->pSurfDesc->uiBuffserSize, 0); |
| #endif |
| break; |
| default: |
| DDI_ASSERTMESSAGE("Unsupported external surface memory type."); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| DDI_CHK_NULL(bo, "Failed to create drm buffer object according to input buffer descriptor." ,VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| switch(mediaSurface->pSurfDesc->uiVaMemType) |
| { |
| case VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM: |
| case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME: |
| //Overwrite the tile format that matches the exteral buffer |
| mos_bo_get_tiling(bo, ¶ms.tileFormat, &swizzle_mode); |
| if(params.tileFormat == 0) |
| { |
| params.tileFormat = mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING ? I915_TILING_Y : I915_TILING_NONE; |
| } |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2: |
| params.pitch = mediaSurface->pSurfDesc->uiPitches[0]; |
| status = SetSurfaceParameterFromModifier(params, mediaSurface->pSurfDesc->modifier); |
| if(status != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Set surface from modifier failed."); |
| return status; |
| } |
| break; |
| case VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR: |
| mos_bo_get_tiling(bo, ¶ms.tileFormat, &swizzle_mode); |
| break; |
| default: |
| DDI_ASSERTMESSAGE("Unsupported external surface memory type."); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| // Set cp flag to indicate the secure surface |
| if (mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_PROTECTED) |
| { |
| params.cpTag = PROTECTED_SURFACE_TAG; |
| } |
| |
| if (params.bMemCompEnable) |
| { |
| GMM_RESCREATE_PARAMS gmmParams = {}; |
| status = GenerateGmmParamsForCompressionExternalSurface(gmmParams, params, mediaDrvCtx); |
| if(status != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Generate gmmParams for compression external surface failed."); |
| return status; |
| } |
| gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateResInfoObject(&gmmParams); |
| } |
| else |
| { |
| GMM_RESCREATE_CUSTOM_PARAMS gmmCustomParams = {}; |
| status = GenerateGmmParamsForNoneCompressionExternalSurface(gmmCustomParams, params, mediaSurface); |
| if(status != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Generate gmmParams for none compression external surface failed."); |
| return status; |
| } |
| gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateCustomResInfoObject(&gmmCustomParams); |
| } |
| |
| DDI_CHK_NULL(gmmResourceInfo, "Gmm create resource failed", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| mediaSurface->pGmmResourceInfo = gmmResourceInfo; |
| mediaSurface->bMapped = false; |
| mediaSurface->format = params.format; |
| mediaSurface->iWidth = params.width; |
| mediaSurface->iHeight = gmmResourceInfo->GetBaseHeight(); |
| mediaSurface->iRealHeight = params.height; |
| mediaSurface->iPitch = params.pitch; |
| mediaSurface->iRefCount = 0; |
| mediaSurface->bo = bo; |
| mediaSurface->TileType = params.tileFormat; |
| mediaSurface->isTiled = (params.tileFormat != I915_TILING_NONE) ? 1 : 0; |
| mediaSurface->pData = (uint8_t*) bo->virt; |
| DDI_VERBOSEMESSAGE("Allocate external surface %7d bytes (%d x %d resource).", mediaSurface->pSurfDesc->uiSize, params.width, params.height); |
| uint32_t event[] = {bo->handle, params.format, params.width, params.height, params.pitch, bo->size, params.tileFormat, params.cpTag}; |
| MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG)); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus MediaLibvaUtilNext::GenerateGmmParamsForInternalSurface( |
| GMM_RESCREATE_PARAMS &gmmParams, |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms, |
| PDDI_MEDIA_CONTEXT mediaDrvCtx) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(mediaDrvCtx, "media context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| MosUtilities::MosZeroMemory(&gmmParams, sizeof(gmmParams)); |
| gmmParams.BaseWidth = params.alignedWidth; |
| gmmParams.BaseHeight = params.alignedHeight; |
| gmmParams.ArraySize = 1; |
| gmmParams.Type = RESOURCE_2D; |
| gmmParams.Format = ConvertMediaFmtToGmmFmt(params.format); |
| |
| DDI_CHK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID, "Unsupported format", VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT); |
| |
| switch (params.tileFormat) |
| { |
| case I915_TILING_Y: |
| // Disable MMC for application required surfaces, because some cases' output streams have corruption. |
| gmmParams.Flags.Gpu.MMC = false; |
| if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrE2ECompression) && |
| (!MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableVPMmc) && |
| !MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaDisableCodecMmc)) && |
| MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrCompressibleSurfaceDefault) && |
| params.bMemCompEnable) |
| { |
| gmmParams.Flags.Gpu.MMC = true; |
| gmmParams.Flags.Info.MediaCompressed = 1; |
| gmmParams.Flags.Info.RenderCompressed = 0; |
| gmmParams.Flags.Gpu.CCS = 1; |
| gmmParams.Flags.Gpu.RenderTarget = 1; |
| gmmParams.Flags.Gpu.UnifiedAuxSurface = 1; |
| |
| if (params.bMemCompRC) |
| { |
| gmmParams.Flags.Info.MediaCompressed = 0; |
| gmmParams.Flags.Info.RenderCompressed = 1; |
| } |
| |
| if (MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrRenderCompressionOnly)) |
| { |
| gmmParams.Flags.Info.MediaCompressed = 0; |
| |
| if (params.format == Media_Format_X8R8G8B8 || |
| params.format == Media_Format_X8B8G8R8 || |
| params.format == Media_Format_A8B8G8R8 || |
| params.format == Media_Format_A8R8G8B8 || |
| params.format == Media_Format_R8G8B8A8) |
| { |
| gmmParams.Flags.Info.MediaCompressed = 0; |
| gmmParams.Flags.Info.RenderCompressed = 1; |
| } |
| else |
| { |
| gmmParams.Flags.Gpu.MMC = false; |
| gmmParams.Flags.Info.MediaCompressed = 0; |
| gmmParams.Flags.Info.RenderCompressed = 0; |
| gmmParams.Flags.Gpu.CCS = 0; |
| gmmParams.Flags.Gpu.UnifiedAuxSurface = 0; |
| } |
| } |
| } |
| break; |
| case I915_TILING_X: |
| gmmParams.Flags.Info.TiledX = true; |
| break; |
| default: |
| gmmParams.Flags.Info.Linear = true; |
| } |
| gmmParams.Flags.Gpu.Video = true; |
| gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaDrvCtx->SkuTable, FtrLocalMemory); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus MediaLibvaUtilNext::CreateInternalSurface( |
| MEDIA_SURFACE_ALLOCATE_PARAM ¶ms, |
| PDDI_MEDIA_SURFACE mediaSurface, |
| PDDI_MEDIA_CONTEXT mediaDrvCtx) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(mediaSurface, "mediaSurface is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaDrvCtx, "media context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaDrvCtx->pGmmClientContext, "gmm context is nullptr", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| VAStatus status = VA_STATUS_SUCCESS; |
| MOS_LINUX_BO *bo = nullptr; |
| GMM_RESCREATE_PARAMS gmmParams = {}; |
| GMM_RESOURCE_INFO *gmmResourceInfo = nullptr; |
| if (mediaSurface->pSurfDesc) |
| { |
| if (mediaSurface->pSurfDesc->uiFlags & VA_SURFACE_EXTBUF_DESC_ENABLE_TILING ) |
| { |
| params.tileFormat = I915_TILING_Y; |
| } |
| else if (mediaSurface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_VA) |
| { |
| params.tileFormat = I915_TILING_NONE; |
| params.alignedHeight = params.height; |
| } |
| } |
| |
| status = GenerateGmmParamsForInternalSurface(gmmParams, params, mediaDrvCtx); |
| if(status != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Generate gmmParams for internal surface failed."); |
| return status; |
| } |
| |
| mediaSurface->pGmmResourceInfo = gmmResourceInfo = mediaDrvCtx->pGmmClientContext->CreateResInfoObject(&gmmParams); |
| DDI_CHK_NULL(gmmResourceInfo, "Gmm create resource failed", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| uint32_t gmmPitch = (uint32_t)gmmResourceInfo->GetRenderPitch(); |
| uint32_t gmmSize = (uint32_t)gmmResourceInfo->GetSizeSurface(); |
| uint32_t gmmHeight = gmmResourceInfo->GetBaseHeight(); |
| |
| if (0 == gmmPitch || 0 == gmmSize || 0 == gmmHeight) |
| { |
| DDI_ASSERTMESSAGE("Gmm Create Resource Failed."); |
| return VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| switch (gmmResourceInfo->GetTileType()) |
| { |
| case GMM_TILED_Y: |
| params.tileFormat = I915_TILING_Y; |
| break; |
| case GMM_TILED_X: |
| params.tileFormat = I915_TILING_X; |
| break; |
| case GMM_NOT_TILED: |
| params.tileFormat = I915_TILING_NONE; |
| break; |
| default: |
| params.tileFormat = I915_TILING_Y; |
| break; |
| } |
| |
| MemoryPolicyParameter memPolicyPar; |
| MosUtilities::MosZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter)); |
| |
| memPolicyPar.skuTable = &mediaDrvCtx->SkuTable; |
| memPolicyPar.waTable = &mediaDrvCtx->WaTable; |
| memPolicyPar.resInfo = mediaSurface->pGmmResourceInfo; |
| memPolicyPar.resName = "Media Surface"; |
| memPolicyPar.preferredMemType = (MEDIA_IS_WA(&mediaDrvCtx->WaTable, WaForceAllocateLML4)) ? MOS_MEMPOOL_DEVICEMEMORY : params.memType; |
| |
| params.memType = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar); |
| |
| if ( params.tileFormat == I915_TILING_NONE ) |
| { |
| bo = mos_bo_alloc(mediaDrvCtx->pDrmBufMgr, "MEDIA", gmmSize, 4096, params.memType); |
| params.pitch = gmmPitch; |
| } |
| else |
| { |
| unsigned long ulPitch = 0; |
| bo = mos_bo_alloc_tiled(mediaDrvCtx->pDrmBufMgr, "MEDIA", gmmPitch, (gmmSize + gmmPitch -1)/gmmPitch, 1, ¶ms.tileFormat, |
| (unsigned long *)&ulPitch, 0, params.memType); |
| params.pitch = ulPitch; |
| } |
| |
| mediaSurface->bMapped = false; |
| DDI_CHK_NULL(bo, "Failed to create drm buffer object according to input buffer descriptor." ,VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| mediaSurface->format = params.format; |
| mediaSurface->iWidth = params.width; |
| mediaSurface->iHeight = gmmHeight; |
| mediaSurface->iRealHeight = params.height; |
| mediaSurface->iPitch = params.pitch; |
| mediaSurface->iRefCount = 0; |
| mediaSurface->bo = bo; |
| mediaSurface->TileType = params.tileFormat; |
| mediaSurface->isTiled = (params.tileFormat != I915_TILING_NONE) ? 1 : 0; |
| mediaSurface->pData = (uint8_t*) bo->virt; |
| DDI_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource, gmmTiledType %d)).",gmmSize, params.width, params.height, gmmResourceInfo->GetTileType()); |
| uint32_t event[] = {bo->handle, params.format, params.width, params.height, params.pitch, bo->size, params.tileFormat, params.cpTag}; |
| MOS_TraceEventExt(EVENT_VA_SURFACE, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG)); |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus MediaLibvaUtilNext::AllocateSurface( |
| DDI_MEDIA_FORMAT format, |
| int32_t width, |
| int32_t height, |
| PDDI_MEDIA_SURFACE mediaSurface, |
| PDDI_MEDIA_CONTEXT mediaDrvCtx) |
| { |
| VAStatus status = VA_STATUS_SUCCESS; |
| MEDIA_SURFACE_ALLOCATE_PARAM params = {}; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(mediaSurface, "mediaSurface is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaDrvCtx, "mediaDrvCtx is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaDrvCtx->pGmmClientContext, "mediaDrvCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| InitSurfaceAllocateParams(params, width, height, format, |
| mediaSurface->memType, mediaSurface->surfaceUsageHint); |
| |
| status = SetDefaultTileFormat(format, mediaSurface->surfaceUsageHint, &mediaDrvCtx->SkuTable, params); |
| if (status != VA_STATUS_SUCCESS) |
| { |
| DDI_ASSERTMESSAGE("Get tile format failed."); |
| return status; |
| } |
| |
| if (IsExternalSurface(mediaSurface)) |
| { |
| return CreateExternalSurface(params, mediaSurface, mediaDrvCtx); |
| } |
| else |
| { |
| return CreateInternalSurface(params, mediaSurface, mediaDrvCtx); |
| } |
| } |
| |
| bool MediaLibvaUtilNext::IsExternalSurface(PDDI_MEDIA_SURFACE surface) |
| { |
| DDI_FUNC_ENTER; |
| if (nullptr == surface) |
| { |
| return false; |
| } |
| else if (surface->pSurfDesc == nullptr) |
| { |
| return false; |
| } |
| else |
| { |
| if (surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_KERNEL_DRM || |
| surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME || |
| surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 || |
| surface->pSurfDesc->uiVaMemType == VA_SURFACE_ATTRIB_MEM_TYPE_USER_PTR) |
| { |
| return true; |
| } |
| else |
| { |
| return false; |
| } |
| } |
| } |
| |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT MediaLibvaUtilNext::AllocPMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap) |
| { |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt = nullptr; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surfaceHeap, "nullptr surfaceHeap", nullptr); |
| |
| if (nullptr == surfaceHeap->pFirstFreeHeapElement) |
| { |
| void *newHeapBase = MOS_ReallocMemory(surfaceHeap->pHeapBase, (surfaceHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_SURFACE_HEAP_ELEMENT)); |
| |
| if (nullptr == newHeapBase) |
| { |
| DDI_ASSERTMESSAGE("DDI: realloc failed."); |
| return nullptr; |
| } |
| surfaceHeap->pHeapBase = newHeapBase; |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT surfaceHeapBase = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase; |
| surfaceHeap->pFirstFreeHeapElement = (void*)(&surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements]); |
| for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++) |
| { |
| mediaSurfaceHeapElmt = &surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements + i]; |
| mediaSurfaceHeapElmt->pNextFree = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &surfaceHeapBase[surfaceHeap->uiAllocatedHeapElements + i + 1]; |
| mediaSurfaceHeapElmt->uiVaSurfaceID = surfaceHeap->uiAllocatedHeapElements + i; |
| } |
| surfaceHeap->uiAllocatedHeapElements += DDI_MEDIA_HEAP_INCREMENTAL_SIZE; |
| } |
| |
| mediaSurfaceHeapElmt = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pFirstFreeHeapElement; |
| surfaceHeap->pFirstFreeHeapElement = mediaSurfaceHeapElmt->pNextFree; |
| |
| return mediaSurfaceHeapElmt; |
| } |
| |
| void MediaLibvaUtilNext::ReleasePMediaSurfaceFromHeap(PDDI_MEDIA_HEAP surfaceHeap, uint32_t vaSurfaceID) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surfaceHeap, "nullptr surfaceHeap", ); |
| |
| DDI_CHK_LESS(vaSurfaceID, surfaceHeap->uiAllocatedHeapElements, "invalid surface id", ); |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapBase = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)surfaceHeap->pHeapBase; |
| DDI_CHK_NULL(mediaSurfaceHeapBase, "nullptr mediaSurfaceHeapBase", ); |
| |
| PDDI_MEDIA_SURFACE_HEAP_ELEMENT mediaSurfaceHeapElmt = &mediaSurfaceHeapBase[vaSurfaceID]; |
| DDI_CHK_NULL(mediaSurfaceHeapElmt->pSurface, "surface is already released", ); |
| void *firstFree = surfaceHeap->pFirstFreeHeapElement; |
| surfaceHeap->pFirstFreeHeapElement = (void*)mediaSurfaceHeapElmt; |
| mediaSurfaceHeapElmt->pNextFree = (PDDI_MEDIA_SURFACE_HEAP_ELEMENT)firstFree; |
| mediaSurfaceHeapElmt->pSurface = nullptr; |
| } |
| |
| VAStatus MediaLibvaUtilNext::CreateSurface(DDI_MEDIA_SURFACE *surface, PDDI_MEDIA_CONTEXT mediaDrvCtx) |
| { |
| VAStatus hr = VA_STATUS_SUCCESS; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| // better to differentiate 1D and 2D type |
| hr = AllocateSurface(surface->format, |
| surface->iWidth, |
| surface->iHeight, |
| surface, |
| mediaDrvCtx); |
| if (VA_STATUS_SUCCESS == hr && nullptr != surface->bo) |
| { |
| surface->base = surface->name; |
| } |
| |
| return hr; |
| } |
| |
| GMM_RESOURCE_FORMAT MediaLibvaUtilNext::ConvertMediaFmtToGmmFmt(DDI_MEDIA_FORMAT format) |
| { |
| DDI_FUNC_ENTER; |
| switch (format) |
| { |
| case Media_Format_X8R8G8B8 : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE; |
| case Media_Format_A8R8G8B8 : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE; |
| case Media_Format_X8B8G8R8 : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE; |
| case Media_Format_A8B8G8R8 : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE; |
| case Media_Format_R8G8B8A8 : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE; |
| case Media_Format_R5G6B5 : return GMM_FORMAT_B5G6R5_UNORM_TYPE; |
| case Media_Format_R8G8B8 : return GMM_FORMAT_R8G8B8_UNORM; |
| case Media_Format_RGBP : return GMM_FORMAT_RGBP; |
| case Media_Format_BGRP : return GMM_FORMAT_BGRP; |
| case Media_Format_NV12 : return GMM_FORMAT_NV12_TYPE; |
| case Media_Format_NV21 : return GMM_FORMAT_NV21_TYPE; |
| case Media_Format_YUY2 : return GMM_FORMAT_YUY2; |
| case Media_Format_YVYU : return GMM_FORMAT_YVYU; |
| case Media_Format_UYVY : return GMM_FORMAT_UYVY; |
| case Media_Format_VYUY : return GMM_FORMAT_VYUY; |
| case Media_Format_YV12 : return GMM_FORMAT_YV12_TYPE; |
| case Media_Format_IYUV : return GMM_FORMAT_IYUV_TYPE; |
| case Media_Format_I420 : return GMM_FORMAT_I420_TYPE; |
| case Media_Format_444P : return GMM_FORMAT_MFX_JPEG_YUV444_TYPE; |
| case Media_Format_422H : return GMM_FORMAT_MFX_JPEG_YUV422H_TYPE; |
| case Media_Format_411P : return GMM_FORMAT_MFX_JPEG_YUV411_TYPE; |
| case Media_Format_422V : return GMM_FORMAT_MFX_JPEG_YUV422V_TYPE; |
| case Media_Format_IMC3 : return GMM_FORMAT_IMC3_TYPE; |
| case Media_Format_400P : return GMM_FORMAT_GENERIC_8BIT; |
| case Media_Format_Buffer : return GMM_FORMAT_RENDER_8BIT; |
| case Media_Format_P010 : return GMM_FORMAT_P010_TYPE; |
| case Media_Format_R10G10B10A2: return GMM_FORMAT_R10G10B10A2_UNORM_TYPE; |
| case Media_Format_B10G10R10A2: return GMM_FORMAT_B10G10R10A2_UNORM_TYPE; |
| case Media_Format_R10G10B10X2: return GMM_FORMAT_R10G10B10A2_UNORM_TYPE; |
| case Media_Format_B10G10R10X2: return GMM_FORMAT_B10G10R10A2_UNORM_TYPE; |
| case Media_Format_P012 : return GMM_FORMAT_P016_TYPE; |
| case Media_Format_P016 : return GMM_FORMAT_P016_TYPE; |
| case Media_Format_Y210 : return GMM_FORMAT_Y210_TYPE; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y212 : return GMM_FORMAT_Y212_TYPE; |
| #endif |
| case Media_Format_Y216 : return GMM_FORMAT_Y216_TYPE; |
| case Media_Format_AYUV : return GMM_FORMAT_AYUV_TYPE; |
| #if VA_CHECK_VERSION(1, 13, 0) |
| case Media_Format_XYUV : return GMM_FORMAT_AYUV_TYPE; |
| #endif |
| case Media_Format_Y410 : return GMM_FORMAT_Y410_TYPE; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case Media_Format_Y412 : return GMM_FORMAT_Y412_TYPE; |
| #endif |
| case Media_Format_Y416 : return GMM_FORMAT_Y416_TYPE; |
| case Media_Format_Y8 : return GMM_FORMAT_MEDIA_Y8_UNORM; |
| case Media_Format_Y16S : return GMM_FORMAT_MEDIA_Y16_SNORM; |
| case Media_Format_Y16U : return GMM_FORMAT_MEDIA_Y16_UNORM; |
| case Media_Format_A16R16G16B16: return GMM_FORMAT_B16G16R16A16_UNORM; |
| case Media_Format_A16B16G16R16: return GMM_FORMAT_R16G16B16A16_UNORM; |
| default : return GMM_FORMAT_INVALID; |
| } |
| } |
| |
| void MediaLibvaUtilNext::WaitSemaphore(PMEDIA_SEM_T sem) |
| { |
| DDI_FUNC_ENTER; |
| int32_t ret = sem_wait(sem); |
| if (ret != 0) |
| { |
| DDI_NORMALMESSAGE("wait semaphore error!\n"); |
| } |
| } |
| |
| int32_t MediaLibvaUtilNext::TryWaitSemaphore(PMEDIA_SEM_T sem) |
| { |
| return sem_trywait(sem); |
| } |
| |
| void MediaLibvaUtilNext::PostSemaphore(PMEDIA_SEM_T sem) |
| { |
| int32_t ret = sem_post(sem); |
| if (ret != 0) |
| { |
| DDI_NORMALMESSAGE("post semaphore error!\n"); |
| } |
| } |
| |
| void MediaLibvaUtilNext::DestroySemaphore(PMEDIA_SEM_T sem) |
| { |
| int32_t ret = sem_destroy(sem); |
| if(ret != 0) |
| { |
| DDI_NORMALMESSAGE("can't destroy the semaphore!\n"); |
| } |
| } |
| |
| VAStatus MediaLibvaUtilNext::UnRegisterRTSurfaces( |
| VADriverContextP ctx, |
| PDDI_MEDIA_SURFACE surface) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(ctx, "nullptr context!", VA_STATUS_ERROR_INVALID_CONTEXT); |
| PDDI_MEDIA_CONTEXT mediaCtx = GetMediaContext(ctx); |
| DDI_CHK_NULL(mediaCtx, "nullptr mediaCtx!", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(surface, "nullptr surface!", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| //Look through all decode contexts to unregister the surface in each decode context's RTtable. |
| if (mediaCtx->pDecoderCtxHeap != nullptr) |
| { |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT decVACtxHeapBase = nullptr; |
| |
| MosUtilities::MosLockMutex(&mediaCtx->DecoderMutex); |
| decVACtxHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaCtx->pDecoderCtxHeap->pHeapBase; |
| for (uint32_t j = 0; j < mediaCtx->pDecoderCtxHeap->uiAllocatedHeapElements; j++) |
| { |
| if (decVACtxHeapBase[j].pVaContext != nullptr) |
| { |
| decode::PDDI_DECODE_CONTEXT decCtx = (decode::PDDI_DECODE_CONTEXT)decVACtxHeapBase[j].pVaContext; |
| if (decCtx && decCtx->m_ddiDecodeNext) |
| { |
| //not check the return value since the surface may not be registered in the context. pay attention to LOGW. |
| decCtx->m_ddiDecodeNext->UnRegisterRTSurfaces(&decCtx->RTtbl, surface); |
| } |
| } |
| } |
| MosUtilities::MosUnlockMutex(&mediaCtx->DecoderMutex); |
| } |
| if (mediaCtx->pEncoderCtxHeap != nullptr) |
| { |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT pEncVACtxHeapBase = nullptr; |
| |
| MosUtilities::MosLockMutex(&mediaCtx->EncoderMutex); |
| pEncVACtxHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)mediaCtx->pEncoderCtxHeap->pHeapBase; |
| for (uint32_t j = 0; j < mediaCtx->pEncoderCtxHeap->uiAllocatedHeapElements; j++) |
| { |
| if (pEncVACtxHeapBase[j].pVaContext != nullptr) |
| { |
| PDDI_ENCODE_CONTEXT pEncCtx = (PDDI_ENCODE_CONTEXT)pEncVACtxHeapBase[j].pVaContext; |
| if (pEncCtx && pEncCtx->m_encode) |
| { |
| //not check the return value since the surface may not be registered in the context. pay attention to LOGW. |
| pEncCtx->m_encode->UnRegisterRTSurfaces(&pEncCtx->RTtbl, surface); |
| } |
| } |
| } |
| MosUtilities::MosUnlockMutex(&mediaCtx->EncoderMutex); |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| void MediaLibvaUtilNext::FreeSurface(DDI_MEDIA_SURFACE *surface) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surface, "nullptr surface", ); |
| DDI_CHK_NULL(surface->bo, "nullptr surface->bo", ); |
| DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", ); |
| DDI_CHK_NULL(surface->pMediaCtx->pGmmClientContext, "nullptr surface->pMediaCtx->pGmmClientContext", ); |
| |
| // Unmap Aux mapping if the surface was mapped |
| if (surface->pMediaCtx->m_auxTableMgr) |
| { |
| surface->pMediaCtx->m_auxTableMgr->UnmapResource(surface->pGmmResourceInfo, surface->bo); |
| } |
| |
| if(surface->bMapped) |
| { |
| UnlockSurface(surface); |
| DDI_VERBOSEMESSAGE("DDI: try to free a locked surface."); |
| } |
| mos_bo_unreference(surface->bo); |
| // For External Buffer, only needs to destory SurfaceDescriptor |
| if (surface->pSurfDesc) |
| { |
| MOS_FreeMemory(surface->pSurfDesc); |
| surface->pSurfDesc = nullptr; |
| } |
| |
| if (nullptr != surface->pGmmResourceInfo) |
| { |
| surface->pMediaCtx->pGmmClientContext->DestroyResInfoObject(surface->pGmmResourceInfo); |
| surface->pGmmResourceInfo = nullptr; |
| } |
| } |
| |
| void MediaLibvaUtilNext::FreeBuffer(DDI_MEDIA_BUFFER *buf) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(buf, "nullptr", ); |
| // calling sequence checking |
| if (buf->bMapped) |
| { |
| UnlockBuffer(buf); |
| DDI_VERBOSEMESSAGE("DDI: try to free a locked buffer."); |
| } |
| if (buf->format == Media_Format_CPU) |
| { |
| MOS_FreeMemory(buf->pData); |
| buf->pData = nullptr; |
| } |
| else |
| { |
| mos_bo_unreference(buf->bo); |
| buf->bo = nullptr; |
| } |
| |
| if (nullptr != buf->pMediaCtx && nullptr != buf->pMediaCtx->pGmmClientContext && nullptr != buf->pGmmResourceInfo) |
| { |
| buf->pMediaCtx->pGmmClientContext->DestroyResInfoObject(buf->pGmmResourceInfo); |
| buf->pGmmResourceInfo = nullptr; |
| } |
| } |
| |
| void* MediaLibvaUtilNext::LockSurface(DDI_MEDIA_SURFACE *surface, uint32_t flag) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surface, "nullptr surface", nullptr); |
| DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", nullptr); |
| |
| if (MEDIA_IS_SKU(&surface->pMediaCtx->SkuTable, FtrLocalMemory)) |
| { |
| if ((MosUtilities::MosAtomicIncrement(&surface->iRefCount) == 1) && (false == surface->bMapped)) |
| { |
| return LockSurfaceInternal(surface, flag); |
| } |
| else |
| { |
| DDI_VERBOSEMESSAGE("line %d, invalide operation for lockSurface. the surface reference count = %d", __LINE__, surface->iRefCount); |
| } |
| } |
| else |
| { |
| if ((surface->iRefCount == 0) && (false == surface->bMapped)) |
| { |
| LockSurfaceInternal(surface, flag); |
| } |
| else |
| { |
| // do nothing here |
| } |
| surface->iRefCount++; |
| } |
| |
| return surface->pData; |
| } |
| |
| void* MediaLibvaUtilNext::LockSurfaceInternal(DDI_MEDIA_SURFACE *surface, uint32_t flag) |
| { |
| int err = 0; |
| uint64_t surfSize = 0; |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| DDI_FUNC_ENTER; |
| |
| DDI_CHK_NULL(surface, "nullptr surface", nullptr); |
| DDI_CHK_NULL(surface->bo, "nullptr surface->bo", nullptr); |
| DDI_CHK_NULL(surface->pMediaCtx, "nullptr surface->pMediaCtx", nullptr); |
| |
| if (surface->pMediaCtx->bIsAtomSOC) |
| { |
| mos_gem_bo_map_gtt(surface->bo); |
| } |
| else |
| { |
| if (surface->TileType == I915_TILING_NONE) |
| { |
| mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_WRITEONLY); |
| } |
| else if ((surface->pMediaCtx->m_useSwSwizzling) && !(flag & MOS_LOCKFLAG_NO_SWIZZLE)) |
| { |
| DDI_CHK_NULL(surface->pGmmResourceInfo, "nullptr surface->pGmmResourceInfo", nullptr); |
| |
| surfSize = surface->pGmmResourceInfo->GetSizeMainSurface(); |
| DDI_CHK_CONDITION((surface->TileType != I915_TILING_Y), "Unsupported tile type", nullptr); |
| DDI_CHK_CONDITION((surfSize <= 0 || surface->iPitch <= 0), "Invalid surface size or pitch", nullptr); |
| |
| if (MEDIA_IS_SKU(&surface->pMediaCtx->SkuTable, FtrLocalMemory)) |
| { |
| if (surface->pShadowBuffer == nullptr) |
| { |
| CreateShadowResource(surface); |
| } |
| |
| if (surface->pShadowBuffer != nullptr) |
| { |
| vaStatus = SwizzleSurfaceByHW(surface); |
| if (vaStatus == VA_STATUS_SUCCESS) |
| { |
| err = mos_bo_map(surface->pShadowBuffer->bo, flag & MOS_LOCKFLAG_WRITEONLY); |
| } |
| |
| if (vaStatus != VA_STATUS_SUCCESS || err != 0) |
| { |
| FreeBuffer(surface->pShadowBuffer); |
| MOS_Delete(surface->pShadowBuffer); |
| surface->pShadowBuffer = nullptr; |
| } |
| } |
| } |
| |
| mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_WRITEONLY); |
| |
| if (surface->pShadowBuffer == nullptr) |
| { |
| if (surface->pSystemShadow == nullptr) |
| { |
| surface->pSystemShadow = MOS_NewArray(uint8_t, surface->bo->size);; |
| DDI_CHK_CONDITION((surface->pSystemShadow == nullptr), "Failed to allocate shadow surface", nullptr); |
| } |
| |
| vaStatus = SwizzleSurface(surface->pMediaCtx, |
| surface->pGmmResourceInfo, |
| surface->bo->virt, |
| (MOS_TILE_TYPE)surface->TileType, |
| (uint8_t *)surface->pSystemShadow, |
| false); |
| DDI_CHK_CONDITION((vaStatus != VA_STATUS_SUCCESS), "SwizzleSurface failed", nullptr); |
| } |
| |
| } |
| else if (flag & MOS_LOCKFLAG_NO_SWIZZLE) |
| { |
| mos_bo_map(surface->bo, flag & MOS_LOCKFLAG_READONLY); |
| } |
| else if (flag & MOS_LOCKFLAG_WRITEONLY) |
| { |
| mos_gem_bo_map_gtt(surface->bo); |
| } |
| else |
| { |
| mos_gem_bo_map_unsynchronized(surface->bo); // only call mmap_gtt ioctl |
| mos_gem_bo_start_gtt_access(surface->bo, 0); // set to GTT domain,0 means readonly |
| } |
| } |
| surface->uiMapFlag = flag; |
| if (surface->pShadowBuffer) |
| { |
| surface->pData = (uint8_t *)surface->pShadowBuffer->bo->virt; |
| } |
| else if (surface->pSystemShadow) |
| { |
| surface->pData = surface->pSystemShadow; |
| } |
| else |
| { |
| surface->pData = (uint8_t*) surface->bo->virt; |
| } |
| surface->data_size = surface->bo->size; |
| surface->bMapped = true; |
| |
| return surface->pData; |
| } |
| |
| void MediaLibvaUtilNext::UnlockSurface(DDI_MEDIA_SURFACE *surface) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surface, "nullptr surface", ); |
| DDI_CHK_NULL(surface->bo, "nullptr surface->bo", ); |
| if (0 == surface->iRefCount) |
| { |
| return; |
| } |
| |
| if((true == surface->bMapped) && (1 == surface->iRefCount)) |
| { |
| if (surface->pMediaCtx->bIsAtomSOC) |
| { |
| mos_gem_bo_unmap_gtt(surface->bo); |
| } |
| else |
| { |
| if (surface->TileType == I915_TILING_NONE) |
| { |
| mos_bo_unmap(surface->bo); |
| } |
| else if (surface->pShadowBuffer != nullptr) |
| { |
| SwizzleSurfaceByHW(surface, true); |
| |
| mos_bo_unmap(surface->pShadowBuffer->bo); |
| FreeBuffer(surface->pShadowBuffer); |
| MOS_FreeMemory(surface->pShadowBuffer); |
| surface->pShadowBuffer = nullptr; |
| |
| mos_bo_unmap(surface->bo); |
| } |
| else if (surface->pSystemShadow) |
| { |
| SwizzleSurface(surface->pMediaCtx, |
| surface->pGmmResourceInfo, |
| surface->bo->virt, |
| (MOS_TILE_TYPE)surface->TileType, |
| (uint8_t *)surface->pSystemShadow, |
| true); |
| |
| MOS_DeleteArray(surface->pSystemShadow); |
| surface->pSystemShadow = nullptr; |
| |
| mos_bo_unmap(surface->bo); |
| } |
| else if(surface->uiMapFlag & MOS_LOCKFLAG_NO_SWIZZLE) |
| { |
| mos_bo_unmap(surface->bo); |
| } |
| else |
| { |
| mos_gem_bo_unmap_gtt(surface->bo); |
| } |
| } |
| surface->pData = nullptr; |
| surface->bo->virt = nullptr; |
| surface->bMapped = false; |
| } |
| else |
| { |
| // do nothing here |
| } |
| |
| surface->iRefCount--; |
| |
| return; |
| } |
| |
| VAStatus MediaLibvaUtilNext::CreateShadowResource(DDI_MEDIA_SURFACE *surface) |
| { |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(surface->pGmmResourceInfo, "nullptr surface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_SURFACE); |
| if (surface->pGmmResourceInfo->GetSetCpSurfTag(0, 0) != 0) |
| { |
| return VA_STATUS_ERROR_INVALID_SURFACE; |
| } |
| |
| if (surface->iWidth < 64 || surface->iRealHeight < 64 || (surface->iPitch % 64 != 0) || surface->format == Media_Format_P016) |
| { |
| return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; |
| } |
| |
| surface->pShadowBuffer = MOS_New(DDI_MEDIA_BUFFER); |
| DDI_CHK_NULL(surface->pShadowBuffer, "Failed to allocate shadow buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| surface->pShadowBuffer->pMediaCtx = surface->pMediaCtx; |
| surface->pShadowBuffer->bUseSysGfxMem = true; |
| surface->pShadowBuffer->iSize = surface->pGmmResourceInfo->GetSizeSurface(); |
| |
| vaStatus = AllocateBuffer(Media_Format_Buffer, surface->pShadowBuffer->iSize, surface->pShadowBuffer, surface->pMediaCtx->pDrmBufMgr); |
| |
| if (vaStatus != VA_STATUS_SUCCESS) |
| { |
| MOS_Delete(surface->pShadowBuffer); |
| surface->pShadowBuffer = nullptr; |
| } |
| |
| return vaStatus; |
| } |
| |
| void* MediaLibvaUtilNext::LockBuffer(DDI_MEDIA_BUFFER *buf, uint32_t flag) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(buf, "nullptr buf", nullptr); |
| if((Media_Format_CPU != buf->format) && (false == buf->bMapped)) |
| { |
| if (nullptr != buf->pSurface) |
| { |
| LockSurface(buf->pSurface, flag); |
| buf->pData = buf->pSurface->pData; |
| } |
| else |
| { |
| if (buf->pMediaCtx->bIsAtomSOC) |
| { |
| mos_gem_bo_map_gtt(buf->bo); |
| } |
| else |
| { |
| if (buf->TileType == I915_TILING_NONE) |
| { |
| mos_bo_map(buf->bo, ((MOS_LOCKFLAG_READONLY | MOS_LOCKFLAG_WRITEONLY) & flag)); |
| } |
| else |
| { |
| mos_gem_bo_map_gtt(buf->bo); |
| } |
| } |
| |
| buf->pData = (uint8_t*)(buf->bo->virt); |
| } |
| |
| buf->bMapped = true; |
| buf->iRefCount++; |
| } |
| else if ((Media_Format_CPU == buf->format) && (false == buf->bMapped)) |
| { |
| buf->bMapped = true; |
| buf->iRefCount++; |
| } |
| else |
| { |
| buf->iRefCount++; |
| } |
| |
| return buf->pData; |
| } |
| |
| void MediaLibvaUtilNext::UnlockBuffer(DDI_MEDIA_BUFFER *buf) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(buf, "nullptr buf", ); |
| if (0 == buf->iRefCount) |
| { |
| return; |
| } |
| if((true == buf->bMapped) && (Media_Format_CPU != buf->format) && (1 == buf->iRefCount)) |
| { |
| if (nullptr != buf->pSurface) |
| { |
| UnlockSurface(buf->pSurface); |
| } |
| else |
| { |
| if (buf->pMediaCtx->bIsAtomSOC) |
| { |
| mos_gem_bo_unmap_gtt(buf->bo); |
| } |
| else |
| { |
| if (buf->TileType == I915_TILING_NONE) |
| { |
| mos_bo_unmap(buf->bo); |
| } |
| else |
| { |
| mos_gem_bo_unmap_gtt(buf->bo); |
| } |
| } |
| buf->bo->virt = nullptr; |
| } |
| |
| buf->pData = nullptr; |
| |
| buf->bMapped = false; |
| } |
| else if ((true == buf->bMapped) && (Media_Format_CPU == buf->format) && (1 == buf->iRefCount)) |
| { |
| buf->bMapped = false; |
| } |
| else |
| { |
| // do nothing here |
| } |
| buf->iRefCount--; |
| return; |
| } |
| |
| VAStatus MediaLibvaUtilNext::SwizzleSurface( |
| PDDI_MEDIA_CONTEXT mediaCtx, |
| PGMM_RESOURCE_INFO pGmmResInfo, |
| void *pLockedAddr, |
| uint32_t TileType, |
| uint8_t *pResourceBase, |
| bool bUpload) |
| { |
| uint32_t uiSize = 0, uiPitch = 0; |
| GMM_RES_COPY_BLT gmmResCopyBlt = {0}; |
| uint32_t uiPicHeight = 0; |
| uint32_t ulSwizzledSize = 0; |
| VAStatus vaStatus = VA_STATUS_SUCCESS; |
| DDI_FUNC_ENTER; |
| |
| DDI_CHK_NULL(pGmmResInfo, "pGmmResInfo is NULL", VA_STATUS_ERROR_OPERATION_FAILED); |
| DDI_CHK_NULL(pLockedAddr, "pLockedAddr is NULL", VA_STATUS_ERROR_OPERATION_FAILED); |
| DDI_CHK_NULL(pResourceBase, "pResourceBase is NULL", VA_STATUS_ERROR_ALLOCATION_FAILED); |
| |
| uiPicHeight = pGmmResInfo->GetBaseHeight(); |
| uiSize = pGmmResInfo->GetSizeSurface(); |
| uiPitch = pGmmResInfo->GetRenderPitch(); |
| gmmResCopyBlt.Gpu.pData = pLockedAddr; |
| gmmResCopyBlt.Sys.pData = pResourceBase; |
| gmmResCopyBlt.Sys.RowPitch = uiPitch; |
| gmmResCopyBlt.Sys.BufferSize = uiSize; |
| gmmResCopyBlt.Sys.SlicePitch = uiSize; |
| gmmResCopyBlt.Blt.Slices = 1; |
| gmmResCopyBlt.Blt.Upload = bUpload; |
| |
| if(mediaCtx->pGmmClientContext->IsPlanar(pGmmResInfo->GetResourceFormat()) == true) |
| { |
| gmmResCopyBlt.Blt.Width = pGmmResInfo->GetBaseWidth(); |
| gmmResCopyBlt.Blt.Height = uiSize/uiPitch; |
| } |
| |
| pGmmResInfo->CpuBlt(&gmmResCopyBlt); |
| |
| return vaStatus; |
| } |
| |
| void MediaLibvaUtilNext::ReleasePMediaBufferFromHeap( |
| PDDI_MEDIA_HEAP bufferHeap, |
| uint32_t vaBufferID) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(bufferHeap, "nullptr bufferHeap", ); |
| |
| DDI_CHK_LESS(vaBufferID, bufferHeap->uiAllocatedHeapElements, "invalid buffer id", ); |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase; |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt = &mediaBufferHeapBase[vaBufferID]; |
| DDI_CHK_NULL(mediaBufferHeapElmt->pBuffer, "buffer is already released", ); |
| void *firstFree = bufferHeap->pFirstFreeHeapElement; |
| bufferHeap->pFirstFreeHeapElement = (void*)mediaBufferHeapElmt; |
| mediaBufferHeapElmt->pNextFree = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)firstFree; |
| mediaBufferHeapElmt->pBuffer = nullptr; |
| return; |
| } |
| |
| VAStatus MediaLibvaUtilNext::SwizzleSurfaceByHW(DDI_MEDIA_SURFACE *surface, bool isDeSwizzle) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(surface, "nullptr surface", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(surface->pMediaCtx, "nullptr media context", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| MOS_CONTEXT mosCtx = {}; |
| PERF_DATA perfData = {}; |
| PDDI_MEDIA_CONTEXT mediaDrvCtx = surface->pMediaCtx; |
| |
| // Get the buf manager for codechal create |
| mosCtx.bufmgr = mediaDrvCtx->pDrmBufMgr; |
| mosCtx.fd = mediaDrvCtx->fd; |
| mosCtx.iDeviceId = mediaDrvCtx->iDeviceId; |
| mosCtx.m_skuTable = mediaDrvCtx->SkuTable; |
| mosCtx.m_waTable = mediaDrvCtx->WaTable; |
| mosCtx.m_gtSystemInfo = *mediaDrvCtx->pGtSystemInfo; |
| mosCtx.m_platform = mediaDrvCtx->platform; |
| |
| mosCtx.ppMediaMemDecompState = &mediaDrvCtx->pMediaMemDecompState; |
| mosCtx.pfnMemoryDecompress = mediaDrvCtx->pfnMemoryDecompress; |
| mosCtx.pfnMediaMemoryCopy = mediaDrvCtx->pfnMediaMemoryCopy; |
| mosCtx.pfnMediaMemoryCopy2D = mediaDrvCtx->pfnMediaMemoryCopy2D; |
| mosCtx.pPerfData = &perfData; |
| mosCtx.m_gtSystemInfo = *mediaDrvCtx->pGtSystemInfo; |
| mosCtx.m_auxTableMgr = mediaDrvCtx->m_auxTableMgr; |
| mosCtx.pGmmClientContext = mediaDrvCtx->pGmmClientContext; |
| |
| mosCtx.m_osDeviceContext = mediaDrvCtx->m_osDeviceContext; |
| mosCtx.m_userSettingPtr = mediaDrvCtx->m_userSettingPtr; |
| |
| MOS_RESOURCE source = {}; |
| MOS_RESOURCE target = {}; |
| |
| if (isDeSwizzle) |
| { |
| |
| MediaLibvaCommonNext::MediaBufferToMosResource(surface->pShadowBuffer, &source); |
| MediaLibvaCommonNext::MediaSurfaceToMosResource(surface, &target); |
| } |
| else |
| { |
| MediaLibvaCommonNext::MediaSurfaceToMosResource(surface, &source); |
| MediaLibvaCommonNext::MediaBufferToMosResource(surface->pShadowBuffer, &target); |
| } |
| |
| return mediaDrvCtx->pfnMediaMemoryTileConvert( |
| &mosCtx, |
| &source, |
| &target, |
| surface->pGmmResourceInfo->GetBaseWidth(), |
| surface->pGmmResourceInfo->GetBaseHeight(), |
| 0, |
| 0, |
| !isDeSwizzle, |
| false); |
| } |
| |
| VAStatus MediaLibvaUtilNext::CreateBuffer( |
| DDI_MEDIA_BUFFER *buffer, |
| MOS_BUFMGR *bufmgr) |
| { |
| VAStatus status = VA_STATUS_SUCCESS; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(buffer, "nullptr buffer", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_LESS(buffer->format, Media_Format_Count, "Invalid buffer->format", VA_STATUS_ERROR_INVALID_PARAMETER); |
| |
| if (buffer->format == Media_Format_CPU) |
| { |
| buffer->pData= (uint8_t*)MOS_AllocAndZeroMemory(buffer->iSize); |
| if (nullptr == buffer->pData) |
| { |
| status = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| } |
| else |
| { |
| if (Media_Format_2DBuffer == buffer->format) |
| { |
| status = Allocate2DBuffer(buffer->uiHeight, buffer->uiWidth, buffer, bufmgr); |
| } |
| else |
| { |
| status = AllocateBuffer(buffer->format, buffer->iSize, buffer, bufmgr); |
| } |
| } |
| |
| buffer->uiLockedBufID = VA_INVALID_ID; |
| buffer->uiLockedImageID = VA_INVALID_ID; |
| buffer->iRefCount = 0; |
| |
| return status; |
| } |
| |
| VAStatus MediaLibvaUtilNext::Allocate2DBuffer( |
| uint32_t height, |
| uint32_t width, |
| PDDI_MEDIA_BUFFER mediaBuffer, |
| MOS_BUFMGR *bufmgr) |
| { |
| DDI_CHK_NULL(mediaBuffer, "mediaBuffer is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaBuffer->pMediaCtx, "mediaBuffer->pMediaCtx is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaBuffer->pMediaCtx->pGmmClientContext, "mediaBuffer->pMediaCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| |
| int32_t size = 0; |
| uint32_t tileformat = I915_TILING_NONE; |
| VAStatus hRes = VA_STATUS_SUCCESS; |
| int32_t mem_type = MOS_MEMPOOL_VIDEOMEMORY; |
| |
| // Create GmmResourceInfo |
| GMM_RESCREATE_PARAMS gmmParams; |
| MOS_ZeroMemory(&gmmParams, sizeof(gmmParams)); |
| gmmParams.BaseWidth = width; |
| gmmParams.BaseHeight = height; |
| gmmParams.ArraySize = 1; |
| gmmParams.Type = RESOURCE_2D; |
| gmmParams.Format = GMM_FORMAT_GENERIC_8BIT; |
| |
| DDI_CHK_CONDITION(gmmParams.Format == GMM_FORMAT_INVALID, |
| "Unsupported format", |
| VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT); |
| |
| gmmParams.Flags.Info.Linear = true; |
| gmmParams.Flags.Gpu.Video = true; |
| gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaBuffer->pMediaCtx->SkuTable, FtrLocalMemory); |
| GMM_RESOURCE_INFO *gmmResourceInfo; |
| mediaBuffer->pGmmResourceInfo = gmmResourceInfo = mediaBuffer->pMediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams); |
| |
| if(nullptr == gmmResourceInfo) |
| { |
| DDI_VERBOSEMESSAGE("Gmm Create Resource Failed."); |
| hRes = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| return hRes; |
| } |
| uint32_t gmmPitch; |
| uint32_t gmmSize; |
| uint32_t gmmHeight; |
| gmmPitch = (uint32_t)gmmResourceInfo->GetRenderPitch(); |
| gmmSize = (uint32_t)gmmResourceInfo->GetSizeSurface(); |
| gmmHeight = gmmResourceInfo->GetBaseHeight(); |
| |
| MemoryPolicyParameter memPolicyPar = { 0 }; |
| memPolicyPar.skuTable = &mediaBuffer->pMediaCtx->SkuTable; |
| memPolicyPar.waTable = &mediaBuffer->pMediaCtx->WaTable; |
| memPolicyPar.resInfo = mediaBuffer->pGmmResourceInfo; |
| memPolicyPar.resName = "Media 2D Buffer"; |
| memPolicyPar.uiType = mediaBuffer->uiType; |
| memPolicyPar.preferredMemType = mediaBuffer->bUseSysGfxMem ? MOS_MEMPOOL_SYSTEMMEMORY : 0; |
| |
| mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar); |
| |
| MOS_LINUX_BO *bo; |
| bo = mos_bo_alloc(bufmgr, "Media 2D Buffer", gmmSize, 4096, mem_type); |
| |
| mediaBuffer->bMapped = false; |
| if (bo) |
| { |
| mediaBuffer->format = Media_Format_2DBuffer; |
| mediaBuffer->uiWidth = width; |
| mediaBuffer->uiHeight = gmmHeight; |
| mediaBuffer->uiPitch = gmmPitch; |
| mediaBuffer->iSize = gmmSize; |
| mediaBuffer->iRefCount = 0; |
| mediaBuffer->bo = bo; |
| mediaBuffer->TileType = tileformat; |
| mediaBuffer->pData = (uint8_t*) bo->virt; |
| DDI_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource)\n", size, width, height); |
| uint32_t event[] = {bo->handle, mediaBuffer->format, width, height, gmmPitch, bo->size, tileformat, 0}; |
| MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_INFO, event, sizeof(event), &gmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG)); |
| } |
| else |
| { |
| DDI_VERBOSEMESSAGE("Fail to Alloc %7d bytes (%d x %d resource)\n", size, width, height); |
| hRes = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| return hRes; |
| } |
| |
| VAStatus MediaLibvaUtilNext::AllocateBuffer( |
| DDI_MEDIA_FORMAT format, |
| int32_t size, |
| PDDI_MEDIA_BUFFER mediaBuffer, |
| MOS_BUFMGR *bufmgr) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(mediaBuffer, "mediaBuffer is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaBuffer->pMediaCtx, "mediaBuffer->pMediaCtx is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| DDI_CHK_NULL(mediaBuffer->pMediaCtx->pGmmClientContext, "mediaBuffer->pMediaCtx->pGmmClientContext is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| if(format >= Media_Format_Count) |
| { |
| return VA_STATUS_ERROR_INVALID_PARAMETER; |
| } |
| |
| VAStatus hRes = VA_STATUS_SUCCESS; |
| int32_t mem_type = MOS_MEMPOOL_VIDEOMEMORY; |
| |
| // create fake GmmResourceInfo |
| GMM_RESCREATE_PARAMS gmmParams; |
| MOS_ZeroMemory(&gmmParams, sizeof(gmmParams)); |
| gmmParams.BaseWidth = 1; |
| gmmParams.BaseHeight = 1; |
| gmmParams.ArraySize = 0; |
| gmmParams.Type = RESOURCE_1D; |
| gmmParams.Format = GMM_FORMAT_GENERIC_8BIT; |
| gmmParams.Flags.Gpu.Video = true; |
| gmmParams.Flags.Info.Linear = true; |
| gmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&mediaBuffer->pMediaCtx->SkuTable, FtrLocalMemory); |
| |
| mediaBuffer->pGmmResourceInfo = mediaBuffer->pMediaCtx->pGmmClientContext->CreateResInfoObject(&gmmParams); |
| DDI_CHK_NULL(mediaBuffer->pGmmResourceInfo, "pGmmResourceInfo is nullptr", VA_STATUS_ERROR_INVALID_BUFFER); |
| mediaBuffer->pGmmResourceInfo->OverrideSize(mediaBuffer->iSize); |
| mediaBuffer->pGmmResourceInfo->OverrideBaseWidth(mediaBuffer->iSize); |
| mediaBuffer->pGmmResourceInfo->OverridePitch(mediaBuffer->iSize); |
| |
| MemoryPolicyParameter memPolicyPar = { 0 }; |
| memPolicyPar.skuTable = &mediaBuffer->pMediaCtx->SkuTable; |
| memPolicyPar.waTable = &mediaBuffer->pMediaCtx->WaTable; |
| memPolicyPar.resInfo = mediaBuffer->pGmmResourceInfo; |
| memPolicyPar.resName = "Media Buffer"; |
| memPolicyPar.uiType = mediaBuffer->uiType; |
| memPolicyPar.preferredMemType = mediaBuffer->bUseSysGfxMem ? MOS_MEMPOOL_SYSTEMMEMORY : 0; |
| |
| mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar); |
| MOS_LINUX_BO *bo = mos_bo_alloc(bufmgr, "Media Buffer", size, 4096, mem_type); |
| mediaBuffer->bMapped = false; |
| if (bo) |
| { |
| mediaBuffer->format = format; |
| mediaBuffer->iSize = size; |
| mediaBuffer->iRefCount = 0; |
| mediaBuffer->bo = bo; |
| mediaBuffer->pData = (uint8_t*) bo->virt; |
| |
| DDI_VERBOSEMESSAGE("Alloc %8d bytes resource.",size); |
| uint32_t event[] = {bo->handle, format, size, 1, size, bo->size, 0, 0}; |
| MOS_TraceEventExt(EVENT_VA_BUFFER, EVENT_TYPE_INFO, event, sizeof(event), &mediaBuffer->pGmmResourceInfo->GetResFlags(), sizeof(GMM_RESOURCE_FLAG)); |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("Fail to Alloc %8d bytes resource.",size); |
| hRes = VA_STATUS_ERROR_ALLOCATION_FAILED; |
| } |
| |
| return hRes; |
| } |
| |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT MediaLibvaUtilNext::AllocPMediaBufferFromHeap(PDDI_MEDIA_HEAP bufferHeap) |
| { |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(bufferHeap, "nullptr bufferHeap", nullptr); |
| |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapElmt = nullptr; |
| if (nullptr == bufferHeap->pFirstFreeHeapElement) |
| { |
| void *newHeapBase = MOS_ReallocMemory(bufferHeap->pHeapBase, (bufferHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_BUFFER_HEAP_ELEMENT)); |
| if (nullptr == newHeapBase) |
| { |
| DDI_ASSERTMESSAGE("DDI: realloc failed."); |
| return nullptr; |
| } |
| bufferHeap->pHeapBase = newHeapBase; |
| PDDI_MEDIA_BUFFER_HEAP_ELEMENT mediaBufferHeapBase = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pHeapBase; |
| bufferHeap->pFirstFreeHeapElement = (void*)(&mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements]); |
| for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++) |
| { |
| mediaBufferHeapElmt = &mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements + i]; |
| mediaBufferHeapElmt->pNextFree = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &mediaBufferHeapBase[bufferHeap->uiAllocatedHeapElements + i + 1]; |
| mediaBufferHeapElmt->uiVaBufferID = bufferHeap->uiAllocatedHeapElements + i; |
| } |
| bufferHeap->uiAllocatedHeapElements += DDI_MEDIA_HEAP_INCREMENTAL_SIZE; |
| } |
| |
| mediaBufferHeapElmt = (PDDI_MEDIA_BUFFER_HEAP_ELEMENT)bufferHeap->pFirstFreeHeapElement; |
| bufferHeap->pFirstFreeHeapElement = mediaBufferHeapElmt->pNextFree; |
| return mediaBufferHeapElmt; |
| } |
| |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT MediaLibvaUtilNext::AllocPVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap) |
| { |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT vaimageHeapElmt = nullptr; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(imageHeap, "nullptr imageHeap", nullptr); |
| |
| if (nullptr == imageHeap->pFirstFreeHeapElement) |
| { |
| void *newHeapBase = MOS_ReallocMemory(imageHeap->pHeapBase, (imageHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_IMAGE_HEAP_ELEMENT)); |
| |
| if (nullptr == newHeapBase) |
| { |
| DDI_ASSERTMESSAGE("DDI: realloc failed."); |
| return nullptr; |
| } |
| imageHeap->pHeapBase = newHeapBase; |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT vaimageHeapBase = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase; |
| imageHeap->pFirstFreeHeapElement = (void*)(&vaimageHeapBase[imageHeap->uiAllocatedHeapElements]); |
| for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++) |
| { |
| vaimageHeapElmt = &vaimageHeapBase[imageHeap->uiAllocatedHeapElements + i]; |
| vaimageHeapElmt->pNextFree = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &vaimageHeapBase[imageHeap->uiAllocatedHeapElements + i + 1]; |
| vaimageHeapElmt->uiVaImageID = imageHeap->uiAllocatedHeapElements + i; |
| } |
| imageHeap->uiAllocatedHeapElements += DDI_MEDIA_HEAP_INCREMENTAL_SIZE; |
| |
| } |
| |
| vaimageHeapElmt = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pFirstFreeHeapElement; |
| imageHeap->pFirstFreeHeapElement = vaimageHeapElmt->pNextFree; |
| return vaimageHeapElmt; |
| } |
| |
| GMM_RESOURCE_FORMAT MediaLibvaUtilNext::ConvertFourccToGmmFmt(uint32_t fourcc) |
| { |
| DDI_FUNC_ENTER; |
| switch (fourcc) |
| { |
| case VA_FOURCC_BGRA : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE; |
| case VA_FOURCC_ARGB : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE; |
| case VA_FOURCC_RGBA : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE; |
| case VA_FOURCC_ABGR : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE; |
| case VA_FOURCC_BGRX : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE; |
| case VA_FOURCC_XRGB : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE; |
| case VA_FOURCC_RGBX : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE; |
| case VA_FOURCC_XBGR : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE; |
| case VA_FOURCC_R8G8B8 : return GMM_FORMAT_R8G8B8_UNORM; |
| case VA_FOURCC_RGBP : return GMM_FORMAT_RGBP; |
| case VA_FOURCC_BGRP : return GMM_FORMAT_BGRP; |
| case VA_FOURCC_RGB565 : return GMM_FORMAT_B5G6R5_UNORM_TYPE; |
| case VA_FOURCC_AYUV : return GMM_FORMAT_AYUV_TYPE; |
| #if VA_CHECK_VERSION(1, 13, 0) |
| case VA_FOURCC_XYUV : return GMM_FORMAT_AYUV_TYPE; |
| #endif |
| case VA_FOURCC_NV12 : return GMM_FORMAT_NV12_TYPE; |
| case VA_FOURCC_NV21 : return GMM_FORMAT_NV21_TYPE; |
| case VA_FOURCC_YUY2 : return GMM_FORMAT_YUY2; |
| case VA_FOURCC_UYVY : return GMM_FORMAT_UYVY; |
| case VA_FOURCC_YV12 : return GMM_FORMAT_YV12_TYPE; |
| case VA_FOURCC_I420 : return GMM_FORMAT_I420_TYPE; |
| case VA_FOURCC_IYUV : return GMM_FORMAT_IYUV_TYPE; |
| case VA_FOURCC_411P : return GMM_FORMAT_MFX_JPEG_YUV411_TYPE; |
| case VA_FOURCC_422H : return GMM_FORMAT_MFX_JPEG_YUV422H_TYPE; |
| case VA_FOURCC_422V : return GMM_FORMAT_MFX_JPEG_YUV422V_TYPE; |
| case VA_FOURCC_444P : return GMM_FORMAT_MFX_JPEG_YUV444_TYPE; |
| case VA_FOURCC_IMC3 : return GMM_FORMAT_IMC3_TYPE; |
| case VA_FOURCC_P208 : return GMM_FORMAT_P208_TYPE; |
| case VA_FOURCC_P010 : return GMM_FORMAT_P010_TYPE; |
| case VA_FOURCC_P012 : return GMM_FORMAT_P016_TYPE; |
| case VA_FOURCC_P016 : return GMM_FORMAT_P016_TYPE; |
| case VA_FOURCC_Y210 : return GMM_FORMAT_Y210_TYPE; |
| case VA_FOURCC_Y410 : return GMM_FORMAT_Y410_TYPE; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y212 : return GMM_FORMAT_Y212_TYPE; |
| #endif |
| case VA_FOURCC_Y216 : return GMM_FORMAT_Y216_TYPE; |
| #if VA_CHECK_VERSION(1, 9, 0) |
| case VA_FOURCC_Y412 : return GMM_FORMAT_Y412_TYPE; |
| #endif |
| case VA_FOURCC_Y416 : return GMM_FORMAT_Y416_TYPE; |
| case VA_FOURCC_Y800 : return GMM_FORMAT_GENERIC_8BIT; |
| case VA_FOURCC_A2R10G10B10 : return GMM_FORMAT_R10G10B10A2_UNORM_TYPE; |
| case VA_FOURCC_A2B10G10R10 : return GMM_FORMAT_B10G10R10A2_UNORM_TYPE; |
| case VA_FOURCC_X2R10G10B10 : return GMM_FORMAT_R10G10B10A2_UNORM_TYPE; |
| case VA_FOURCC_X2B10G10R10 : return GMM_FORMAT_B10G10R10A2_UNORM_TYPE; |
| default : return GMM_FORMAT_INVALID; |
| } |
| } |
| |
| void MediaLibvaUtilNext::InitMutex(PMEDIA_MUTEX_T mutex) |
| { |
| pthread_mutex_init(mutex, nullptr); |
| } |
| |
| void MediaLibvaUtilNext::DestroyMutex(PMEDIA_MUTEX_T mutex) |
| { |
| int32_t ret = pthread_mutex_destroy(mutex); |
| if(ret != 0) |
| { |
| DDI_NORMALMESSAGE("can't destroy the mutex!\n"); |
| } |
| } |
| |
| VAStatus MediaLibvaUtilNext::SetMediaResetEnableFlag(PDDI_MEDIA_CONTEXT mediaCtx) |
| { |
| bool enableReset = false; |
| mediaCtx->bMediaResetEnable = false; |
| |
| DDI_CHK_NULL(mediaCtx,"nullptr mediaCtx!", VA_STATUS_ERROR_INVALID_CONTEXT); |
| |
| if(!MEDIA_IS_SKU(&mediaCtx->SkuTable, FtrSWMediaReset)) |
| { |
| mediaCtx->bMediaResetEnable = false; |
| return VA_STATUS_SUCCESS; |
| } |
| |
| mediaCtx->bMediaResetEnable = true; |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| ReadUserSettingForDebug( |
| mediaCtx->m_userSettingPtr, |
| enableReset, |
| __MEDIA_USER_FEATURE_VALUE_MEDIA_RESET_ENABLE, |
| MediaUserSetting::Group::Device); |
| mediaCtx->bMediaResetEnable = enableReset; |
| #endif |
| if(!mediaCtx->bMediaResetEnable) |
| { |
| return VA_STATUS_SUCCESS; |
| } |
| |
| char* mediaResetEnv = getenv("INTEL_MEDIA_RESET_WATCHDOG"); |
| if(mediaResetEnv) |
| { |
| mediaCtx->bMediaResetEnable = strcmp(mediaResetEnv, "1") ? false : true; |
| return VA_STATUS_SUCCESS; |
| } |
| |
| return VA_STATUS_SUCCESS; |
| } |
| |
| VAStatus MediaLibvaUtilNext::GetSurfaceModifier( |
| DDI_MEDIA_CONTEXT *mediaCtx, |
| DDI_MEDIA_SURFACE *mediaSurface, |
| uint64_t &modifier) |
| { |
| DDI_CHK_NULL(mediaCtx, "nullptr media context", VA_STATUS_ERROR_INVALID_CONTEXT); |
| DDI_CHK_NULL(mediaSurface, "nullptr mediaSurface", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(mediaSurface->bo, "nullptr mediaSurface->bo", VA_STATUS_ERROR_INVALID_SURFACE); |
| DDI_CHK_NULL(mediaSurface->pGmmResourceInfo, "nullptr mediaSurface->pGmmResourceInfo", VA_STATUS_ERROR_INVALID_SURFACE); |
| GMM_TILE_TYPE gmmTileType = mediaSurface->pGmmResourceInfo->GetTileType(); |
| GMM_RESOURCE_FLAG gmmFlags = {0}; |
| gmmFlags = mediaSurface->pGmmResourceInfo->GetResFlags(); |
| |
| bool bMmcEnabled = false; |
| if ((gmmFlags.Gpu.MMC || |
| gmmFlags.Gpu.CCS) && |
| (gmmFlags.Info.MediaCompressed || |
| gmmFlags.Info.RenderCompressed)) |
| { |
| bMmcEnabled = true; |
| } |
| else |
| { |
| bMmcEnabled = false; |
| } |
| |
| switch(gmmTileType) |
| { |
| case GMM_TILED_4: |
| if(mediaCtx->m_auxTableMgr && bMmcEnabled) |
| { |
| modifier = gmmFlags.Info.MediaCompressed ? I915_FORMAT_MOD_4_TILED_MTL_MC_CCS : |
| (gmmFlags.Info.RenderCompressed ? I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC : I915_FORMAT_MOD_4_TILED); |
| } |
| else |
| { |
| modifier = I915_FORMAT_MOD_4_TILED; |
| } |
| break; |
| case GMM_TILED_Y: |
| if (mediaCtx->m_auxTableMgr && bMmcEnabled) |
| { |
| modifier = gmmFlags.Info.MediaCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS : |
| - (gmmFlags.Info.RenderCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS : I915_FORMAT_MOD_Y_TILED); |
| } |
| else |
| { |
| modifier = I915_FORMAT_MOD_Y_TILED; |
| } |
| break; |
| case GMM_TILED_X: |
| modifier = I915_FORMAT_MOD_X_TILED; |
| break; |
| case GMM_NOT_TILED: |
| modifier = DRM_FORMAT_MOD_NONE; |
| break; |
| default: |
| //handle other possible tile format |
| if(I915_TILING_Y == mediaSurface->TileType) |
| { |
| modifier = gmmFlags.Info.MediaCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS : |
| - (gmmFlags.Info.RenderCompressed ? I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS : I915_FORMAT_MOD_Y_TILED); |
| } |
| else |
| { |
| modifier = DRM_FORMAT_MOD_NONE; |
| } |
| break; |
| |
| } |
| return VA_STATUS_SUCCESS; |
| } |
| |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT MediaLibvaUtilNext::DdiAllocPVAContextFromHeap( |
| PDDI_MEDIA_HEAP vaContextHeap) |
| { |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vacontextHeapElmt = nullptr; |
| DDI_FUNCTION_ENTER(); |
| DDI_CHK_NULL(vaContextHeap, "nullptr vaContextHeap", nullptr); |
| |
| if (nullptr == vaContextHeap->pFirstFreeHeapElement) |
| { |
| void *newHeapBase = MOS_ReallocMemory(vaContextHeap->pHeapBase, (vaContextHeap->uiAllocatedHeapElements + DDI_MEDIA_HEAP_INCREMENTAL_SIZE) * sizeof(DDI_MEDIA_VACONTEXT_HEAP_ELEMENT)); |
| DDI_CHK_NULL(newHeapBase, "DDI: realloc failed.", nullptr); |
| |
| vaContextHeap->pHeapBase = newHeapBase; |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vacontextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pHeapBase; |
| DDI_CHK_NULL(vacontextHeapBase, "nullptr vacontextHeapBase.", nullptr); |
| vaContextHeap->pFirstFreeHeapElement = (void*)(&(vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements])); |
| for (int32_t i = 0; i < (DDI_MEDIA_HEAP_INCREMENTAL_SIZE); i++) |
| { |
| vacontextHeapElmt = &vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements + i]; |
| vacontextHeapElmt->pNextFree = (i == (DDI_MEDIA_HEAP_INCREMENTAL_SIZE - 1))? nullptr : &vacontextHeapBase[vaContextHeap->uiAllocatedHeapElements + i + 1]; |
| vacontextHeapElmt->uiVaContextID = vaContextHeap->uiAllocatedHeapElements + i; |
| vacontextHeapElmt->pVaContext = nullptr; |
| } |
| vaContextHeap->uiAllocatedHeapElements += DDI_MEDIA_HEAP_INCREMENTAL_SIZE; |
| } |
| |
| vacontextHeapElmt = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pFirstFreeHeapElement; |
| vaContextHeap->pFirstFreeHeapElement = vacontextHeapElmt->pNextFree; |
| return vacontextHeapElmt; |
| } |
| |
| void MediaLibvaUtilNext::DdiReleasePVAContextFromHeap( |
| PDDI_MEDIA_HEAP vaContextHeap, |
| uint32_t vaContextID) |
| { |
| DDI_FUNCTION_ENTER(); |
| DDI_CHK_NULL(vaContextHeap, "nullptr vaContextHeap", ); |
| DDI_CHK_LESS(vaContextID, vaContextHeap->uiAllocatedHeapElements, "invalid context id", ); |
| |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapBase = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)vaContextHeap->pHeapBase; |
| PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT vaContextHeapElmt = &vaContextHeapBase[vaContextID]; |
| DDI_CHK_NULL(vaContextHeapElmt->pVaContext, "context is already released", ); |
| void *firstFree = vaContextHeap->pFirstFreeHeapElement; |
| |
| vaContextHeap->pFirstFreeHeapElement = (void*)vaContextHeapElmt; |
| vaContextHeapElmt->pNextFree = (PDDI_MEDIA_VACONTEXT_HEAP_ELEMENT)firstFree; |
| vaContextHeapElmt->pVaContext = nullptr; |
| |
| return; |
| } |
| |
| MOS_FORMAT MediaLibvaUtilNext::GetFormatFromMediaFormat(DDI_MEDIA_FORMAT mediaFormat) |
| { |
| MOS_FORMAT format = Format_Invalid; |
| DDI_FUNC_ENTER; |
| static const std::map<const DDI_MEDIA_FORMAT, const MOS_FORMAT> ddiFormatToMediaFormatMap = |
| { |
| {Media_Format_NV12, Format_NV12}, |
| {Media_Format_NV21, Format_NV21}, |
| {Media_Format_X8R8G8B8, Format_X8R8G8B8}, |
| {Media_Format_X8B8G8R8, Format_X8B8G8R8}, |
| {Media_Format_A8R8G8B8, Format_A8R8G8B8}, |
| {Media_Format_A8B8G8R8, Format_A8B8G8R8}, |
| {Media_Format_R8G8B8A8, Format_A8B8G8R8}, |
| {Media_Format_R5G6B5, Format_R5G6B5}, |
| {Media_Format_R8G8B8, Format_R8G8B8}, |
| {Media_Format_YUY2, Format_YUY2}, |
| {Media_Format_UYVY, Format_UYVY}, |
| {Media_Format_YV12, Format_YV12}, |
| {Media_Format_I420, Format_I420}, |
| {Media_Format_IYUV, Format_IYUV}, |
| {Media_Format_422H, Format_422H}, |
| {Media_Format_422V, Format_422V}, |
| {Media_Format_400P, Format_400P}, |
| {Media_Format_411P, Format_411P}, |
| {Media_Format_444P, Format_444P}, |
| {Media_Format_IMC3, Format_IMC3}, |
| {Media_Format_P010, Format_P010}, |
| {Media_Format_P012, Format_P016}, |
| {Media_Format_P016, Format_P016}, |
| {Media_Format_R10G10B10A2, Format_R10G10B10A2}, |
| {Media_Format_R10G10B10X2, Format_R10G10B10A2}, |
| {Media_Format_B10G10R10A2, Format_B10G10R10A2}, |
| {Media_Format_B10G10R10X2, Format_B10G10R10A2}, |
| {Media_Format_RGBP, Format_RGBP}, |
| {Media_Format_BGRP, Format_BGRP}, |
| {Media_Format_Y210, Format_Y210}, |
| #if VA_CHECK_VERSION(1, 9, 0) |
| {Media_Format_Y212, Format_Y216}, |
| {Media_Format_Y412, Format_Y416}, |
| #endif |
| {Media_Format_Y216, Format_Y216}, |
| {Media_Format_Y410, Format_Y410}, |
| {Media_Format_Y416, Format_Y416}, |
| {Media_Format_AYUV, Format_AYUV}, |
| #if VA_CHECK_VERSION(1, 13, 0) |
| {Media_Format_XYUV, Format_AYUV}, |
| #endif |
| {Media_Format_Y8, Format_Y8}, |
| {Media_Format_Y16S, Format_Y16S}, |
| {Media_Format_Y16U, Format_Y16U}, |
| {Media_Format_VYUY, Format_VYUY}, |
| {Media_Format_YVYU, Format_YVYU}, |
| {Media_Format_A16R16G16B16, Format_A16R16G16B16}, |
| {Media_Format_A16B16G16R16, Format_A16B16G16R16} |
| }; |
| auto it = ddiFormatToMediaFormatMap.find(mediaFormat); |
| if(it != ddiFormatToMediaFormatMap.end()) |
| { |
| return it->second; |
| } |
| else |
| { |
| DDI_ASSERTMESSAGE("ERROR media format to vphal format."); |
| return Format_Invalid; |
| } |
| } |
| |
| MOS_TILE_TYPE MediaLibvaUtilNext::GetTileTypeFromMediaTileType(uint32_t mediaTileType) |
| { |
| MOS_TILE_TYPE tileType = MOS_TILE_INVALID; |
| DDI_FUNC_ENTER; |
| |
| switch(mediaTileType) |
| { |
| case I915_TILING_Y: |
| tileType = MOS_TILE_Y; |
| break; |
| case I915_TILING_X: |
| tileType = MOS_TILE_X; |
| break; |
| case I915_TILING_NONE: |
| tileType = MOS_TILE_LINEAR; |
| break; |
| default: |
| tileType = MOS_TILE_LINEAR; |
| } |
| |
| return tileType; |
| } |
| |
| VPHAL_CSPACE MediaLibvaUtilNext::GetColorSpaceFromMediaFormat(DDI_MEDIA_FORMAT format) |
| { |
| DDI_FUNC_ENTER; |
| MOS_FORMAT mosFormat = GetFormatFromMediaFormat(format); |
| |
| if (IS_RGB_FORMAT(mosFormat)) |
| { |
| return CSpace_sRGB; |
| } |
| else |
| { |
| return CSpace_BT601; |
| } |
| } |
| |
| void MediaLibvaUtilNext::UnRefBufObjInMediaBuffer(PDDI_MEDIA_BUFFER buf) |
| { |
| DDI_FUNC_ENTER; |
| mos_bo_unreference(buf->bo); |
| return; |
| } |
| |
| void MediaLibvaUtilNext::ReleasePVAImageFromHeap(PDDI_MEDIA_HEAP imageHeap, uint32_t vaImageID) |
| { |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT vaImageHeapBase = nullptr; |
| PDDI_MEDIA_IMAGE_HEAP_ELEMENT vaImageHeapElmt = nullptr; |
| void *firstFree = nullptr; |
| DDI_FUNC_ENTER; |
| DDI_CHK_NULL(imageHeap, "nullptr imageHeap", ); |
| |
| DDI_CHK_LESS(vaImageID, imageHeap->uiAllocatedHeapElements, "invalid image id", ); |
| vaImageHeapBase = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)imageHeap->pHeapBase; |
| vaImageHeapElmt = &vaImageHeapBase[vaImageID]; |
| DDI_CHK_NULL(vaImageHeapElmt->pImage, "image is already released", ); |
| firstFree = imageHeap->pFirstFreeHeapElement; |
| imageHeap->pFirstFreeHeapElement = (void*)vaImageHeapElmt; |
| vaImageHeapElmt->pNextFree = (PDDI_MEDIA_IMAGE_HEAP_ELEMENT)firstFree; |
| vaImageHeapElmt->pImage = nullptr; |
| } |
| |
| #ifdef RELEASE |
| void MediaLibvaUtilNext::MediaPrintFps() |
| { |
| return; |
| } |
| #else |
| void MediaLibvaUtilNext::MediaPrintFps() |
| { |
| struct timeval tv2 ={}; |
| DDI_FUNC_ENTER; |
| if (m_isMediaFpsPrintFpsEnabled == false) |
| { |
| return; |
| } |
| if (0 == m_vaFpsSampleSize) |
| { |
| return; |
| } |
| gettimeofday(&tv2, 0); |
| |
| pthread_mutex_lock(&m_fpsMutex); |
| if (-1 == m_frameCountFps) |
| { |
| gettimeofday(&m_tv1, 0); |
| } |
| |
| if (++m_frameCountFps >= m_vaFpsSampleSize) |
| { |
| char fpsFileName[LENGTH_OF_FPS_FILE_NAME] = {}; |
| FILE *fp = nullptr; |
| char temp[LENGTH_OF_FPS_FILE_NAME] = {}; |
| |
| int64_t diff = (tv2.tv_sec - m_tv1.tv_sec)*1000000 + tv2.tv_usec - m_tv1.tv_usec; |
| float fps = m_frameCountFps / (diff / 1000000.0); |
| DDI_NORMALMESSAGE("FPS:%6.4f, Interval:%11lu.", fps,((uint64_t)tv2.tv_sec)*1000 + (tv2.tv_usec/1000)); |
| sprintf_s(temp, sizeof(temp), "FPS:%6.4f, Interval:%" PRIu64"\n", fps,((uint64_t)tv2.tv_sec)*1000 + (tv2.tv_usec/1000)); |
| |
| MOS_ZeroMemory(fpsFileName,LENGTH_OF_FPS_FILE_NAME); |
| sprintf_s(fpsFileName, sizeof(fpsFileName), FPS_FILE_NAME); |
| if ((fp = fopen(fpsFileName, "wb")) == nullptr) |
| { |
| pthread_mutex_unlock(&m_fpsMutex); |
| DDI_ASSERTMESSAGE("Unable to open fps file."); |
| } |
| |
| fwrite(temp, 1, strlen(temp), fp); |
| fclose(fp); |
| m_frameCountFps = -1; |
| } |
| pthread_mutex_unlock(&m_fpsMutex); |
| return; |
| } |
| #endif |