blob: 91bdbc29b520b39f41046ca271ba4197f0dd9c88 [file] [log] [blame]
/*
* Copyright (c) 2009-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 renderhal_linux.cpp
//! \brief Linux-specific functions in Render Engine state heap manager for VP and CM
//! \details Linux-specific Render Engine state heap management interfaces
//!
#include "mos_os.h"
#include "renderhal.h"
void RenderHal_SetupPrologParams(
PRENDERHAL_INTERFACE renderHal,
RENDERHAL_GENERIC_PROLOG_PARAMS *prologParams,
PMOS_RESOURCE osResource,
uint32_t offset,
uint32_t tag)
{
return;
}
//!
//! \brief Get Surface Info from OsResource
//! \details Update surface info in PRENDERHAL_SURFACE based on allocated OsResource
//! \param PMOS_INTERFACE pOsInterface
//! [in] Pointer to MOS_INTERFACE
//! \param PRENDERHAL_GET_SURFACE_INFO pInfo
//! [in] Pointer to RENDERHAL_GET_SURFACE_INFO
//! \param PMOS_SURFACE pSurface
//! [in/out] Pointer to PMOS_SURFACE
//! \return MOS_STATUS
//! Return MOS_STATUS_SUCCESS if successful, otherwise failed
//!
MOS_STATUS RenderHal_GetSurfaceInfo(
PMOS_INTERFACE pOsInterface,
PRENDERHAL_GET_SURFACE_INFO pInfo,
PMOS_SURFACE pSurface)
{
MOS_STATUS eStatus = MOS_STATUS_UNKNOWN;
MHW_RENDERHAL_ASSERT(pOsInterface);
MHW_RENDERHAL_ASSERT(pSurface);
PMOS_RESOURCE pResource = &pSurface->OsResource;
MOS_SURFACE ResDetails;
MHW_RENDERHAL_ASSERT(!Mos_ResourceIsNull(&pSurface->OsResource));
MOS_ZeroMemory(&ResDetails, sizeof(MOS_SURFACE));
ResDetails.dwArraySlice = pInfo->ArraySlice;
ResDetails.dwMipSlice = pInfo->MipSlice;
ResDetails.S3dChannel = pInfo->S3dChannel;
ResDetails.Format = pSurface->Format;
MHW_RENDERHAL_CHK_STATUS(pOsInterface->pfnGetResourceInfo(pOsInterface, &pSurface->OsResource, &ResDetails));
if (ResDetails.Format == Format_420O)
{
ResDetails.Format = Format_NV12;
}
// Get resource information
pSurface->dwWidth = ResDetails.dwWidth;
pSurface->dwHeight = ResDetails.dwHeight;
pSurface->dwPitch = ResDetails.dwPitch;
pSurface->dwSlicePitch = ResDetails.dwSlicePitch;
pSurface->dwQPitch = ResDetails.dwQPitch;
pSurface->dwDepth = ResDetails.dwDepth;
pSurface->TileType = ResDetails.TileType;
pSurface->TileModeGMM = ResDetails.TileModeGMM;
pSurface->bGMMTileEnabled = ResDetails.bGMMTileEnabled;
pSurface->bOverlay = ResDetails.bOverlay;
pSurface->bFlipChain = ResDetails.bFlipChain;
pSurface->Format = ResDetails.Format;
pSurface->bCompressible = ResDetails.bCompressible;
pSurface->bIsCompressed = ResDetails.bIsCompressed;
pSurface->CompressionMode = ResDetails.CompressionMode;
MHW_RENDERHAL_CHK_STATUS(pOsInterface->pfnGetMemoryCompressionMode(pOsInterface,
&pSurface->OsResource, &pSurface->MmcState));
MHW_RENDERHAL_CHK_STATUS(pOsInterface->pfnGetMemoryCompressionFormat(pOsInterface,
&pSurface->OsResource, &pSurface->CompressionFormat));
if (IS_RGB32_FORMAT(pSurface->Format) ||
IS_RGB16_FORMAT(pSurface->Format) ||
IS_RGB128_FORMAT(pSurface->Format)||
pSurface->Format == Format_RGB ||
pSurface->Format == Format_Y410)
{
pSurface->dwOffset = ResDetails.RenderOffset.RGB.BaseOffset;
pSurface->YPlaneOffset.iSurfaceOffset = ResDetails.RenderOffset.RGB.BaseOffset;
pSurface->YPlaneOffset.iXOffset = ResDetails.RenderOffset.RGB.XOffset;
pSurface->YPlaneOffset.iYOffset = ResDetails.RenderOffset.RGB.YOffset;
}
else // YUV or PL3_RGB
{
// Get Y plane information (plane offset, X/Y offset)
pSurface->dwOffset = ResDetails.RenderOffset.YUV.Y.BaseOffset;
pSurface->YPlaneOffset.iSurfaceOffset = ResDetails.RenderOffset.YUV.Y.BaseOffset;
pSurface->YPlaneOffset.iXOffset = ResDetails.RenderOffset.YUV.Y.XOffset;
pSurface->YPlaneOffset.iYOffset = ResDetails.RenderOffset.YUV.Y.YOffset;
pSurface->YPlaneOffset.iLockSurfaceOffset = ResDetails.LockOffset.YUV.Y;
// Get U/UV plane information (plane offset, X/Y offset)
pSurface->UPlaneOffset.iSurfaceOffset = ResDetails.RenderOffset.YUV.U.BaseOffset;
pSurface->UPlaneOffset.iXOffset = ResDetails.RenderOffset.YUV.U.XOffset;
pSurface->UPlaneOffset.iYOffset = ResDetails.RenderOffset.YUV.U.YOffset;
pSurface->UPlaneOffset.iLockSurfaceOffset = ResDetails.LockOffset.YUV.U;
// Get V plane information (plane offset, X/Y offset)
pSurface->VPlaneOffset.iSurfaceOffset = ResDetails.RenderOffset.YUV.V.BaseOffset;
pSurface->VPlaneOffset.iXOffset = ResDetails.RenderOffset.YUV.V.XOffset;
pSurface->VPlaneOffset.iYOffset = ResDetails.RenderOffset.YUV.V.YOffset;
pSurface->VPlaneOffset.iLockSurfaceOffset = ResDetails.LockOffset.YUV.V;
}
eStatus = MOS_STATUS_SUCCESS;
goto finish;
finish:
return eStatus;
}
//!
//! \brief Send Surfaces PatchList
//! \details Send Surface State commands
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \param PMOS_COMMAND_BUFFER pCmdBuffer
//! [in] Pointer to Command Buffer
//! \return MOS_STATUS
//!
MOS_STATUS RenderHal_SendSurfaces_PatchList(
PRENDERHAL_INTERFACE pRenderHal,
PMOS_COMMAND_BUFFER pCmdBuffer)
{
PMOS_INTERFACE pOsInterface;
PRENDERHAL_STATE_HEAP pStateHeap;
uint8_t *pIndirectState;
uint32_t IndirectStateBase;
uint32_t IndirectStateSize;
int32_t iBindingTableOffs;
MHW_BINDING_TABLE_SEND_PARAMS SendBtParams;
MHW_SURFACE_STATE_SEND_PARAMS SendSurfaceParams;
int32_t iSurfacesPerBT;
int32_t i;
int32_t j;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
//----------------------------------------------
MHW_RENDERHAL_CHK_NULL(pRenderHal);
MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap);
MHW_RENDERHAL_CHK_NULL(pRenderHal->pMhwStateHeap);
MHW_RENDERHAL_CHK_NULL(pRenderHal->pOsInterface);
//----------------------------------------------
pStateHeap = pRenderHal->pStateHeap;
pOsInterface = pRenderHal->pOsInterface;
iSurfacesPerBT = pRenderHal->StateHeapSettings.iSurfacesPerBT;
// Get offset and size of indirect state in command buffer
MHW_RENDERHAL_CHK_STATUS(pOsInterface->pfnGetIndirectState(pOsInterface, &IndirectStateBase, &IndirectStateSize));
pIndirectState = (uint8_t*)pCmdBuffer->pCmdBase + IndirectStateBase;
// Null Patch is only enabled for Media Patchless
SendSurfaceParams.bNeedNullPatch = MEDIA_IS_SKU(pOsInterface->pfnGetSkuTable(pOsInterface), FtrMediaPatchless);
SendSurfaceParams.pIndirectStateBase = pIndirectState;
SendSurfaceParams.iIndirectStateBase = IndirectStateBase;
// Send binding tables and surface states for all phases
SendBtParams.iSurfaceStateBase = pStateHeap->iSurfaceStateOffset;
iBindingTableOffs = pStateHeap->iBindingTableOffset;
for (i = pStateHeap->iCurrentBindingTable; i > 0; i--,
iBindingTableOffs += pStateHeap->iBindingTableSize)
{
// Binding tables entries (input/output)
SendBtParams.pBindingTableSource = pStateHeap->pSshBuffer + iBindingTableOffs;
SendBtParams.pBindingTableTarget = pIndirectState + iBindingTableOffs;
for (j = iSurfacesPerBT; j > 0; j--)
{
// Send BT to indirect heap, retrieve surface state associated with BT entry
pRenderHal->pMhwStateHeap->SendBindingTableEntry(&SendBtParams);
// Function returns Params.iSurfaceState for BT entry (-1 if "Copy=0") and iSurfaceStateOffset
if (SendBtParams.iSurfaceState < 0) continue;
SendSurfaceParams.pSurfaceToken = (uint8_t*) &pStateHeap->pSurfaceEntry[SendBtParams.iSurfaceState].SurfaceToken;
SendSurfaceParams.pSurfaceStateSource = (uint8_t*) pStateHeap->pSurfaceEntry[SendBtParams.iSurfaceState].pSurfaceState;
SendSurfaceParams.iSurfaceStateOffset = SendBtParams.iSurfaceStateOffset;
// It should consider MHW instead of VPHAL type, but currently the function only supports VPHAL type.
pRenderHal->pfnSendSurfaceStateEntry(pRenderHal, pCmdBuffer, &SendSurfaceParams);
}
}
finish:
MHW_RENDERHAL_ASSERT(eStatus == MOS_STATUS_SUCCESS);
return eStatus;
}
//!
//! \brief Set surface state token
//! \details Set surface state token
//! \param [in] pRenderHal
//! pointer to render hal
//! \param [in] Surface token parameters
//! Surface token parameters
//! \param void *pSurfaceStateToken
//! [in/out] pointer to surface state token
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS RenderHal_SetSurfaceStateToken(
PRENDERHAL_INTERFACE pRenderHal,
PMHW_SURFACE_TOKEN_PARAMS pParams,
void *pSurfaceStateToken)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_MI_CHK_NULL(pSurfaceStateToken);
MHW_MI_CHK_NULL(pParams);
MHW_MI_CHK_NULL(pParams->pOsSurface);
SURFACE_STATE_TOKEN_COMMON *pTokenState = (SURFACE_STATE_TOKEN_COMMON*)pSurfaceStateToken;
PMOS_INTERFACE pOsInterface = pRenderHal->pOsInterface;
PMOS_RESOURCE pOsResource = &(pParams->pOsSurface->OsResource);
int32_t iAllocationIndex = pOsInterface->pfnGetResourceAllocationIndex(pOsInterface, pOsResource);
// Initialize Token State
*pTokenState = g_cInit_SURFACE_STATE_TOKEN_COMMON;
pTokenState->DW1.SurfaceAllocationIndex = iAllocationIndex;
MHW_ASSERT(pTokenState->DW1.SurfaceAllocationIndex != MOS_INVALID_ALLOC_INDEX);
pTokenState->DW3.RenderTargetEnable = pParams->bRenderTarget;
pTokenState->DW3.YUVPlane = pParams->YUVPlane;
MOS_HW_COMMAND HwCommandType;
if (pParams->bSurfaceTypeAvs)
{
pTokenState->DW3.SurfaceStateType = MEDIASTATE_BTS_DI_SAMPLE8x8_VME_TYPE;
HwCommandType = MOS_SURFACE_STATE_ADV;
}
else
{
pTokenState->DW3.SurfaceStateType = MEDIASTATE_BTS_DEFAULT_TYPE;
HwCommandType = MOS_SURFACE_STATE;
}
pTokenState->DW0.DriverID = HwCommandType;
pTokenState->DW2.SurfaceOffset = pParams->dwSurfaceOffset;
if (pOsInterface->bUsesGfxAddress)
{
uint64_t ui64GfxAddress = 0;
if ( pOsResource->user_provided_va != 0 )
{
ui64GfxAddress = pOsResource->user_provided_va;
}
else
{
ui64GfxAddress = pOsInterface->pfnGetResourceGfxAddress( pOsInterface, pOsResource ) + pTokenState->DW2.SurfaceOffset;
}
pTokenState->DW4.SurfaceBaseAddress = ( uint32_t )( ui64GfxAddress & 0x00000000FFFFFFFF );
pTokenState->DW5.SurfaceBaseAddress64 = ( uint32_t )( ( ui64GfxAddress & 0x0000FFFF00000000 ) >> 32 );
}
pTokenState->pResourceInfo = (void *)pOsResource;
return eStatus;
}
//!
//! \brief Get Y Offset according to the planeOffset struct and surface pitch
//! \details Get Y Offset according to the planeOffset struct and surface pitch
//! \param pOsInterface
//! [in] pointer to OS Interface
//! \param pSurface
//! [in] Pointers to Surface
//! \return uint16_t
//! [out] the Y offset
//!
uint16_t RenderHal_CalculateYOffset(PMOS_INTERFACE pOsInterface, PMOS_RESOURCE pOsResource)
{
// This is for MMCD/Non-MMCD, GMM will allocate the surface 32 height align surface, the the UV offset will not equal to the surface height.
MOS_SURFACE ResDetails;
uint16_t UYoffset = 0;
MHW_RENDERHAL_ASSERT(!Mos_ResourceIsNull(pOsResource));
MHW_RENDERHAL_ASSERT(pOsInterface);
MOS_ZeroMemory(&ResDetails, sizeof(MOS_SURFACE));
pOsInterface->pfnGetResourceInfo(pOsInterface, pOsResource, &ResDetails);
if (ResDetails.dwPitch)
{
UYoffset = (uint16_t)((ResDetails.RenderOffset.YUV.U.BaseOffset - ResDetails.RenderOffset.YUV.Y.BaseOffset) / ResDetails.dwPitch + ResDetails.RenderOffset.YUV.U.YOffset);
return MOS_MAX(UYoffset, (uint16_t)ResDetails.dwHeight);
}
else
{
return (uint16_t)ResDetails.dwHeight;
}
}
//!
//! \brief Allocate Debug Surface
//! \details Allocate surface for ISA ASM debugging
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success
//! Error code otherwise
//!
MOS_STATUS RenderHal_AllocateDebugSurface(
PRENDERHAL_INTERFACE pRenderHal)
{
MHW_RENDERHAL_UNUSED(pRenderHal);
return MOS_STATUS_SUCCESS;
}
//!
//! \brief Setup Debug Surface State
//! \details Setup surface state for ISA ASM Debug surface
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success
//! Error code otherwise
//!
MOS_STATUS RenderHal_SetupDebugSurfaceState(
PRENDERHAL_INTERFACE pRenderHal)
{
MHW_RENDERHAL_UNUSED(pRenderHal);
return MOS_STATUS_SUCCESS;
}
//!
//! \brief Free Debug Surface
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \return void
//!
void RenderHal_FreeDebugSurface(
PRENDERHAL_INTERFACE pRenderHal)
{
MHW_RENDERHAL_UNUSED(pRenderHal);
return;
}
//!
//! \brief Load Debug Kernel
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \param PMHW_KERNEL_PARAM pSipKernel
//! [in] Pointer to Debug (Sip) Kernel Parameters
//! \return int32_t
//! 0
//!
int32_t RenderHal_LoadDebugKernel(
PRENDERHAL_INTERFACE pRenderHal,
PMHW_KERNEL_PARAM pSipKernel)
{
MHW_RENDERHAL_UNUSED(pRenderHal);
MHW_RENDERHAL_UNUSED(pSipKernel);
return 0;
}
//!
//! \brief Load Debug Kernel
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \param void *pSipKernel
//! [in] Pointer to Debug (Sip) Kernel binary
//! \param uint32_t dwSipSize
//! [in] Debug (Sip) Kernel size
//! \return MOS_STATUS
//!
MOS_STATUS RenderHal_LoadSipKernel(
PRENDERHAL_INTERFACE pRenderHal,
void *pSipKernel,
uint32_t dwSipSize)
{
MHW_RENDERHAL_UNUSED(pRenderHal);
MHW_RENDERHAL_UNUSED(pSipKernel);
MHW_RENDERHAL_UNUSED(dwSipSize);
return MOS_STATUS_SUCCESS;
}
//!
//! \brief Send SIP state command
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \param PMOS_COMMAND_BUFFER pCmdBuffer
//! [in] Pointer to Command Buffer
//! \return MOS_STATUS
//!
MOS_STATUS RenderHal_SendSipStateCmd(
PRENDERHAL_INTERFACE pRenderHal,
PMOS_COMMAND_BUFFER pCmdBuffer)
{
MHW_RENDERHAL_UNUSED(pRenderHal);
MHW_RENDERHAL_UNUSED(pCmdBuffer);
return MOS_STATUS_SUCCESS;
}
//!
//! \brief Add debug control commands
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to Hardware Interface Structure
//! \param PMOS_COMMAND_BUFFER pCmdBuffer
//! [in] Pointer to Command Buffer
//! \return MOS_STATUS
//!
MOS_STATUS RenderHal_AddDebugControl(
PRENDERHAL_INTERFACE pRenderHal,
PMOS_COMMAND_BUFFER pCmdBuffer)
{
MHW_RENDERHAL_UNUSED(pRenderHal);
MHW_RENDERHAL_UNUSED(pCmdBuffer);
return MOS_STATUS_SUCCESS;
}
//!
//! \brief Init Special Interface
//! \details Initializes RenderHal Interface structure, responsible for HW
//! abstraction of HW Rendering Engine for CM(MDF) and VP.
//! \param PRENDERHAL_INTERFACE pRenderHal
//! [in] Pointer to RenderHal Interface Structure
//!
void RenderHal_InitInterfaceEx(PRENDERHAL_INTERFACE pRenderHal)
{
// No special APIs
MHW_RENDERHAL_UNUSED(pRenderHal);
return;
}
//!
//! \brief Issue command to write timestamp
//! \param [in] pRenderHal
//! \param [in] pCmdBuffer
//! \param [in] bStartTime
//! \return MOS_STATUS
//!
MOS_STATUS RenderHal_SendTimingData(
PRENDERHAL_INTERFACE pRenderHal,
PMOS_COMMAND_BUFFER pCmdBuffer,
bool bStartTime)
{
return MOS_STATUS_SUCCESS;
}