/* * Copyright (c) 2018, 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 cm_surface_state.cpp //! \brief Contains Class CmSurfaceState definitions //! #include "cm_surface_state.h" #include "cm_surface_state_manager.h" #include "renderhal_platform_interface.h" uint16_t RenderHal_CalculateYOffset(PMOS_INTERFACE pOsInterface, PMOS_RESOURCE pOsResource); extern const MHW_SURFACE_PLANES g_cRenderHal_SurfacePlanes[RENDERHAL_PLANES_DEFINITION_COUNT]; const uint32_t g_cLookup_RotationMode[8] = { ROTATION_IDENTITY, // 0 - MHW_ROTATION_IDENTITY ROTATION_90, // 1 - MHW_ROTATION_90 ROTATION_180, // 2 - MHW_ROTATION_180 ROTATION_270, // 3 - MHW_ROTATION_270 ROTATION_IDENTITY, // 4 - MHW_MIRROR_HORIZONTAL ROTATION_180, // 5 - MHW_MIRROR_VERTICAL ROTATION_270, // 6 - MHW_ROTATE_90_MIRROR_VERTICAL ROTATION_90 // 7 - MHW_ROTATE_90_MIRROR_HORIZONTAL }; CmSurfaceState::CmSurfaceState(CM_HAL_STATE *cmhal): m_cmhal(cmhal), m_renderhal(nullptr), m_resource(nullptr), m_memoryObjectControl(0), m_ssh(nullptr), m_btIdx(-1), m_bteIdx(-1), m_ssIdx(-1) { m_resourceData = {0}; } CM_RETURN_CODE CmSurfaceState::Initialize(MOS_RESOURCE *resource) { if (m_cmhal) { m_renderhal = m_cmhal->renderHal; } if (!m_renderhal) { return CM_NULL_POINTER; } m_resource = resource; return CM_SUCCESS; } uint32_t CmSurfaceState::GetCacheabilityControl() { RENDERHAL_SURFACE_STATE_PARAMS surfaceParam; MOS_ZeroMemory(&surfaceParam, sizeof(surfaceParam)); GMM_RESOURCE_FLAG gmm_flags = m_resource->pGmmResInfo->GetResFlags(); if (gmm_flags.Gpu.CameraCapture) { m_cmhal->cmHalInterface->HwSetSurfaceMemoryObjectControl( MOS_MHW_GMM_RESOURCE_USAGE_CAMERA_CAPTURE << 8, &surfaceParam); } else { m_cmhal->cmHalInterface->HwSetSurfaceMemoryObjectControl( m_memoryObjectControl, &surfaceParam); } return surfaceParam.MemObjCtl; } CmSurfaceState2Dor3D::CmSurfaceState2Dor3D(CM_HAL_STATE *cmhal): //m_device(device), CmSurfaceState(cmhal), m_format(Format_Invalid), m_width(0), m_height(0), m_depth(0), m_pitch(0), m_qPitch(0), m_tile(0), m_tileModeGMM(MOS_TILE_LINEAR_GMM), m_bGMMTileEnabled(0), m_isCompressed(0), m_compressionMode(0), m_mmcState(MOS_MEMCOMP_DISABLED), m_compressionFormat(0), m_rotation(0), m_chromaSitting(0), m_surfaceXOffset(0), m_surfaceYOffset(0), m_frameType(CM_FRAME), m_isRenderTarget(true), m_paletteID(0), m_userWidth(0), m_userHeight(0), m_userDepth(0), m_maxStateSize(0), m_avsUsed(0), m_numPlane(0), m_pixelPitch(false), m_isWidthInDWord(false), m_isVme(false), m_direction(0), m_isHalfPitchChroma(false), m_isInterleaveChrome(false), m_uXOffset(0), m_uYOffset(0), m_vXOffset(0), m_vYOffset(0), m_isVaSurface(false) { MOS_ZeroMemory(m_surfOffsets, sizeof(m_surfOffsets)); MOS_ZeroMemory(m_xOffsets, sizeof(m_xOffsets)); MOS_ZeroMemory(m_yOffsets, sizeof(m_yOffsets)); MOS_ZeroMemory(m_lockOffsets, sizeof(m_lockOffsets)); MOS_ZeroMemory(m_planeParams, sizeof(m_planeParams)); MOS_ZeroMemory(m_cmds, sizeof(m_cmds)); } CM_RETURN_CODE CmSurfaceState2Dor3D::Initialize(MOS_RESOURCE *resource, bool isAvs, bool isSampler) { CmSurfaceState::Initialize(resource); m_avsUsed = isAvs; m_pixelPitch = (!isAvs)&&isSampler; m_isVme = isAvs&&(!isSampler); m_isWidthInDWord = m_avsUsed?false:(m_pixelPitch?false:true); m_maxStateSize = m_renderhal->pRenderHalPltInterface->GetSurfaceStateCmdSize(); return CM_SUCCESS; } MOS_STATUS CmSurfaceState2Dor3D::GenerateSurfaceState(CM_HAL_SURFACE2D_SURFACE_STATE_PARAM *param) { RefreshSurfaceInfo(param); UpdateSurfaceState(); return MOS_STATUS_SUCCESS; } MOS_STATUS CmSurfaceState2Dor3D::RefreshSurfaceInfo(CM_HAL_SURFACE2D_SURFACE_STATE_PARAM *param) { MOS_SURFACE ResDetails; MHW_RENDERHAL_ASSERT(!Mos_ResourceIsNull(m_resource)); MOS_ZeroMemory(&ResDetails, sizeof(MOS_SURFACE)); ResDetails.Format = (param && param->format)?(MOS_FORMAT)param->format:m_format; m_cmhal->osInterface->pfnGetResourceInfo(m_cmhal->osInterface, m_resource, &ResDetails); m_width = ResDetails.dwWidth; m_height = ResDetails.dwHeight; m_depth = ResDetails.dwDepth; m_pitch = ResDetails.dwPitch; m_qPitch = ResDetails.dwQPitch; m_format = ResDetails.Format; m_tile = ResDetails.TileType; m_tileModeGMM = ResDetails.TileModeGMM; m_bGMMTileEnabled = ResDetails.bGMMTileEnabled; m_isCompressed = ResDetails.bIsCompressed; m_compressionMode = ResDetails.CompressionMode; m_cmhal->osInterface->pfnGetMemoryCompressionMode(m_cmhal->osInterface, m_resource, &m_mmcState); m_cmhal->osInterface->pfnGetMemoryCompressionFormat(m_cmhal->osInterface, m_resource, &m_compressionFormat); #ifdef __GNUC__ // calculate the offsets switch (m_format) { case Format_NV12: m_surfOffsets[1] = ResDetails.RenderOffset.YUV.U.BaseOffset; m_yOffsets[1] = ResDetails.RenderOffset.YUV.U.YOffset; break; case Format_P010: case Format_P016: case Format_P208: m_surfOffsets[1] = (m_height - m_height % 32) * m_pitch; m_yOffsets[1] = m_height % 32; break; case Format_NV21: m_surfOffsets[1] = m_height * m_pitch; break; case Format_YV12: m_surfOffsets[2] = m_height * m_pitch; m_yOffsets[2] = 0; m_surfOffsets[1] = m_height * m_pitch * 5 / 4; m_yOffsets[1] = 0; break; case Format_422H: // Calculation methods are derived from Gmm's result. m_surfOffsets[1] = (m_height - m_height % 32) * m_pitch; m_yOffsets[1] = m_height % 32; m_surfOffsets[2] = (m_height * 2 - (m_height * 2) % 32) * m_pitch; m_yOffsets[2] = (m_height * 2) % 32; break; case Format_IMC3: case Format_422V: // Calculation methods are derived from Gmm's result. m_surfOffsets[1] = (m_height - m_height % 32) * m_pitch; m_yOffsets[1] = m_height % 32; m_surfOffsets[2] = (m_height * 3 / 2 - (m_height * 3 / 2) % 32) * m_pitch; m_yOffsets[2] = (m_height * 3 / 2) % 32; break; case Format_IMC4: m_surfOffsets[1] = m_height * m_pitch; m_yOffsets[1] = m_height; m_yOffsets[2] = m_height * 3 / 2; break; case Format_411P: m_surfOffsets[1] = m_height * m_pitch; m_yOffsets[1] = 0; m_surfOffsets[2] = m_height * m_pitch * 2; m_yOffsets[2] = 0; break; case Format_444P: case Format_RGBP: m_surfOffsets[1] = m_height * m_pitch; m_yOffsets[1] = 0; m_surfOffsets[2] = m_height * m_pitch * 2; m_yOffsets[2] = 0; break; default: break; } #else if (IS_RGB32_FORMAT(m_format) || IS_RGB16_FORMAT(m_format) || IS_RGB128_FORMAT(m_format)|| m_format == Format_RGB || m_format == Format_Y410) { m_surfOffsets[0] = ResDetails.RenderOffset.RGB.BaseOffset; m_xOffsets[0] = ResDetails.RenderOffset.RGB.XOffset; m_yOffsets[0] = ResDetails.RenderOffset.RGB.YOffset; } else // YUV or PL3_RGB { // Get Y plane information (plane offset, X/Y offset) m_surfOffsets[0] = ResDetails.RenderOffset.YUV.Y.BaseOffset; m_xOffsets[0] = ResDetails.RenderOffset.YUV.Y.XOffset; m_yOffsets[0] = ResDetails.RenderOffset.YUV.Y.YOffset; m_lockOffsets[0] = ResDetails.LockOffset.YUV.Y; // Get U/UV plane information (plane offset, X/Y offset) m_surfOffsets[1] = ResDetails.RenderOffset.YUV.U.BaseOffset; m_xOffsets[1] = ResDetails.RenderOffset.YUV.U.XOffset; m_yOffsets[1] = ResDetails.RenderOffset.YUV.U.YOffset; m_lockOffsets[1] = ResDetails.LockOffset.YUV.U; // Get V plane information (plane offset, X/Y offset) m_surfOffsets[2] = ResDetails.RenderOffset.YUV.V.BaseOffset; m_xOffsets[2] = ResDetails.RenderOffset.YUV.V.XOffset; m_yOffsets[2] = ResDetails.RenderOffset.YUV.V.YOffset; m_lockOffsets[2] = ResDetails.LockOffset.YUV.V; } #endif // set User-defined dimension m_width = m_userWidth?m_userWidth:m_width; m_height = m_userHeight?m_userHeight:m_height; m_depth = m_userDepth?m_userDepth:m_depth; // set paramaters for alias if (param) { m_format = param->format?(MOS_FORMAT)param->format:m_format; m_width = param->width?param->width:m_width; m_height = param->height?param->height:m_height; m_depth = param->depth?param->depth:m_depth; m_pitch = param->pitch?param->pitch:m_pitch; m_surfaceXOffset = param->surfaceXOffset?param->surfaceXOffset:m_surfaceXOffset; m_surfaceYOffset = param->surfaceYOffset?param->surfaceYOffset:m_surfaceYOffset; m_memoryObjectControl = param->memoryObjectControl?param->memoryObjectControl:m_memoryObjectControl; } return MOS_STATUS_SUCCESS; } void CmSurfaceState2Dor3D::GetDIUVOffSet() { uint32_t dwNumRowsFromTopV = 0; uint32_t dwNumRowsFromTopU = 0; uint32_t dwNumColsFromLeftV = 0; uint32_t dwNumColsFromLeftU = 0; switch (m_format) { // YY // YY // V- // U- case Format_IMC1: dwNumRowsFromTopV = m_height; dwNumRowsFromTopU = m_height + (m_height >> 1); break; // YY // YY // VU case Format_IMC2: dwNumRowsFromTopV = dwNumRowsFromTopU = m_height; dwNumColsFromLeftU = m_pitch >> 1; break; // YY // YY // U- // V- case Format_IMC3: dwNumRowsFromTopU = m_height; dwNumRowsFromTopV = m_height + (m_height >> 1); break; // YY // YY // UV case Format_IMC4: dwNumRowsFromTopU = dwNumRowsFromTopV = m_height; dwNumColsFromLeftV = m_pitch >> 1; break; // YY // YY // U // V case Format_I420: case Format_IYUV: dwNumRowsFromTopU = m_height; dwNumRowsFromTopV = m_height + (m_height >> 1); break; // YY // YY // V // U case Format_YV12: dwNumRowsFromTopU = m_height + (m_height >> 1); dwNumRowsFromTopV = m_height; break; // YYYY // YYYY // YYYY // YYYY // V // U case Format_YVU9: dwNumRowsFromTopU = m_height; dwNumRowsFromTopV = m_height + (m_height >> 2); break; // NV12 P208 // ---- ---- // YY YY // YY UV (interleaved) // UV (interleaved) case Format_NV12: case Format_P208: case Format_P016: case Format_P010: dwNumRowsFromTopU = dwNumRowsFromTopV = m_height; break; // NV11 // ---- // YYYY // UV (interleaved) case Format_NV11: dwNumRowsFromTopU = dwNumRowsFromTopV = m_height; break; default: MHW_RENDERHAL_ASSERTMESSAGE("called with Packed or Unknown format."); break; } // the Offsets must be even numbers so we round down dwNumRowsFromTopU = MOS_ALIGN_FLOOR(dwNumRowsFromTopU, 2); dwNumColsFromLeftU = MOS_ALIGN_FLOOR(dwNumColsFromLeftU, 2); dwNumRowsFromTopV = MOS_ALIGN_FLOOR(dwNumRowsFromTopV, 2); dwNumColsFromLeftV = MOS_ALIGN_FLOOR(dwNumColsFromLeftV, 2); m_vYOffset = (uint16_t)dwNumRowsFromTopV; m_uYOffset = (uint16_t)dwNumRowsFromTopU; m_vXOffset = (uint16_t)dwNumColsFromLeftV; m_uXOffset = (uint16_t)dwNumColsFromLeftU; } bool CmSurfaceState2Dor3D::IsFormatMMCSupported(MOS_FORMAT format) { // Check if Sample Format is supported if ((format != Format_YUY2) && (format != Format_Y410) && (format != Format_Y216) && (format != Format_Y210) && (format != Format_Y416) && (format != Format_P010) && (format != Format_P016) && (format != Format_AYUV) && (format != Format_NV21) && (format != Format_NV12) && (format != Format_UYVY) && (format != Format_YUYV) && (format != Format_A8B8G8R8) && (format != Format_X8B8G8R8) && (format != Format_A8R8G8B8) && (format != Format_X8R8G8B8) && (format != Format_B10G10R10A2) && (format != Format_R10G10B10A2) && (format != Format_A16R16G16B16F)) { return false; } return true; } int CmSurfaceState2Dor3D::GetPlaneDefinitionMedia() { int planeIndex = -1; bool isRenderOutTarget = false; if ( (m_format == Format_NV12 || m_format == Format_YV12 || m_format == Format_Y216) && (!m_pixelPitch)) { isRenderOutTarget = true; } uint8_t direction = GetDirection(); switch (m_format) { case Format_NV12: { // On G8, NV12 format needs the width and Height to be a multiple // of 4 for both 3D sampler and 8x8 sampler; G75 needs the width // of NV12 input surface to be a multiple of 4 for 3D sampler; // G9+ does not has such restriction; to simplify the implementation, // we enable 2 plane NV12 for all of the platform when the width // or Height is not a multiple of 4 bool is2PlaneNeeded = false; if (!GFX_IS_GEN_10_OR_LATER(m_renderhal->Platform)) { is2PlaneNeeded = (!MOS_IS_ALIGNED(m_height, 4) || !MOS_IS_ALIGNED(m_width, 4)); } else { is2PlaneNeeded = (!MOS_IS_ALIGNED(m_height, 2) || !MOS_IS_ALIGNED(m_width, 2)); } if (is2PlaneNeeded) { planeIndex = RENDERHAL_PLANES_NV12_2PLANES_ADV; } else { planeIndex = RENDERHAL_PLANES_NV12_ADV; m_uYOffset = RenderHal_CalculateYOffset(m_renderhal->pOsInterface, m_resource); } m_isHalfPitchChroma = false; m_isInterleaveChrome = true; // Set up chroma direction m_direction = direction; break; } case Format_P016: if (m_isVme) { planeIndex = RENDERHAL_PLANES_P010_1PLANE_ADV; } else { planeIndex = RENDERHAL_PLANES_P016_2PLANES_ADV; } break; case Format_P208: planeIndex = RENDERHAL_PLANES_P208_1PLANE_ADV; break; case Format_IMC1: case Format_IMC2: case Format_IMC3: case Format_IMC4: case Format_I420: case Format_IYUV: case Format_YV12: case Format_YVU9: planeIndex = RENDERHAL_PLANES_PL3_ADV; m_isHalfPitchChroma = false; if (m_format == Format_I420 || m_format == Format_IYUV || m_format == Format_YV12 || m_format == Format_NV11) { m_isHalfPitchChroma = true; } // Set up chroma direction m_direction = direction; if (true) //if (!pParams->bAVS) { // Get U/V offset for PL3 DNDI RENDERHAL_SURFACE surface; MOS_ZeroMemory(&surface, sizeof(surface)); GetDIUVOffSet(); planeIndex = RENDERHAL_PLANES_NV12_ADV; } break; case Format_400P: // Single Y plane here is treated like a NV12 surface. // U and V offsets fall inside this Y plane. Eventhough false UV pixels are // picked by the kernel, CSC coeffecients are such that the effect of these // are nullified. planeIndex = RENDERHAL_PLANES_NV12_ADV; break; case Format_411P: planeIndex = RENDERHAL_PLANES_411P_ADV; break; case Format_411R: planeIndex = RENDERHAL_PLANES_411R_ADV; break; case Format_422H: planeIndex = RENDERHAL_PLANES_422H_ADV; break; case Format_422V: planeIndex = RENDERHAL_PLANES_422V_ADV; break; case Format_444P: planeIndex = RENDERHAL_PLANES_444P_ADV; break; case Format_RGBP: planeIndex = RENDERHAL_PLANES_RGBP_ADV; break; case Format_BGRP: planeIndex = RENDERHAL_PLANES_BGRP_ADV; break; case Format_AYUV: planeIndex = RENDERHAL_PLANES_AYUV_ADV; break; case Format_YUYV: case Format_YUY2: if (m_isVme) { //Since 422 planar is not supported on application side. //App is using 422 packed as WA with w=w/2 and h=h*2 m_width = m_width * 2; m_height = m_height / 2; planeIndex = RENDERHAL_PLANES_YUY2_ADV; // Set up chroma direction m_direction = direction; } else { planeIndex = RENDERHAL_PLANES_YUY2_ADV; // Set up chroma direction m_direction = direction; } break; case Format_UYVY: planeIndex = RENDERHAL_PLANES_UYVY_ADV; // Set up chroma direction m_direction = direction; break; case Format_YVYU: planeIndex = RENDERHAL_PLANES_YVYU_ADV; // Set up chroma direction m_direction = direction; break; case Format_VYUY: planeIndex = RENDERHAL_PLANES_VYUY_ADV; // Set up chroma direction m_direction = direction; break; case Format_A8R8G8B8: case Format_X8R8G8B8: if (m_isVaSurface) { m_width *= 32; planeIndex = RENDERHAL_PLANES_Y1; } else { planeIndex = RENDERHAL_PLANES_ARGB_ADV; } break; case Format_R8G8SN: if ( m_isVaSurface ) { planeIndex = RENDERHAL_PLANES_Y16S; } break; case Format_V8U8: if ( m_isVaSurface ) { planeIndex = RENDERHAL_PLANES_Y16U; } break; case Format_A8B8G8R8: case Format_X8B8G8R8: planeIndex = RENDERHAL_PLANES_ABGR_ADV; break; case Format_STMM: planeIndex = RENDERHAL_PLANES_STMM_ADV; break; case Format_A8: case Format_Buffer_2D: if (m_isVaSurface) { planeIndex = RENDERHAL_PLANES_Y8; } break; case Format_L8: planeIndex = RENDERHAL_PLANES_L8_ADV; break; case Format_A16B16G16R16: case Format_Y416: planeIndex = RENDERHAL_PLANES_A16B16G16R16_ADV; break; case Format_R10G10B10A2: case Format_Y410: planeIndex = RENDERHAL_PLANES_R10G10B10A2_ADV; break; case Format_L16: case Format_R16S: if (m_isVaSurface) { planeIndex = RENDERHAL_PLANES_Y16S; } break; case Format_D16: case Format_R16U: if (m_isVaSurface) { planeIndex = RENDERHAL_PLANES_Y16U; } break; case Format_P010: if (m_isVme) { planeIndex = RENDERHAL_PLANES_P010_1PLANE_ADV; } else if (m_cmhal->cmHalInterface->IsP010SinglePassSupported() && (!isRenderOutTarget)) { planeIndex = RENDERHAL_PLANES_P010_1PLANE_ADV; m_isHalfPitchChroma = false; m_isInterleaveChrome = true; m_uYOffset = RenderHal_CalculateYOffset(m_renderhal->pOsInterface, m_resource); // Set up chroma direction m_direction = direction; } else { // Format not supported with AVS - use regular format MHW_RENDERHAL_NORMALMESSAGE("Format not supported with AVS."); m_avsUsed = false; } break; case Format_Y210: case Format_Y216: if (m_isVme) { //Since 422 planar is not supported on application side. //App is using 422 packed as WA with w=w/2 and h=h*2 m_width = m_width * 2; m_height = m_height / 2; planeIndex = RENDERHAL_PLANES_Y210_1PLANE_ADV; } else { planeIndex = RENDERHAL_PLANES_Y210_ADV; } break; default: // Format not supported with AVS - use regular format MHW_RENDERHAL_NORMALMESSAGE("Format not supported with AVS."); m_avsUsed = false; break; } MHW_RENDERHAL_ASSERT(planeIndex < RENDERHAL_PLANES_DEFINITION_COUNT); return (int)planeIndex; } int CmSurfaceState2Dor3D::GetPlaneDefinitionRender() { int planeIndex = -1; bool isRenderOutTarget = false; if ( (m_format == Format_NV12 || m_format == Format_YV12 || m_format == Format_Y210 || m_format == Format_Y216) && (!m_pixelPitch)) { isRenderOutTarget = true; } switch (m_format) { case Format_IMC1: case Format_IMC2: case Format_IMC3: case Format_IMC4: case Format_I420: case Format_IYUV: case Format_YVU9: planeIndex = RENDERHAL_PLANES_PL3; break; case Format_YV12: m_isHalfPitchChroma = true; // Y_Uoffset(Height*2 + Height/2) of RENDERHAL_PLANES_YV12 define Bitfield_Range(0, 13) on gen9+. // The max value is 16383. So use PL3 kernel to avoid out of range when Y_Uoffset is larger than 16383. // Use PL3 plane to avoid YV12 U channel shift issue with not 4-aligned height planeIndex = (m_renderhal->bEnableYV12SinglePass && (!isRenderOutTarget) && MOS_IS_ALIGNED(m_height, 4) && (m_height * 2 + m_height / 2) < RENDERHAL_MAX_YV12_PLANE_Y_U_OFFSET_G9)? RENDERHAL_PLANES_YV12 : RENDERHAL_PLANES_PL3; break; case Format_400P: // Single Y plane here is treated like a NV12 surface. // U and V offsets fall inside this Y plane. Eventhough false UV pixels are // picked by the kernel, CSC coeffecients are such that the effect of these // are nullified. planeIndex = RENDERHAL_PLANES_NV12; break; case Format_P016: planeIndex = RENDERHAL_PLANES_P016; break; case Format_P208: planeIndex = RENDERHAL_PLANES_P208; break; case Format_P010: if (m_renderhal->bEnableP010SinglePass && (!isRenderOutTarget)) { planeIndex = RENDERHAL_PLANES_P010_1PLANE; } else { planeIndex = RENDERHAL_PLANES_P010; } break; case Format_411P: planeIndex = RENDERHAL_PLANES_411P; break; case Format_411R: planeIndex = RENDERHAL_PLANES_411R; break; case Format_422H: planeIndex = RENDERHAL_PLANES_422H; break; case Format_422V: planeIndex = RENDERHAL_PLANES_422V; break; case Format_444P: planeIndex = RENDERHAL_PLANES_444P; break; case Format_RGBP: planeIndex = RENDERHAL_PLANES_RGBP; break; case Format_BGRP: planeIndex = RENDERHAL_PLANES_BGRP; break; case Format_NV12: // On Gen7.5 (Haswell) NV12 format needs a single plane instead // of two (listed in renderhal_g75.c for RENDERHAL_PLANES_NV12), and // is also expected by the Sampler or Media Kernels. Yet, the // Data Port works with two planes instead. Besides, the Sampler // uses it for input only (as there is no output) while the Data // Port uses it for input as well as output or both for the same // surface. Hence the check added for bWidthInDword_Y && // bWidthInDword_UV, which are set in vphal_render_3P.c for the // above reason. Two plane NV12 can also be explicitly spcified. // On G8, NV12 format needs the width and Height to be a multiple // of 4 for both 3D sampler and 8x8 sampler; G75 needs the width // of NV12 input surface to be a multiple of 4 for 3D sampler; // G9+ does not has such restriction; to simplify the implementation, // we enable 2 plane NV12 for all of the platform when the width // or Height is not a multiple of 4 { bool is2PlaneNeeded = false; if (!GFX_IS_GEN_10_OR_LATER(m_renderhal->Platform)) { is2PlaneNeeded = (!MOS_IS_ALIGNED(m_height, 4) || !MOS_IS_ALIGNED(m_width, 4)); } else { is2PlaneNeeded = (!MOS_IS_ALIGNED(m_height, 4) || !MOS_IS_ALIGNED(m_width, 2)); } if ( isRenderOutTarget || m_isWidthInDWord || is2PlaneNeeded) { planeIndex = RENDERHAL_PLANES_NV12_2PLANES; } else { planeIndex = RENDERHAL_PLANES_NV12; } } break; case Format_YUYV : case Format_YUY2 : planeIndex = RENDERHAL_PLANES_YUY2; break; case Format_G8R8_G8B8: case Format_UYVY : planeIndex = RENDERHAL_PLANES_UYVY; break; case Format_YVYU: planeIndex = RENDERHAL_PLANES_YVYU; break; case Format_VYUY: planeIndex = RENDERHAL_PLANES_VYUY; break; case Format_A8R8G8B8: planeIndex = RENDERHAL_PLANES_ARGB; break; case Format_R32U: planeIndex = RENDERHAL_PLANES_R32U; break; case Format_R32S: planeIndex = RENDERHAL_PLANES_R32S; break; case Format_R32F: case Format_D32F: case Format_R32: planeIndex = RENDERHAL_PLANES_R32F; break; case Format_Y8: planeIndex = RENDERHAL_PLANES_Y8; break; case Format_Y1: planeIndex = RENDERHAL_PLANES_Y1; break; case Format_Y16U: planeIndex = RENDERHAL_PLANES_Y16U; break; case Format_Y16S: planeIndex = RENDERHAL_PLANES_Y16S; break; case Format_R8G8SN: case Format_V8U8: planeIndex = RENDERHAL_PLANES_V8U8; break; case Format_R16U: planeIndex = RENDERHAL_PLANES_R16U; break; case Format_R16S: planeIndex = RENDERHAL_PLANES_R16S; break; case Format_R8G8UN: planeIndex = RENDERHAL_PLANES_R8G8_UNORM; break; case Format_X8R8G8B8: // h/w doesn't support XRGB render target planeIndex = (m_isRenderTarget) ? RENDERHAL_PLANES_ARGB : RENDERHAL_PLANES_XRGB; break; case Format_A8B8G8R8: planeIndex = RENDERHAL_PLANES_ABGR; break; case Format_X8B8G8R8: // h/w doesn't support XBGR render target planeIndex = (m_isRenderTarget) ? RENDERHAL_PLANES_ABGR : RENDERHAL_PLANES_XBGR; break; case Format_R5G6B5: planeIndex = RENDERHAL_PLANES_RGB16; break; case Format_R8G8B8: planeIndex = RENDERHAL_PLANES_RGB24; break; case Format_AYUV : planeIndex = RENDERHAL_PLANES_AYUV; break; case Format_AI44 : planeIndex = (m_paletteID == 0) ? RENDERHAL_PLANES_AI44_PALLETE_0 : RENDERHAL_PLANES_AI44_PALLETE_1; break; case Format_IA44: planeIndex = (m_paletteID == 0) ? RENDERHAL_PLANES_IA44_PALLETE_0 : RENDERHAL_PLANES_IA44_PALLETE_1; break; case Format_P8: planeIndex = (m_paletteID == 0) ? RENDERHAL_PLANES_P8_PALLETE_0 : RENDERHAL_PLANES_P8_PALLETE_1; break; case Format_A8P8: planeIndex = (m_paletteID == 0) ? RENDERHAL_PLANES_A8P8_PALLETE_0 : RENDERHAL_PLANES_A8P8_PALLETE_1; break; case Format_STMM: planeIndex = RENDERHAL_PLANES_STMM; break; case Format_L8: planeIndex = RENDERHAL_PLANES_L8; break; case Format_A8: case Format_Buffer_2D: planeIndex = RENDERHAL_PLANES_A8; break; case Format_R8U: case Format_R8UN: planeIndex = RENDERHAL_PLANES_R8; break; case Format_R16UN: case Format_D16: case Format_R16: planeIndex = RENDERHAL_PLANES_R16_UNORM; break; case Format_A16B16G16R16: planeIndex = RENDERHAL_PLANES_A16B16G16R16; break; case Format_Y416: if (isRenderOutTarget) { planeIndex = RENDERHAL_PLANES_Y416_RT; } else { planeIndex = RENDERHAL_PLANES_A16B16G16R16; } break; case Format_A16B16G16R16F: planeIndex = RENDERHAL_PLANES_A16B16G16R16F; break; case Format_A16R16G16B16F: planeIndex = RENDERHAL_PLANES_A16R16G16B16F; break; case Format_R32G32B32A32F: planeIndex = RENDERHAL_PLANES_R32G32B32A32F; break; case Format_NV21: planeIndex = RENDERHAL_PLANES_NV21; break; case Format_L16: planeIndex = RENDERHAL_PLANES_L16; break; case Format_R10G10B10A2: case Format_Y410: planeIndex = RENDERHAL_PLANES_R10G10B10A2; break; case Format_Y210: case Format_Y216: { RENDERHAL_PLANE_DEFINITION temp = RENDERHAL_PLANES_DEFINITION_COUNT; m_renderhal->pRenderHalPltInterface->GetPlaneDefForFormatY216( isRenderOutTarget, m_renderhal, temp); planeIndex = temp; } break; case Format_B10G10R10A2: planeIndex = RENDERHAL_PLANES_B10G10R10A2; break; case Format_IRW0: planeIndex = RENDERHAL_PLANES_IRW0; break; case Format_IRW1: planeIndex = RENDERHAL_PLANES_IRW1; break; case Format_IRW2: planeIndex = RENDERHAL_PLANES_IRW2; break; case Format_IRW3: planeIndex = RENDERHAL_PLANES_IRW3; break; case Format_R16G16UN: planeIndex = RENDERHAL_PLANES_R16G16_UNORM; break; case Format_R16G16S: planeIndex = RENDERHAL_PLANES_R16G16_SINT; break; case Format_R16F: planeIndex = RENDERHAL_PLANES_R16_FLOAT; break; case Format_R24G8: case Format_D24S8UN: planeIndex = RENDERHAL_PLANES_R24_UNORM_X8_TYPELESS; break; case Format_R32G8X24: case Format_D32S8X24_FLOAT: planeIndex = RENDERHAL_PLANES_R32_FLOAT_X8X24_TYPELESS; break; default: return -1; } // Get plane definitions MHW_RENDERHAL_ASSERT(planeIndex < RENDERHAL_PLANES_DEFINITION_COUNT); return (int)planeIndex; } uint8_t CmSurfaceState2Dor3D::GetDirection() { if(GFX_IS_GEN_9_OR_LATER(m_renderhal->Platform)) { // Gen9+ uint8_t direction; if (m_chromaSitting & MHW_CHROMA_SITING_HORZ_CENTER) { direction = CHROMA_SITING_UDIRECTION_CENTER; } else { direction = CHROMA_SITING_UDIRECTION_LEFT; } direction = direction << 3; if (m_chromaSitting & MHW_CHROMA_SITING_VERT_TOP) { direction |= CHROMA_SITING_VDIRECTION_0; } else if (m_chromaSitting & MHW_CHROMA_SITING_VERT_BOTTOM) { direction |= CHROMA_SITING_VDIRECTION_1; } else { direction |= CHROMA_SITING_VDIRECTION_1_2; } return direction; } else { return MEDIASTATE_VDIRECTION_FULL_FRAME; } } MOS_STATUS CmSurfaceState2Dor3D::SetPerPlaneParam() { int planeIndex = -1; if (m_avsUsed) { planeIndex = GetPlaneDefinitionMedia(); } else { planeIndex = GetPlaneDefinitionRender(); } CM_CHK_COND_RETURN((planeIndex == -1), MOS_STATUS_UNKNOWN, "Cannot find the plane definition."); bool isWidthInDword = m_avsUsed?false:(m_pixelPitch?false:true); m_numPlane = g_cRenderHal_SurfacePlanes[planeIndex].dwNumPlanes; PCMHW_PLANE_SETTING plane = g_cRenderHal_SurfacePlanes[planeIndex].Plane; uint32_t alignUnitWidth = 1; uint32_t alignUnitHeight = 1; if (m_format == Format_YUY2 || m_format == Format_UYVY || m_format == Format_YVYU || m_format == Format_VYUY || m_format == Format_P208) { alignUnitHeight = 2; } for (uint32_t idx = 0; idx < m_numPlane; idx ++, plane ++) { uint32_t adjustedWidth = MOS_ALIGN_CEIL(m_width, alignUnitWidth); uint32_t adjustedHeight = MOS_ALIGN_CEIL(m_height, alignUnitHeight); adjustedHeight = (adjustedHeight + plane->ui8ScaleHeight - 1) / plane->ui8ScaleHeight; adjustedWidth = adjustedWidth / plane->ui8ScaleWidth; if (m_isWidthInDWord) { if (planeIndex == RENDERHAL_PLANES_R32G32B32A32F) { adjustedWidth = adjustedWidth << 2; } else if(planeIndex == RENDERHAL_PLANES_A16B16G16R16 || planeIndex == RENDERHAL_PLANES_A16B16G16R16_ADV || planeIndex == RENDERHAL_PLANES_A16B16G16R16F || planeIndex == RENDERHAL_PLANES_A16R16G16B16F || planeIndex == RENDERHAL_PLANES_Y210_RT || planeIndex == RENDERHAL_PLANES_Y416_RT || planeIndex == RENDERHAL_PLANES_R32_FLOAT_X8X24_TYPELESS) { adjustedWidth = adjustedWidth << 1; } else { adjustedWidth = (adjustedWidth + plane->ui8PixelsPerDword - 1) / plane->ui8PixelsPerDword; } } if ((!m_isVme) && m_frameType != CM_FRAME) { adjustedHeight /= 2; adjustedHeight = MOS_MAX(adjustedHeight, 1); } adjustedHeight = MOS_ALIGN_FLOOR(adjustedHeight, plane->ui8AlignHeight); adjustedWidth = MOS_ALIGN_FLOOR(adjustedWidth, plane->ui8AlignWidth); m_planeParams[idx].planeID = plane->ui8PlaneID; m_planeParams[idx].format = plane->dwFormat; m_planeParams[idx].width = adjustedWidth; m_planeParams[idx].height= adjustedHeight; if (plane->ui8PlaneID == MHW_U_PLANE || plane->ui8PlaneID == MHW_V_PLANE) { if (m_format == Format_I420 || m_format == Format_IYUV || m_format == Format_YV12 || m_format == Format_NV11) { m_planeParams[idx].pitch = (m_pitch>>1); } else if (m_format == Format_YVU9) { m_planeParams[idx].pitch = (m_pitch>>2); } else { m_planeParams[idx].pitch = m_pitch; } } else { m_planeParams[idx].pitch = m_pitch; } m_planeParams[idx].isAvs = plane->bAdvanced; m_planeParams[idx].xoffset = m_xOffsets[idx] + m_surfaceXOffset; if (m_format == Format_NV12 && idx == 1) { m_planeParams[idx].yoffset = m_yOffsets[idx] + m_surfaceYOffset/2; } else { m_planeParams[idx].yoffset = m_yOffsets[idx] + m_surfaceYOffset; } } return MOS_STATUS_SUCCESS; } MOS_STATUS CmSurfaceState2Dor3D::UpdateSurfaceState() { // get the number of planes and plane types: y, u, v SetPerPlaneParam(); // Set Surface States MHW_SURFACE_STATE_PARAMS SurfStateParams; for (uint32_t idx = 0; idx < m_numPlane; idx ++) { MOS_ZeroMemory(&SurfStateParams, sizeof(SurfStateParams)); SurfStateParams.pSurfaceState = m_cmds + idx * m_maxStateSize; SurfStateParams.bUseAdvState = m_planeParams[idx].isAvs; SurfStateParams.dwWidth = m_planeParams[idx].width; SurfStateParams.dwHeight = m_planeParams[idx].height; SurfStateParams.dwFormat = m_planeParams[idx].format; SurfStateParams.dwPitch = m_planeParams[idx].pitch; SurfStateParams.dwQPitch = m_qPitch; SurfStateParams.bTiledSurface = (m_tile != MOS_TILE_LINEAR)?1:0; SurfStateParams.bTileWalk = IS_Y_MAJOR_TILE_FORMAT(m_tile) ? GFX3DSTATE_TILEWALK_YMAJOR : GFX3DSTATE_TILEWALK_XMAJOR;; SurfStateParams.TileModeGMM = m_tileModeGMM; SurfStateParams.bGMMTileEnabled = m_bGMMTileEnabled; SurfStateParams.dwCacheabilityControl = GetCacheabilityControl(); if (m_cmhal->platform.eRenderCoreFamily <= IGFX_GEN11_CORE) { SurfStateParams.bCompressionEnabled = m_isCompressed; SurfStateParams.bCompressionMode = (m_compressionMode == MOS_MMC_VERTICAL) ? 1 : 0; } else { if (IsFormatMMCSupported(m_format) && m_renderhal->isMMCEnabled) { // bCompressionEnabled/bCompressionMode is deprecated, use MmcState instead. if ((!m_cmhal->cmHalInterface->SupportCompressedOutput()) && (m_mmcState == MOS_MEMCOMP_RC && m_isRenderTarget)) { // RC compression mode is not supported on render output surface. SurfStateParams.MmcState = MOS_MEMCOMP_DISABLED; m_mmcState = MOS_MEMCOMP_DISABLED; SurfStateParams.dwCompressionFormat = 0; } else if (m_mmcState == MOS_MEMCOMP_MC || m_mmcState == MOS_MEMCOMP_RC) { SurfStateParams.MmcState = m_mmcState; if (m_planeParams[idx].planeID == MHW_U_PLANE && (m_format == Format_NV12 || m_format == Format_P010 || m_format == Format_P016)) { SurfStateParams.dwCompressionFormat = (uint32_t)(0x00000010) | (m_compressionFormat & 0x0f); } else if ((m_format == Format_R8G8UN) && (m_mmcState == MOS_MEMCOMP_MC)) { /* it will be an issue if the R8G8UN surface with MC enable is not chroma plane from NV12 surface, so far there is no such case */ SurfStateParams.dwCompressionFormat = (uint32_t)(0x00000010) | (m_compressionFormat & 0x0f); } else { SurfStateParams.dwCompressionFormat = m_compressionFormat & 0x1f; } } else { MHW_RENDERHAL_NORMALMESSAGE("Unsupported Compression Mode for Render Engine."); SurfStateParams.MmcState = MOS_MEMCOMP_DISABLED; m_mmcState = MOS_MEMCOMP_DISABLED; SurfStateParams.dwCompressionFormat = 0; } } } // update if is sampler if (m_pixelPitch || (m_avsUsed && (!m_isVme))) { SurfStateParams.RotationMode = g_cLookup_RotationMode[m_rotation]; } if (m_planeParams[idx].isAvs) { SurfStateParams.bHalfPitchChroma = m_isHalfPitchChroma; SurfStateParams.bInterleaveChroma = m_isInterleaveChrome; SurfStateParams.UVPixelOffsetUDirection = m_direction >> 0x3; SurfStateParams.UVPixelOffsetVDirection = m_direction & 0x7; if (m_planeParams[idx].planeID == MHW_U_PLANE) // AVS U plane { // Lockoffset is the offset from base address of Y plane to the origin of U/V plane. // So, We can get XOffsetforU by Lockoffset % pSurface->dwPitch, and get YOffsetForU by Lockoffset / pSurface->dwPitch SurfStateParams.dwXOffsetForU = (uint32_t)m_lockOffsets[1] % m_pitch; SurfStateParams.dwYOffsetForU = (uint32_t)m_lockOffsets[1] / m_pitch; SurfStateParams.dwXOffsetForV = 0; SurfStateParams.dwYOffsetForV = 0; SurfStateParams.iXOffset = m_xOffsets[1]; SurfStateParams.iYOffset = m_yOffsets[1]; } else if (m_planeParams[idx].planeID == MHW_V_PLANE) // AVS V plane { SurfStateParams.dwXOffsetForU = 0; SurfStateParams.dwYOffsetForU = 0; SurfStateParams.dwXOffsetForV = (uint32_t)m_lockOffsets[2] % m_pitch; SurfStateParams.dwYOffsetForV = (uint32_t)m_lockOffsets[2] / m_pitch; SurfStateParams.iXOffset = m_xOffsets[2]; SurfStateParams.iYOffset = m_yOffsets[2]; } else // AVS/DNDI Y plane { SurfStateParams.dwXOffsetForU = m_uXOffset; SurfStateParams.dwYOffsetForU = m_uYOffset; SurfStateParams.dwXOffsetForV = m_vXOffset; SurfStateParams.dwYOffsetForV = m_vYOffset; SurfStateParams.iXOffset = 0; SurfStateParams.iYOffset = m_yOffsets[0]; } } else { SurfStateParams.SurfaceType3D = (m_depth > 1) ? GFX3DSTATE_SURFACETYPE_3D : GFX3DSTATE_SURFACETYPE_2D; SurfStateParams.dwDepth = MOS_MAX(1, m_depth); SurfStateParams.bVerticalLineStrideOffset = (m_frameType == CM_BOTTOM_FIELD)?1:0; SurfStateParams.bVerticalLineStride = (m_frameType == CM_FRAME)?0:1; SurfStateParams.bHalfPitchChroma = m_isHalfPitchChroma; // Setup surface g9 surface state if (m_planeParams[idx].planeID == MHW_U_PLANE || m_planeParams[idx].planeID == MHW_V_PLANE) { uint32_t pixelPerSampleUV = 1; if (m_isWidthInDWord) { RenderHal_GetPixelsPerSample(m_format, &pixelPerSampleUV); } if(pixelPerSampleUV == 1) { SurfStateParams.iXOffset = m_planeParams[idx].xoffset; } else { SurfStateParams.iXOffset = m_planeParams[idx].xoffset/sizeof(uint32_t); } SurfStateParams.iYOffset = m_planeParams[idx].yoffset; } else // Y plane { SurfStateParams.iXOffset = m_planeParams[idx].xoffset/sizeof(uint32_t); SurfStateParams.iYOffset = m_planeParams[idx].yoffset; if(m_planeParams[idx].format == MHW_GFX3DSTATE_SURFACEFORMAT_PLANAR_420_8) { if (m_format == Format_YV12) { SurfStateParams.bSeperateUVPlane = true; SurfStateParams.dwXOffsetForU = 0; SurfStateParams.dwYOffsetForU = m_height * 2 + m_height/2; SurfStateParams.dwXOffsetForV = 0; SurfStateParams.dwYOffsetForV = m_height * 2; } else { SurfStateParams.bSeperateUVPlane = false; SurfStateParams.dwXOffsetForU = 0; SurfStateParams.dwYOffsetForU = m_surfOffsets[1]/m_pitch + m_yOffsets[1]; SurfStateParams.dwXOffsetForV = 0; SurfStateParams.dwYOffsetForV = 0; } } } } MHW_CHK_STATUS_RETURN(m_renderhal->pMhwStateHeap->SetSurfaceStateEntry(&SurfStateParams)); } return MOS_STATUS_SUCCESS; } CmSurfaceStateBuffer::CmSurfaceStateBuffer(CM_HAL_STATE *cmhal): CmSurfaceState(cmhal), m_size(0), m_offset(0) { MOS_ZeroMemory(m_cmds, sizeof(m_cmds)); } CM_RETURN_CODE CmSurfaceStateBuffer::Initialize(MOS_RESOURCE *resource, uint32_t size) { CmSurfaceState::Initialize(resource); m_size = size; return CM_SUCCESS; } MOS_STATUS CmSurfaceStateBuffer::GenerateSurfaceState(CM_HAL_BUFFER_SURFACE_STATE_ENTRY *param) { if (param) { m_size = param->surfaceStateSize?param->surfaceStateSize:m_size; m_offset = param->surfaceStateOffset?param->surfaceStateOffset:m_offset; m_memoryObjectControl = param->surfaceStateMOCS?param->surfaceStateMOCS:m_memoryObjectControl; } MHW_SURFACE_STATE_PARAMS params; MOS_ZeroMemory(¶ms, sizeof(params)); uint32_t bufferSize = m_size - 1; params.SurfaceType3D = GFX3DSTATE_SURFACETYPE_BUFFER; // Width contains bits [ 6:0] of the number of entries in the buffer params.dwWidth = (uint8_t)(bufferSize & MOS_MASKBITS32(0, 6)); // Height contains bits [20:7] of the number of entries in the buffer params.dwHeight = (uint16_t)((bufferSize & MOS_MASKBITS32(7, 20)) >> 7); // For SURFTYPE_BUFFER, this field indicates the size of the structure params.dwPitch = 0; uint32_t depthMaskRawBuffer = m_renderhal->pRenderHalPltInterface->GetDepthBitMaskForRawBuffer(); params.dwFormat = MHW_GFX3DSTATE_SURFACEFORMAT_RAW; params.dwDepth = (uint16_t)((bufferSize & depthMaskRawBuffer) >> 21); params.dwCacheabilityControl = GetCacheabilityControl(); params.pSurfaceState = m_cmds; // Default tile mode of surface state buffer is linear params.bGMMTileEnabled = true; MHW_CHK_STATUS_RETURN(m_renderhal->pMhwStateHeap->SetSurfaceStateEntry(¶ms)); return MOS_STATUS_SUCCESS; } CmSurfaceStateVME::CmSurfaceStateVME(CM_HAL_STATE *cmhal): CmSurfaceState(cmhal), m_numBte(0), m_forwardCount(0), m_backwardCount(0), m_curIndex(CM_NULL_SURFACE), m_forwardIndexes(nullptr), m_backwardIndexes(nullptr) { MOS_ZeroMemory(&m_surf2DParam, sizeof(m_surf2DParam)); MOS_ZeroMemory(m_offsets, sizeof(m_offsets)); MOS_ZeroMemory(m_mmcStates, sizeof(m_mmcStates)); } CM_RETURN_CODE CmSurfaceStateVME::Initialize(CM_HAL_VME_ARG_VALUE *vmeArg) { CmSurfaceState::Initialize(nullptr); m_forwardCount = vmeArg->fwRefNum; m_backwardCount = vmeArg->bwRefNum; m_curIndex = vmeArg->curSurface; m_forwardIndexes = findFwRefInVmeArg(vmeArg); m_backwardIndexes = findBwRefInVmeArg(vmeArg); uint32_t numPair = m_forwardCount>m_backwardCount?m_forwardCount:m_backwardCount; m_numBte = 2*numPair + 1; m_surf2DParam.width = vmeArg->surfStateParam.surfaceStateWidth; m_surf2DParam.height= vmeArg->surfStateParam.surfaceStateHeight; return CM_SUCCESS; } uint8_t *CmSurfaceStateVME::GetSurfaceState(int index) { int surfIndex = GetCmHalSurfaceIndex(index); if (surfIndex == -1) return nullptr; CmSurfaceState2Dor3DMgr *surfStateMgr = m_cmhal->umdSurf2DTable[surfIndex].surfStateMgr; CmSurfaceState *surfState = nullptr; if (m_surf2DParam.width == 0 && m_surf2DParam.height == 0) { surfState = surfStateMgr->GetSurfaceState(1); } else { surfState = surfStateMgr->GetSurfaceState(1, 0, &m_surf2DParam); } CM_CHK_NULL_RETURN(surfState, nullptr); m_offsets[index]=surfState->GetSurfaceOffset(0); m_mmcStates[index]=surfState->GetMmcState(0); return surfState->GetSurfaceState(0); //in vme every surface has only one plane } MOS_RESOURCE *CmSurfaceStateVME::GetResource(uint32_t index) { int surfIndex = GetCmHalSurfaceIndex(index); if (surfIndex == -1) return nullptr; return m_cmhal->umdSurf2DTable[surfIndex].surfStateMgr->GetResource(); } int CmSurfaceStateVME::GetCmHalSurfaceIndex(uint32_t index) { uint32_t surfIndex; if (index == 0) // current surface { surfIndex = m_curIndex; } else if (index%2 == 1) // forward references { if ((index - 1)/2 >= m_forwardCount) { return -1; } surfIndex = m_forwardIndexes[(index - 1)/2]; } else // backward references { if ((index - 1)/2 >= m_backwardCount) { return -1; } surfIndex = m_backwardIndexes[(index - 2)/2]; } return (int)surfIndex; }