| /* |
| * Copyright (c) 2007-2017, 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_manager_os.cpp |
| //! \brief Contains Class CmSurfaceManager definitions |
| //! |
| #include "cm_surface_manager.h" |
| |
| #include "cm_surface_2d_rt.h" |
| |
| #include "cm_surface_2d_rt.h" |
| #include "cm_device_rt.h" |
| #include "cm_mem.h" |
| |
| namespace CMRT_UMD |
| { |
| //*----------------------------------------------------------------------------- |
| //| Purpose: Create Surface Manager |
| //| Arguments : |
| //| device [in] Pointer to Cm Device |
| //| halMaxValues [in] Cm Max values |
| //| surfaceManager [out] Reference to pointer to CmSurfaceManager |
| //| |
| //| Returns: Result of the operation. |
| //*----------------------------------------------------------------------------- |
| int32_t CmSurfaceManager::Create( |
| CmDeviceRT* device, |
| CM_HAL_MAX_VALUES halMaxValues, |
| CM_HAL_MAX_VALUES_EX halMaxValuesEx, |
| CmSurfaceManager* &surfaceManager) |
| { |
| int32_t result = CM_SUCCESS; |
| |
| surfaceManager = new (std::nothrow) CmSurfaceManager(device); |
| if (surfaceManager) |
| { |
| result = surfaceManager->Initialize(halMaxValues, halMaxValuesEx); |
| if (result != CM_SUCCESS) |
| { |
| CmSurfaceManager::Destroy(surfaceManager); |
| } |
| } |
| else |
| { |
| CM_ASSERTMESSAGE("Error: Failed to create CmSurfaceManager due to out of system memory."); |
| result = CM_OUT_OF_HOST_MEMORY; |
| } |
| return result; |
| } |
| |
| //*----------------------------------------------------------------------------- |
| //| Purpose: Destroy CmSurfaceManager |
| //| Returns: Result of the operation. |
| //*----------------------------------------------------------------------------- |
| int32_t CmSurfaceManager::Destroy(CmSurfaceManager* &surfaceManager) |
| { |
| if (surfaceManager) |
| { |
| delete surfaceManager; |
| surfaceManager = nullptr; |
| } |
| return CM_SUCCESS; |
| } |
| |
| //*----------------------------------------------------------------------------- |
| //| Purpose: Constructor of CmSurfaceManager |
| //| Returns: None |
| //*----------------------------------------------------------------------------- |
| CmSurfaceManager::CmSurfaceManager(CmDeviceRT* device) :CmSurfaceManagerBase(device) {} |
| |
| //*----------------------------------------------------------------------------- |
| //| Purpose: Destructor of CmSurfaceManager |
| //| Returns: None |
| //*----------------------------------------------------------------------------- |
| CmSurfaceManager::~CmSurfaceManager() {} |
| |
| //*----------------------------------------------------------------------------- |
| //| Purpose: Create surface 2d with mos info |
| //| Arguments : |
| //| mosResource [in] pointer to mos resource |
| //| createdByCm [in] if this surface created by thin layer |
| //| surface [IN/out] Reference to CmSurface2D |
| //| |
| //| Returns: Result of the operation. |
| //*----------------------------------------------------------------------------- |
| int32_t CmSurfaceManager::CreateSurface2DFromMosResource(MOS_RESOURCE * mosResource, bool createdByCm, CmSurface2DRT* & surface) |
| { |
| uint32_t handle = 0; |
| uint32_t index = ValidSurfaceIndexStart(); |
| int32_t result = 0; |
| uint32_t width = 0; |
| uint32_t height = 0; |
| uint32_t pitch = 0; |
| CM_SURFACE_FORMAT format = CM_SURFACE_FORMAT_INVALID; |
| |
| surface = nullptr; |
| |
| //Get width, height, pitch, format from mosResource |
| result = GetSurfaceInfo(mosResource, width, height, pitch, format); |
| if( result != CM_SUCCESS ) |
| { |
| CM_ASSERTMESSAGE("Error: Failed to get surface info from mosResource."); |
| return result; |
| } |
| |
| //Sanity check |
| result = Surface2DSanityCheck(width, height, format); |
| if( result != CM_SUCCESS ) |
| { |
| CM_ASSERTMESSAGE("Error: Sanity check for surface 2D failure."); |
| return result; |
| } |
| |
| // For 2D surface, since the real memory buffer is not allocated in CMRT@UMD, no reuse/manager can be done |
| // Real reuse is controlled by the CMRT library. |
| if (GetFreeSurfaceIndex(index) != CM_SUCCESS) |
| { |
| CM_ASSERTMESSAGE("Error: Exceed the maximum surface amount."); |
| return CM_EXCEED_SURFACE_AMOUNT; |
| } |
| |
| if( m_2DSurfaceCount >= m_max2DSurfaceCount ) |
| { |
| CM_ASSERTMESSAGE("Error: Exceed the maximum surface amount."); |
| return CM_EXCEED_SURFACE_AMOUNT; |
| } |
| |
| result = AllocateSurface2D( width, height, format, mosResource, handle); |
| if( result != CM_SUCCESS ) |
| { |
| CM_ASSERTMESSAGE("Error: Failed to allocate surface."); |
| return result; |
| } |
| |
| result = CmSurface2DRT::Create( index, handle, width, height, pitch, format, createdByCm, this, surface ); |
| if( result != CM_SUCCESS ) |
| { |
| FreeSurface2D( handle ); |
| CM_ASSERTMESSAGE("Error: Failed to create CmSurface2D."); |
| return result; |
| } |
| |
| m_surfaceArray[ index ] = surface; |
| UpdateProfileFor2DSurface(index, width, height, format); |
| |
| return CM_SUCCESS; |
| } |
| |
| //*----------------------------------------------------------------------------- |
| //| Purpose: Check the legality of surface's width,height and format |
| //| Returns: Result of the operation. |
| //*----------------------------------------------------------------------------- |
| int32_t CmSurfaceManager::Surface2DSanityCheck(uint32_t width, uint32_t height, CM_SURFACE_FORMAT format) |
| { |
| if( ( width < CM_MIN_SURF_WIDTH ) || ( width > CM_MAX_2D_SURF_WIDTH ) ) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface width."); |
| return CM_INVALID_WIDTH; |
| } |
| |
| if( ( height < CM_MIN_SURF_HEIGHT ) || ( height > CM_MAX_2D_SURF_HEIGHT ) ) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface height."); |
| return CM_INVALID_HEIGHT; |
| } |
| |
| switch( format ) |
| { |
| case CM_SURFACE_FORMAT_X8R8G8B8: |
| case CM_SURFACE_FORMAT_A8R8G8B8: |
| case CM_SURFACE_FORMAT_A8B8G8R8: |
| case CM_SURFACE_FORMAT_R32F: |
| case CM_SURFACE_FORMAT_A8: |
| case CM_SURFACE_FORMAT_P8: |
| case CM_SURFACE_FORMAT_R8G8_SNORM: |
| case CM_SURFACE_FORMAT_Y8_UNORM: |
| case CM_SURFACE_FORMAT_Y16_UNORM: |
| case CM_SURFACE_FORMAT_Y16_SNORM: |
| case CM_SURFACE_FORMAT_A16B16G16R16: |
| case CM_SURFACE_FORMAT_R10G10B10A2: |
| case CM_SURFACE_FORMAT_A16B16G16R16F: |
| case CM_SURFACE_FORMAT_V8U8: |
| case CM_SURFACE_FORMAT_R16_FLOAT: |
| case CM_SURFACE_FORMAT_L8: |
| case CM_SURFACE_FORMAT_R32_SINT: |
| case CM_SURFACE_FORMAT_R32_UINT: |
| case CM_SURFACE_FORMAT_BUFFER_2D: |
| case CM_SURFACE_FORMAT_Y216: |
| case CM_SURFACE_FORMAT_Y416: |
| case CM_SURFACE_FORMAT_AYUV: |
| case CM_SURFACE_FORMAT_Y210: |
| case CM_SURFACE_FORMAT_Y410: |
| case CM_SURFACE_FORMAT_R32G32B32A32F: |
| case CM_SURFACE_FORMAT_400P: |
| break; |
| |
| case CM_SURFACE_FORMAT_R8_UINT: |
| case CM_SURFACE_FORMAT_R16_UINT: |
| case CM_SURFACE_FORMAT_L16: |
| break; |
| |
| case CM_SURFACE_FORMAT_UYVY: |
| case CM_SURFACE_FORMAT_YUY2: |
| if( width & 0x1 ) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface width."); |
| return CM_INVALID_WIDTH; |
| } |
| break; |
| |
| case CM_SURFACE_FORMAT_NV12: |
| if (width & 0x1) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface width."); |
| return CM_INVALID_WIDTH; |
| } |
| break; |
| |
| case CM_SURFACE_FORMAT_P010: |
| case CM_SURFACE_FORMAT_P016: |
| case CM_SURFACE_FORMAT_YV12: |
| if( width & 0x1 ) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface width."); |
| return CM_INVALID_WIDTH; |
| } |
| if( height & 0x1 ) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface height."); |
| return CM_INVALID_HEIGHT; |
| } |
| break; |
| |
| case CM_SURFACE_FORMAT_411P: |
| case CM_SURFACE_FORMAT_411R: |
| case CM_SURFACE_FORMAT_IMC3: |
| case CM_SURFACE_FORMAT_422H: |
| case CM_SURFACE_FORMAT_422V: |
| case CM_SURFACE_FORMAT_444P: |
| case CM_SURFACE_FORMAT_RGBP: |
| case CM_SURFACE_FORMAT_BGRP: |
| case CM_SURFACE_FORMAT_P208: |
| if( width & 0x1 ) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface width."); |
| return CM_INVALID_WIDTH; |
| } |
| if( height & 0x1 ) |
| { |
| CM_ASSERTMESSAGE("Error: Invalid surface height."); |
| return CM_INVALID_HEIGHT; |
| } |
| break; |
| |
| default: |
| CM_ASSERTMESSAGE("Error: Unsupported surface format."); |
| return CM_SURFACE_FORMAT_NOT_SUPPORTED; |
| } |
| |
| return CM_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get mos surface's information (width, height, pitch and format) |
| //! \details This function calls mos interface pfnGetResourceInfo to get details of surface. |
| //! \param [in] mosResource |
| //! pointer to mos resource |
| //! \param [in,out] width |
| //! reference to surface's width |
| //! \param [in,out] height |
| //! reference to surface's height |
| //! \param [in,out] pitch |
| //! reference to surface's lock pitch |
| //! \param [in,out] format |
| //! reference to surface's format |
| //! \return MOS_STATUS |
| //! |
| int32_t CmSurfaceManager::GetSurfaceInfo( MOS_RESOURCE * mosResource, uint32_t &width, uint32_t &height, uint32_t &pitch, CM_SURFACE_FORMAT &format) |
| { |
| PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData(); |
| PCM_HAL_STATE state = cmData->cmHalState; |
| |
| MOS_SURFACE surfaceDetails; |
| MOS_ZeroMemory(&surfaceDetails, sizeof(surfaceDetails)); |
| surfaceDetails.Format = CM_SURFACE_FORMAT_INVALID; |
| state->osInterface->pfnGetResourceInfo(state->osInterface, mosResource, &surfaceDetails); |
| |
| width = surfaceDetails.dwWidth; |
| height = surfaceDetails.dwHeight; |
| format = surfaceDetails.Format; |
| pitch = surfaceDetails.dwLockPitch; |
| |
| return CM_SUCCESS; |
| } |
| |
| int32_t CmSurfaceManager::UpdateSurface2D(MOS_RESOURCE * mosResource, int index, uint32_t handle) |
| { |
| PCM_CONTEXT_DATA cmData = (PCM_CONTEXT_DATA)m_device->GetAccelData(); |
| PCM_HAL_STATE state = cmData->cmHalState; |
| |
| CM_SURFACE_FORMAT format; |
| uint32_t width = 0; |
| uint32_t height = 0; |
| uint32_t pitch = 0; |
| int result = GetSurfaceInfo(mosResource, width, height, pitch, format); |
| if( result != CM_SUCCESS ) |
| { |
| CM_ASSERTMESSAGE("Error: Failed to get surface info from pMosResource."); |
| return result; |
| } |
| |
| CM_HAL_SURFACE2D_PARAM inParam; |
| CmSafeMemSet( &inParam, 0, sizeof( CM_HAL_SURFACE2D_PARAM ) ); |
| inParam.width = width; |
| inParam.height = height; |
| inParam.format = format; |
| inParam.mosResource = mosResource; |
| inParam.isAllocatedbyCmrtUmd = false; |
| inParam.handle = handle; |
| |
| state->pfnUpdateSurface2D(state, &inParam); |
| |
| CmSurface2DRT *surface = static_cast<CmSurface2DRT *>(m_surfaceArray[index]); |
| |
| int ret = surface->UpdateSurfaceProperty(width, height, pitch, format); |
| |
| return ret; |
| |
| } |
| |
| } // namespace |