blob: c2bfd1ed62d64daa100d43587da14ec39b5bb02e [file] [log] [blame]
/*
* Copyright (c) 2014-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 mhw_state_heap.c
//! \brief This modules implements HW interface layer to be used on all platforms on all operating systems/DDIs, across MHW components.
//!
#include "mhw_state_heap.h"
#include "mhw_utilities.h"
#include "mhw_block_manager.h"
#include "media_interfaces_mhw.h"
#include "mhw_mi.h"
#include "mhw_cp_interface.h"
extern const uint8_t g_cMhw_VDirection[MHW_NUM_FRAME_FIELD_TYPES] = {
MEDIASTATE_VDIRECTION_FULL_FRAME,
MEDIASTATE_VDIRECTION_TOP_FIELD,
MEDIASTATE_VDIRECTION_BOTTOM_FIELD
};
extern const MHW_SAMPLER_STATE_UNORM_PARAM g_cInit_MhwSamplerStateUnormParam =
{
MHW_SAMPLER_FILTER_CUSTOM, // SamplerFilterMode
MHW_GFX3DSTATE_MAPFILTER_LINEAR, // MagFilter
MHW_GFX3DSTATE_MAPFILTER_LINEAR, // MinFilter
MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP, // AddressU
MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP, // AddressV
MHW_GFX3DSTATE_TEXCOORDMODE_CLAMP, // AddressW
MHW_SAMPLER_SURFACE_PIXEL_UINT,
{0},
{0},
{0},
{0},
0,
0,
0
};
extern const MHW_SURFACE_STATE_PARAMS g_cInit_MhwSurfaceStateParams =
{
nullptr, // pSurfaceState
0, // dwCacheabilityControl
0, // dwFormat
0, // dwWidth
0, // dwHeight
0, // dwDepth
0, // dwPitch
0, // dwQPitch
0, // bUseAdvState
0, // AddressControl
0, // SurfaceType3D
false, // bTiledSurface
false, // bTileWalk
false, // bVerticalLineStride
false, // bVerticalLineStrideOffset
false, // bCompressionEnabled
false, // bCompressionMode
0, // MmcState
false, // bInterleaveChroma
false, // bHalfPitchChroma
false, // bSeperateUVPlane
0, // UVPixelOffsetUDirection
0, // UVPixelOffsetVDirection
0, // RotationMode
0, // bSurfaceArraySpacing
false, // bBoardColorOGL
0, // iXOffset
0, // iYOffset
0, // dwXOffsetForU
0, // dwYOffsetForU
0, // dwXOffsetForV
0, // dwYOffsetForV
0, // Compression Format
0, // L1CacheConfig
nullptr, // [out] pdwCmd
0 // [out] dwLocationInCmd
};
extern const MHW_ID_ENTRY_PARAMS g_cInit_MhwIdEntryParams =
{
0, // dwMediaIdOffset
0, // iMediaId
0, // dwKernelOffset
0, // dwSamplerOffset
0, // dwSamplerCount
0, // dwBindingTableOffset
0, // iCurbeOffset
0, // iCurbeLength
false, // bBarrierEnable
0, // bGlobalBarrierEnable
0, // dwNumberofThreadsInGPGPUGroup
0, // dwSharedLocalMemorySize
0 // iCrsThdConDataRdLn
};
//!
//! \brief Assigns space in a state heap to a kernel state
//! \details Client facing function to assign as space in a state heap a kernel state;
//! if no space is available, a clean up is attempted
//! \param PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface
//! [in] State heap interface
//! \param MHW_STATE_HEAP_TYPE StateHeapType
//! [in] The state heap type requested (ISH/DSH)
//! \param PMHW_KERNEL_STATE pKernelState
//! [in] Kernel state to which a state heap space will be assigned
//! \param uint32_t dwSpaceRequested
//! [in] The amount of space requested from the state heap
//! \param bool bStatic
//! [in] Whether or not the space requested is static
//! \param bool bZeroAssignedMem
//! [in] Whether or not acquired memory should be zeroed
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, MOS_STATUS_CLIENT_AR_NO_SPACE if no space
//! is available but it is possible for the client to wait, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_AssignSpaceInStateHeap(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_KERNEL_STATE pKernelState,
uint32_t dwSpaceRequested,
bool bStatic,
bool bZeroAssignedMem)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->AssignSpaceInStateHeap(
StateHeapType,
pKernelState,
dwSpaceRequested,
bStatic,
bZeroAssignedMem));
finish:
return eStatus;
}
//!
//! \brief Assigns space in a state heap to a kernel state
//! \details Client facing function to assign as space in a state heap a kernel state;
//! if no space is available, a clean up is attempted
//! \param [in] pCommonStateHeapInterface
//! State heap interface
//! \param [in] pKernelState
//! Kernel state containing all memory blocks to submit
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success
//!
MOS_STATUS Mhw_StateHeapInterface_SubmitBlocks(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_KERNEL_STATE pKernelState)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SubmitBlocks(pKernelState));
finish:
return eStatus;
}
//!
//! \brief Locks requested state heap
//! \details Client facing function to lock a state heap
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param PMHW_STATE_HEAP pStateHeap
//! [in] The state heap to be locked
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success
//!
MOS_STATUS Mhw_StateHeapInterface_LockStateHeap(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_STATE_HEAP pStateHeap)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->LockStateHeap(
pStateHeap));
finish:
return eStatus;
}
//!
//! \brief Unlocks requested state heap
//! \details Client facing function to unlock a state heap
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param PMHW_STATE_HEAP pStateHeap
//! [in] The state heap to be locked
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success
//!
MOS_STATUS Mhw_StateHeapInterface_UnlockStateHeap(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_STATE_HEAP pStateHeap)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->UnLockStateHeap(
pStateHeap));
finish:
return eStatus;
}
//!
//! \brief Allocates a state heap of the requested type
//! \details Client facing function to extend a state heap of the requested time, which
//! involves allocating state heap and added it to the state heap liked list.
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param MHW_STATE_HEAP_TYPE StateHeapType
//! [in] The state heap type requested (ISH/DSH)
//! \param uint32_t dwSizeRequested
//! [in] The size of the state heap
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_ExtendStateHeap(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
MHW_STATE_HEAP_TYPE StateHeapType,
uint32_t dwSizeRequested)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->ExtendStateHeap(
StateHeapType, dwSizeRequested));
finish:
return eStatus;
}
//!
//! \brief Update CmdBufIdGlobal
//! \details Client facing function to update CmdBufIdGlobal
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param PMOS_COMMAND_BUFFER pCmdBuffer
//! [in] The command buffer containing the kernel workload
//! \param void *pvRenderEngineInterface
//! [in] Render engine interface
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_UpdateGlobalCmdBufId(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->UpdateGlobalCmdBufId());
finish:
return eStatus;
}
//!
//! \brief Set command buffer status pointer
//! \details Client facing function to set command buffer status pointer
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param void *pvCmdBufStatus
//! [in] command buffer status pointer
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_SetCmdBufStatusPtr(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
void *pvCmdBufStatus)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetCmdBufStatusPtr(
pvCmdBufStatus));
finish:
return eStatus;
}
//!
//! \brief Calculate the space needed in the SSH
//! \details Client facing function to calculate the space needed in the SSH
//! given the number of binding table entries
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param uint32_t dwBtEntriesRequested
//! [in] Binding table entries requested in the SSH
//! \param uint32_t *pdwSshSize
//! [out] The size needed in the SSH
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_CalculateSshAndBtSizesRequested(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
uint32_t dwBtEntriesRequested,
uint32_t *pdwSshSize,
uint32_t *pdwBtSize)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->CalculateSshAndBtSizesRequested(
dwBtEntriesRequested, pdwSshSize, pdwBtSize));
finish:
return eStatus;
}
//!
//! \brief Request SSH space for a command buffer.
//! \details Client facing function to request SSH space for a command buffer, if not enough
//! space is available, more will be requested.
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param uint32_t dwBtEntriesRequested
//! [in] Binding table entries requested in the SSH
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_RequestSshSpaceForCmdBuf(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
uint32_t dwBtEntriesRequested)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->RequestSshSpaceForCmdBuf(
dwBtEntriesRequested));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SetInterfaceDescriptor (
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
uint32_t dwNumIdsToSet,
PMHW_INTERFACE_DESCRIPTOR_PARAMS pParams)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetInterfaceDescriptor(
dwNumIdsToSet, pParams));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SetInterfaceDescriptorEntry (
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_ID_ENTRY_PARAMS pParams)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetInterfaceDescriptorEntry(
pParams));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SetBindingTable (
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_KERNEL_STATE pKernelState)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetBindingTable(
pKernelState));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SetBindingTableEntry (
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_BINDING_TABLE_PARAMS pParams)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetBindingTableEntry(
pParams));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SendBindingTableEntry (
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_BINDING_TABLE_SEND_PARAMS pParams)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SendBindingTableEntry (
pParams));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SetSurfaceState(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_KERNEL_STATE pKernelState,
PMOS_COMMAND_BUFFER pCmdBuffer,
uint32_t dwNumSurfaceStatesToSet,
PMHW_RCS_SURFACE_PARAMS pParams)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetSurfaceState (
pKernelState,pCmdBuffer, dwNumSurfaceStatesToSet, pParams));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SetSurfaceStateEntry(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
PMHW_SURFACE_STATE_PARAMS pParams)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetSurfaceStateEntry(
pParams));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_InitSamplerStates(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
void *pSampler,
int32_t iSamplers)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->InitSamplerStates(
pSampler,iSamplers));
finish:
return eStatus;
}
MOS_STATUS Mhw_StateHeapInterface_SetSamplerState(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface,
void *pSampler,
PMHW_SAMPLER_STATE_PARAM pParams)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pCommonStateHeapInterface);
MHW_CHK_NULL(pCommonStateHeapInterface->pStateHeapInterface);
MHW_CHK_STATUS(pCommonStateHeapInterface->pStateHeapInterface->SetSamplerState(
pSampler,pParams));
finish:
return eStatus;
}
uint32_t Mhw_StateHeapInterface_DSH_CalculateSpaceNeeded(
PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
{
if (pStateHeapInterface == nullptr)
{
MHW_ASSERTMESSAGE("Invalid Input Parameter");
return 0;
}
else
{
if (pStateHeapInterface->pStateHeapInterface == nullptr)
{
MHW_ASSERTMESSAGE("Invalid Input Parameter");
return 0;
}
}
return pStateHeapInterface->pStateHeapInterface->CalculateSpaceNeededDyn(
StateHeapType, pParams);
}
PMHW_STATE_HEAP_MEMORY_BLOCK Mhw_StateHeapInterface_DSH_AllocateDynamicBlock(
PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
{
if (pStateHeapInterface == nullptr)
{
MHW_ASSERTMESSAGE("Invalid Input Parameter");
return (PMHW_STATE_HEAP_MEMORY_BLOCK)0;
}
else
{
if (pStateHeapInterface->pStateHeapInterface == nullptr)
{
MHW_ASSERTMESSAGE("Invalid Input Parameter");
return (PMHW_STATE_HEAP_MEMORY_BLOCK)0;
}
}
return pStateHeapInterface->pStateHeapInterface->AllocateDynamicBlockDyn(
StateHeapType, pParams);
}
MOS_STATUS Mhw_StateHeapInterface_DSH_SubmitDynamicBlock(
PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_MEMORY_BLOCK pBlock,
FrameTrackerTokenFlat *trackerToken)
{
MHW_CHK_NULL_RETURN(pStateHeapInterface);
MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
return pStateHeapInterface->pStateHeapInterface->SubmitDynamicBlockDyn(
StateHeapType, pBlock, trackerToken);
}
MOS_STATUS Mhw_StateHeapInterface_DSH_FreeDynamicBlock(
PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_MEMORY_BLOCK pBlock)
{
MHW_CHK_NULL_RETURN(pStateHeapInterface);
MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
return pStateHeapInterface->pStateHeapInterface->FreeDynamicBlockDyn(
StateHeapType, pBlock);
}
MOS_STATUS Mhw_StateHeapInterface_DSH_RefreshDynamicHeap (
PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,
MHW_STATE_HEAP_TYPE StateHeapType)
{
MHW_CHK_NULL_RETURN(pStateHeapInterface);
MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
return pStateHeapInterface->pStateHeapInterface->RefreshDynamicHeapDyn(
StateHeapType);
}
MOS_STATUS Mhw_StateHeapInterface_DSH_ReleaseStateHeap(
PMHW_STATE_HEAP_INTERFACE pStateHeapInterface,
PMHW_STATE_HEAP pStateHeap)
{
MHW_CHK_NULL_RETURN(pStateHeapInterface);
MHW_CHK_NULL_RETURN(pStateHeapInterface->pStateHeapInterface);
return pStateHeapInterface->pStateHeapInterface->ReleaseStateHeapDyn(pStateHeap);
}
//!
//! \brief Allocates the state heap interface internal parameters
//! \details Internal MHW function to allocate all parameters needed for the
//! state heap interface
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \param MHW_STATE_HEAP_SETTINGS StateHeapSettings
//! [in] Setting used to initialize the state heap interface
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_Create(
PMHW_STATE_HEAP_INTERFACE *ppStateHeapInterface,
MHW_STATE_HEAP_SETTINGS StateHeapSettings)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(ppStateHeapInterface);
MHW_CHK_NULL(*ppStateHeapInterface);
MHW_CHK_NULL((*ppStateHeapInterface)->pStateHeapInterface);
MHW_CHK_STATUS((*ppStateHeapInterface)->pStateHeapInterface->InitializeInterface(
StateHeapSettings));
finish:
return eStatus;
}
//!
//! \brief Destroys the state heap interface
//! \details Internal MHW function to destroy the state heap interface
//! \param PMHW_STATE_HEAP_INTERFACE pStateHeapInterface
//! [in] State heap interface
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_Destroy(
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
if (pCommonStateHeapInterface)
{
if (pCommonStateHeapInterface->pStateHeapInterface)
{
MOS_Delete(pCommonStateHeapInterface->pStateHeapInterface);
}
MOS_FreeMemory(pCommonStateHeapInterface);
}
return eStatus;
}
//!
//! \brief Initializes the state heap interface
//! \details Internal MHW function to initialize all function pointers and some parameters
//! \param PMHW_STATE_HEAP_INTERFACE* ppStateHeapInterface
//! [in/out] Poitner to state heap interface pointer to be allocated
//! \param PMOS_INTERFACE pOsInterface
//! [in] OS interface
//! \return MOS_STATUS
//! MOS_STATUS_SUCCESS if success, else fail reason
//!
MOS_STATUS Mhw_StateHeapInterface_InitInterface(
PMHW_STATE_HEAP_INTERFACE *ppCommonStateHeapInterface,
PMOS_INTERFACE pOsInterface,
uint8_t bDynamicMode)
{
PMHW_STATE_HEAP_INTERFACE pCommonStateHeapInterface = nullptr;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MhwInterfaces::CreateParams params;
MhwInterfaces *mhwInterfaces = nullptr;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(ppCommonStateHeapInterface);
MHW_CHK_NULL(pOsInterface);
pCommonStateHeapInterface =
(PMHW_STATE_HEAP_INTERFACE)MOS_AllocAndZeroMemory(sizeof(MHW_STATE_HEAP_INTERFACE));
MHW_CHK_NULL(pCommonStateHeapInterface);
//Common Interfaces
pCommonStateHeapInterface->pfnCreate = Mhw_StateHeapInterface_Create;
pCommonStateHeapInterface->pfnDestroy = Mhw_StateHeapInterface_Destroy;
pCommonStateHeapInterface->pfnLockStateHeap = Mhw_StateHeapInterface_LockStateHeap;
pCommonStateHeapInterface->pfnUnlockStateHeap = Mhw_StateHeapInterface_UnlockStateHeap;
pCommonStateHeapInterface->pfnAssignSpaceInStateHeap = Mhw_StateHeapInterface_AssignSpaceInStateHeap;
pCommonStateHeapInterface->pfnSubmitBlocks = Mhw_StateHeapInterface_SubmitBlocks;
pCommonStateHeapInterface->pfnExtendStateHeap = Mhw_StateHeapInterface_ExtendStateHeap;
pCommonStateHeapInterface->pfnUpdateGlobalCmdBufId = Mhw_StateHeapInterface_UpdateGlobalCmdBufId;
pCommonStateHeapInterface->pfnSetCmdBufStatusPtr = Mhw_StateHeapInterface_SetCmdBufStatusPtr;
pCommonStateHeapInterface->pfnRequestSshSpaceForCmdBuf = Mhw_StateHeapInterface_RequestSshSpaceForCmdBuf;
pCommonStateHeapInterface->pfnCalculateSshAndBtSizesRequested = Mhw_StateHeapInterface_CalculateSshAndBtSizesRequested;
//Interfaces in dynamic mode
pCommonStateHeapInterface->pfnCalculateDynamicSpaceNeeded = Mhw_StateHeapInterface_DSH_CalculateSpaceNeeded;
pCommonStateHeapInterface->pfnAllocateDynamicBlock = Mhw_StateHeapInterface_DSH_AllocateDynamicBlock;
pCommonStateHeapInterface->pfnSubmitDynamicBlock = Mhw_StateHeapInterface_DSH_SubmitDynamicBlock;
pCommonStateHeapInterface->pfnFreeDynamicBlock = Mhw_StateHeapInterface_DSH_FreeDynamicBlock;
pCommonStateHeapInterface->pfnRefreshDynamicHeap = Mhw_StateHeapInterface_DSH_RefreshDynamicHeap;
pCommonStateHeapInterface->pfnReleaseStateHeap = Mhw_StateHeapInterface_DSH_ReleaseStateHeap;
//Generic Interfaces
pCommonStateHeapInterface->pfnSetInterfaceDescriptor = Mhw_StateHeapInterface_SetInterfaceDescriptor;
pCommonStateHeapInterface->pfnSetInterfaceDescriptorEntry = Mhw_StateHeapInterface_SetInterfaceDescriptorEntry;
pCommonStateHeapInterface->pfnSetBindingTable = Mhw_StateHeapInterface_SetBindingTable;
pCommonStateHeapInterface->pfnSetSurfaceState = Mhw_StateHeapInterface_SetSurfaceState;
pCommonStateHeapInterface->pfnSetBindingTableEntry = Mhw_StateHeapInterface_SetBindingTableEntry;
pCommonStateHeapInterface->pfnSendBindingTableEntry = Mhw_StateHeapInterface_SendBindingTableEntry;
pCommonStateHeapInterface->pfnSetSurfaceStateEntry = Mhw_StateHeapInterface_SetSurfaceStateEntry;
pCommonStateHeapInterface->pfnInitSamplerStates = Mhw_StateHeapInterface_InitSamplerStates;
pCommonStateHeapInterface->pfnSetSamplerState = Mhw_StateHeapInterface_SetSamplerState;
MOS_ZeroMemory(&params, sizeof(params));
params.Flags.m_stateHeap = true;
params.m_heapMode = bDynamicMode;
mhwInterfaces = MhwInterfaces::CreateFactory(params, pOsInterface);
if (mhwInterfaces)
{
MHW_CHK_NULL(mhwInterfaces->m_stateHeapInterface);
pCommonStateHeapInterface->pStateHeapInterface = mhwInterfaces->m_stateHeapInterface;
// MhwInterfaces always create CP and MI interfaces, so we have to delete those we don't need.
MOS_Delete(mhwInterfaces->m_miInterface);
Delete_MhwCpInterface(mhwInterfaces->m_cpInterface);
mhwInterfaces->m_cpInterface = NULL;
MOS_Delete(mhwInterfaces);
}
else
{
MHW_ASSERTMESSAGE("Allocate MhwInterfaces failed");
eStatus = MOS_STATUS_NO_SPACE;
goto finish;
}
*ppCommonStateHeapInterface = pCommonStateHeapInterface;
finish:
if (eStatus != MOS_STATUS_SUCCESS && pCommonStateHeapInterface)
{
pCommonStateHeapInterface->pfnDestroy(pCommonStateHeapInterface);
*ppCommonStateHeapInterface = nullptr;
}
return eStatus;
}
XMHW_STATE_HEAP_INTERFACE::XMHW_STATE_HEAP_INTERFACE(
PMOS_INTERFACE pInputOSInterface,
int8_t bDynamicMode):
m_pWaTable(nullptr),
m_pdwCmdBufIdGlobal(nullptr),
m_dwCurrCmdBufId(0),
m_pSyncTags(nullptr),
m_dwCurrSyncTag(0),
m_dwInvalidSyncTagId(0),
m_bRegisteredBBCompleteNotifyEvent(false),
m_pInstructionStateHeaps(nullptr),
m_dwNumIsh(0),
m_dwNumDsh(0),
m_pDynamicStateHeaps(nullptr),
m_bDynamicMode(bDynamicMode),
m_pIshBlockManager(nullptr),
m_pDshBlockManager(nullptr),
m_pOsInterface(pInputOSInterface),
m_wIdAlignment(0),
m_wBtIdxAlignment(0),
m_wCurbeAlignment(0),
m_wSizeOfCmdSamplerState(0),
m_dwMaxSurfaceStateSize(0),
m_pfnAddResourceToCmd(nullptr),
m_wSizeOfCmdInterfaceDescriptorData(0)
{
MHW_FUNCTION_ENTER;
MOS_ZeroMemory(&m_resCmdBufIdGlobal, sizeof(m_resCmdBufIdGlobal));
MOS_ZeroMemory(&m_SurfaceStateHeap, sizeof(m_SurfaceStateHeap));
MOS_ZeroMemory(&m_HwSizes, sizeof(m_HwSizes));
MOS_ZeroMemory(&m_StateHeapSettings, sizeof(m_StateHeapSettings));
}
XMHW_STATE_HEAP_INTERFACE::~XMHW_STATE_HEAP_INTERFACE()
{
MHW_FUNCTION_ENTER;
if (m_bDynamicMode == MHW_DGSH_MODE)
{
// heap manager destructors called automatically
return;
}
PMHW_STATE_HEAP pStateHeapPtr, pStateHeapNext;
PMHW_STATE_HEAP_MEMORY_BLOCK pMemBlkPtr, pMemBlkNext;
//Release m_SyncTags
MOS_FreeMemory(m_pSyncTags);
// Destroy all memory block objects and block manager objects for ISH, DSH
if(m_bDynamicMode == MHW_DSH_MODE)
{
MOS_Delete(m_pIshBlockManager);
MOS_Delete(m_pDshBlockManager);
}
//Release m_resCmdBufIdGlobal
if (m_pOsInterface != nullptr)
{
m_pOsInterface->pfnUnlockResource(m_pOsInterface, &m_resCmdBufIdGlobal);
m_pOsInterface->pfnFreeResource(m_pOsInterface, &m_resCmdBufIdGlobal);
}
//Free ISH
pStateHeapPtr = m_pInstructionStateHeaps;
for (uint32_t i = 0; i < m_dwNumIsh; i++)
{
pStateHeapNext = pStateHeapPtr->pNext;
if (m_pOsInterface != nullptr)
{
if (pStateHeapPtr->bKeepLocked)
{
pStateHeapPtr->bKeepLocked = false;
UnLockStateHeap(pStateHeapPtr);
}
m_pOsInterface->pfnFreeResource(m_pOsInterface, &pStateHeapPtr->resHeap);
}
if(m_bDynamicMode == MHW_RENDER_HAL_MODE)
{
pMemBlkPtr = pStateHeapPtr->pMemoryHead;
while (pMemBlkPtr)
{
pMemBlkNext = pMemBlkPtr->pNext;
MOS_FreeMemory(pMemBlkPtr);
pMemBlkPtr = pMemBlkNext;
}
}
MOS_FreeMemory(pStateHeapPtr);
pStateHeapPtr = pStateHeapNext;
}
// Free DSH
pStateHeapPtr = m_pDynamicStateHeaps;
for (uint32_t i = 0; i < m_dwNumDsh; i++)
{
if (pStateHeapPtr == nullptr)
{
break;
}
pStateHeapNext = pStateHeapPtr->pNext;
if (m_pOsInterface != nullptr)
{
if (pStateHeapPtr->bKeepLocked)
{
pStateHeapPtr->bKeepLocked = false;
UnLockStateHeap(pStateHeapPtr);
}
m_pOsInterface->pfnFreeResource(m_pOsInterface, &pStateHeapPtr->resHeap);
}
if(m_bDynamicMode == MHW_RENDER_HAL_MODE)
{
pMemBlkPtr = pStateHeapPtr->pMemoryHead;
while (pMemBlkPtr)
{
pMemBlkNext = pMemBlkPtr->pNext;
MOS_FreeMemory(pMemBlkPtr);
pMemBlkPtr = pMemBlkNext;
}
}
MOS_FreeMemory(pStateHeapPtr);
pStateHeapPtr = pStateHeapNext;
}
return ;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InitializeInterface(
MHW_STATE_HEAP_SETTINGS StateHeapSettings)
{
MOS_ALLOC_GFXRES_PARAMS AllocParams;
MOS_LOCK_PARAMS LockParams;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
//state heap settings
m_StateHeapSettings = StateHeapSettings;
MHW_CHK_NULL(m_pOsInterface);
m_pWaTable = m_pOsInterface->pfnGetWaTable(m_pOsInterface);
if (m_pOsInterface->bUsesGfxAddress)
{
m_pfnAddResourceToCmd = Mhw_AddResourceToCmd_GfxAddress;
}
else if (m_pOsInterface->bUsesPatchList)
{
m_pfnAddResourceToCmd = Mhw_AddResourceToCmd_PatchList;
}
else
{
// No addressing method selected
eStatus = MOS_STATUS_UNKNOWN;
goto finish;
}
if (m_bDynamicMode == MHW_DGSH_MODE)
{
m_ishManager.RegisterOsInterface(m_pOsInterface);
m_ishManager.SetDefaultBehavior(StateHeapSettings.m_ishBehavior);
m_ishManager.SetInitialHeapSize(StateHeapSettings.dwIshSize);
if (StateHeapSettings.m_ishBehavior == HeapManager::Behavior::extend ||
StateHeapSettings.m_ishBehavior == HeapManager::Behavior::destructiveExtend ||
StateHeapSettings.m_ishBehavior == HeapManager::Behavior::waitAndExtend)
{
m_ishManager.SetExtendHeapSize(StateHeapSettings.dwIshIncrement);
}
if (StateHeapSettings.m_keepIshLocked)
{
MHW_MI_CHK_STATUS(m_ishManager.LockHeapsOnAllocate());
}
m_dshManager.RegisterOsInterface(m_pOsInterface);
m_dshManager.SetDefaultBehavior(StateHeapSettings.m_dshBehavior);
m_dshManager.SetInitialHeapSize(StateHeapSettings.dwDshSize);
if (StateHeapSettings.m_dshBehavior == HeapManager::Behavior::extend ||
StateHeapSettings.m_dshBehavior == HeapManager::Behavior::destructiveExtend ||
StateHeapSettings.m_dshBehavior == HeapManager::Behavior::waitAndExtend)
{
m_dshManager.SetExtendHeapSize(StateHeapSettings.dwDshIncrement);
}
if (StateHeapSettings.m_keepDshLocked)
{
MHW_MI_CHK_STATUS(m_dshManager.LockHeapsOnAllocate());
}
return MOS_STATUS_SUCCESS;
}
//Sync tags and sync tag id
m_pSyncTags = (PMHW_SYNC_TAG)MOS_AllocAndZeroMemory(sizeof(MHW_SYNC_TAG) *
StateHeapSettings.dwNumSyncTags);
MHW_CHK_NULL(m_pSyncTags);
if(m_bDynamicMode == MHW_DSH_MODE)
{
m_dwInvalidSyncTagId = 0;
//Allocate block manager for ISH
m_pIshBlockManager = MOS_New(MHW_BLOCK_MANAGER, nullptr);
MHW_CHK_NULL(m_pIshBlockManager);
}
else // m_bDynamicMode == MHW_RENDER_HAL_MODE
{
m_dwInvalidSyncTagId = StateHeapSettings.dwNumSyncTags;
//Extend state heap for DSH
MHW_CHK_STATUS(ExtendStateHeap(
MHW_DSH_TYPE,
StateHeapSettings.dwDshSize));
if (StateHeapSettings.m_keepDshLocked)
{
MHW_CHK_STATUS(LockStateHeap(m_pDynamicStateHeaps));
m_pDynamicStateHeaps->bKeepLocked = true;
}
}
//Allocate resCmdBufIdGlobal
MOS_ZeroMemory(&AllocParams, sizeof(AllocParams));
AllocParams.Type = MOS_GFXRES_BUFFER;
AllocParams.TileType = MOS_TILE_LINEAR;
AllocParams.Format = Format_Buffer;
AllocParams.dwBytes = MHW_CACHELINE_SIZE;
AllocParams.pBufName = "CmdBufIdGlobal";
MHW_CHK_STATUS(m_pOsInterface->pfnAllocateResource(
m_pOsInterface,
&AllocParams,
&m_resCmdBufIdGlobal));
m_dwCurrCmdBufId = 1;
MOS_ZeroMemory(&LockParams, sizeof(LockParams));
LockParams.WriteOnly = 1;
m_pdwCmdBufIdGlobal = (uint32_t*)m_pOsInterface->pfnLockResource(
m_pOsInterface,
&m_resCmdBufIdGlobal,
&LockParams);
MHW_CHK_NULL(m_pdwCmdBufIdGlobal);
MOS_ZeroMemory(m_pdwCmdBufIdGlobal, AllocParams.dwBytes);
m_dwCurrCmdBufId = 1;
//Extend state heap for ISH
MHW_CHK_STATUS(ExtendStateHeap(
MHW_ISH_TYPE,
StateHeapSettings.dwIshSize));
if (StateHeapSettings.m_keepIshLocked)
{
MHW_CHK_NULL(m_pInstructionStateHeaps);
MHW_CHK_STATUS(LockStateHeap(m_pInstructionStateHeaps));
m_pInstructionStateHeaps->bKeepLocked = true;
}
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InitMemoryBlock(
PMHW_STATE_HEAP pStateHeap,
PMHW_STATE_HEAP_MEMORY_BLOCK *ppMemoryBlock,
uint32_t dwRequestedSize,
bool bStatic)
{
PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlock;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_CHK_NULL(ppMemoryBlock);
if (dwRequestedSize > 0)
{
pMemoryBlock = (PMHW_STATE_HEAP_MEMORY_BLOCK)MOS_AllocAndZeroMemory(
sizeof(MHW_STATE_HEAP_MEMORY_BLOCK));
MHW_CHK_NULL(pMemoryBlock);
FrameTrackerTokenFlat_Invalidate(&pMemoryBlock->trackerToken);
pMemoryBlock->dwBlockSize = dwRequestedSize;
pMemoryBlock->pStateHeap = pStateHeap;
pMemoryBlock->bStatic = bStatic;
*ppMemoryBlock = pMemoryBlock;
}
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InsertMemoryBlock(
PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlockFree,
PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlockToAdd)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_CHK_NULL(pMemoryBlockFree);
MHW_CHK_NULL(pMemoryBlockToAdd);
if (pMemoryBlockFree->dwBlockSize < pMemoryBlockToAdd->dwBlockSize)
{
MHW_ASSERTMESSAGE("Free block does not have enough space to contain new block.");
eStatus = MOS_STATUS_NO_SPACE;
goto finish;
}
pMemoryBlockFree->dwBlockSize -= pMemoryBlockToAdd->dwBlockSize;
pMemoryBlockToAdd->dwOffsetInStateHeap =
pMemoryBlockFree->dwOffsetInStateHeap + pMemoryBlockFree->dwBlockSize;
MHW_CHK_STATUS(InsertLinkedList(
pMemoryBlockFree,
pMemoryBlockToAdd));
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::InsertLinkedList(
PMHW_STATE_HEAP_MEMORY_BLOCK pStartNode,
PMHW_STATE_HEAP_MEMORY_BLOCK pNodeToAdd)
{
PMHW_STATE_HEAP_MEMORY_BLOCK pStartNext;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_CHK_NULL(pStartNode);
MHW_CHK_NULL(pNodeToAdd);
pStartNext = pStartNode->pNext;
pStartNode->pNext = pNodeToAdd;
pNodeToAdd->pPrev = pStartNode;
pNodeToAdd->pNext = pStartNext;
if (pStartNext)
{
pStartNext->pPrev = pNodeToAdd;
}
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ReturnSpaceMemoryBlock(
PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlock)
{
PMHW_STATE_HEAP_MEMORY_BLOCK pPrevBlock, pNextBlock;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_CHK_NULL(pMemoryBlock);
if (pMemoryBlock->bStatic)
{
MHW_VERBOSEMESSAGE("Static blocks do not need to be cleaned up.");
goto finish;
}
pPrevBlock = pMemoryBlock->pPrev;
pNextBlock = pMemoryBlock->pNext;
FrameTrackerTokenFlat_Invalidate(&pMemoryBlock->trackerToken);
if (pPrevBlock && !pPrevBlock->bStatic)
{
if (!FrameTrackerTokenFlat_IsValid(&pPrevBlock->trackerToken))
{
pPrevBlock->dwBlockSize += pMemoryBlock->dwBlockSize;
pPrevBlock->pNext = pNextBlock;
if (pNextBlock)
{
pNextBlock->pPrev = pPrevBlock;
}
MOS_FreeMemory(pMemoryBlock);
pMemoryBlock = pPrevBlock;
}
}
if (pNextBlock && !pNextBlock->bStatic)
{
if (!FrameTrackerTokenFlat_IsValid(&pNextBlock->trackerToken))
{
pMemoryBlock->dwBlockSize += pNextBlock->dwBlockSize;
pMemoryBlock->pNext = pNextBlock->pNext;
if (pNextBlock->pNext)
{
pNextBlock->pNext->pPrev = pMemoryBlock;
}
MOS_FreeMemory(pNextBlock);
}
}
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::AssignSpaceInStateHeap(
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_KERNEL_STATE pKernelState,
uint32_t dwSpaceRequested,
bool bStatic,
bool bZeroAssignedMem)
{
MHW_FUNCTION_ENTER;
MHW_MI_CHK_NULL(pKernelState);
HeapManager *heapManager = nullptr;
MemoryBlock *requestedBlock = nullptr;
if (StateHeapType == MHW_ISH_TYPE)
{
heapManager = &m_ishManager;
requestedBlock = &pKernelState->m_ishRegion;
}
else if (StateHeapType == MHW_DSH_TYPE)
{
heapManager = &m_dshManager;
requestedBlock = &pKernelState->m_dshRegion;
}
else if (StateHeapType == MHW_SSH_TYPE)
{
pKernelState->dwSshOffset = m_SurfaceStateHeap.dwCurrOffset;
m_SurfaceStateHeap.dwCurrOffset += pKernelState->dwSshSize;
if (m_SurfaceStateHeap.dwCurrOffset > m_SurfaceStateHeap.dwSize)
{
MHW_ASSERTMESSAGE("Insufficient space requested for SSH");
return MOS_STATUS_NO_SPACE;
}
return MOS_STATUS_SUCCESS;
}
else
{
MHW_ASSERTMESSAGE("Unsupported state heap type.");
return MOS_STATUS_INVALID_PARAMETER;
}
MHW_MI_CHK_NULL(heapManager);
uint32_t spaceNeeded = 0;
MemoryBlockManager::AcquireParams acquireParams =
MemoryBlockManager::AcquireParams(pKernelState->m_currTrackerId, m_blockSizes);
acquireParams.m_staticBlock = bStatic ? true : false;
if (m_blockSizes.empty())
{
m_blockSizes.emplace_back(dwSpaceRequested);
}
else
{
m_blockSizes[0] = dwSpaceRequested;
}
MHW_MI_CHK_STATUS(heapManager->AcquireSpace(
acquireParams,
m_blocks,
spaceNeeded));
if (m_blocks.empty())
{
MHW_ASSERTMESSAGE("No blocks were acquired");
return MOS_STATUS_UNKNOWN;
}
if (!m_blocks[0].IsValid())
{
MHW_ASSERTMESSAGE("No blocks were acquired");
return MOS_STATUS_UNKNOWN;
}
*requestedBlock = m_blocks[0];
if (bZeroAssignedMem)
{
requestedBlock->AddData(nullptr, 0, 0, true);
}
return MOS_STATUS_SUCCESS;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::SubmitBlocks(PMHW_KERNEL_STATE pKernelState)
{
MHW_MI_CHK_NULL(pKernelState);
if (!pKernelState->m_ishRegion.IsStatic())
{
std::vector<MemoryBlock> block;
block.push_back(pKernelState->m_ishRegion);
MHW_MI_CHK_STATUS(m_ishManager.SubmitBlocks(block));
}
if (!pKernelState->m_dshRegion.IsStatic())
{
std::vector<MemoryBlock> block;
block.push_back(pKernelState->m_dshRegion);
MHW_MI_CHK_STATUS(m_dshManager.SubmitBlocks(block));
}
pKernelState->m_currTrackerId = MemoryBlock::m_invalidTrackerId;
return MOS_STATUS_SUCCESS;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::LockStateHeap(
PMHW_STATE_HEAP pStateHeap)
{
PMOS_INTERFACE pOsInterface = nullptr;
MOS_LOCK_PARAMS LockParams;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_CHK_NULL(pStateHeap);
if (pStateHeap->bKeepLocked)
{
MHW_CHK_NULL(pStateHeap->pvLockedHeap);
goto finish;
}
pOsInterface = m_pOsInterface;
MOS_ZeroMemory(&LockParams, sizeof(LockParams));
LockParams.WriteOnly = 1;
LockParams.NoOverWrite = 1;
LockParams.Uncached = 1;
pStateHeap->pvLockedHeap =
pOsInterface->pfnLockResource(pOsInterface, &pStateHeap->resHeap, &LockParams);
MHW_CHK_NULL(pStateHeap->pvLockedHeap);
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::UnLockStateHeap(
PMHW_STATE_HEAP pStateHeap)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_CHK_NULL(pStateHeap);
if (pStateHeap->bKeepLocked)
{
MHW_CHK_NULL(pStateHeap->pvLockedHeap);
goto finish;
}
MHW_CHK_STATUS(m_pOsInterface->pfnUnlockResource(m_pOsInterface, &pStateHeap->resHeap));
pStateHeap->pvLockedHeap = nullptr;
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ExtendStateHeap(
MHW_STATE_HEAP_TYPE StateHeapType,
uint32_t dwSizeRequested)
{
if (m_bDynamicMode == MHW_DSH_MODE)
{
return ExtendStateHeapDyn(StateHeapType,dwSizeRequested);
}
else if (m_bDynamicMode == MHW_RENDER_HAL_MODE)
{
return ExtendStateHeapSta(StateHeapType,dwSizeRequested);
}
else
{
return MOS_STATUS_UNKNOWN;
}
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::UpdateGlobalCmdBufId()
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
m_SurfaceStateHeap.dwCurrOffset = 0;
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::SetCmdBufStatusPtr(void *pvCmdBufStatus)
{
MHW_FUNCTION_ENTER;
MHW_MI_CHK_NULL(pvCmdBufStatus);
m_pdwCmdBufIdGlobal = (uint32_t*)pvCmdBufStatus;
MHW_MI_CHK_STATUS(m_ishManager.RegisterTrackerResource((uint32_t*)m_pdwCmdBufIdGlobal));
MHW_MI_CHK_STATUS(m_dshManager.RegisterTrackerResource((uint32_t*)m_pdwCmdBufIdGlobal));
return MOS_STATUS_SUCCESS;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::RequestSshSpaceForCmdBuf(
uint32_t dwBtEntriesRequested)
{
PMOS_INTERFACE pOsInterface;
PMHW_STATE_HEAP pStateHeap;
MOS_COMMAND_BUFFER CmdBuffer;
uint32_t dwRequestedSshSize = 0, dwBtSize = 0;
uint32_t uiExistingSshSize = 0, uiExistingSshOffset = 0;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
pOsInterface = m_pOsInterface;
pStateHeap = &m_SurfaceStateHeap;
MHW_CHK_NULL(pOsInterface);
MHW_CHK_NULL(pStateHeap);
MHW_CHK_STATUS(pOsInterface->pfnGetIndirectState(
pOsInterface,
&uiExistingSshOffset,
&uiExistingSshSize));
pStateHeap->dwSize = (uint32_t)uiExistingSshSize;
dwBtSize =
MOS_ALIGN_CEIL(dwBtEntriesRequested, m_wBtIdxAlignment);
MHW_CHK_STATUS(CalculateSshAndBtSizesRequested(
dwBtEntriesRequested,
&dwRequestedSshSize,
&dwBtSize));
dwRequestedSshSize = MOS_ALIGN_CEIL(dwRequestedSshSize, (1 << MHW_SSH_BASE_SHIFT));
if (dwRequestedSshSize > pStateHeap->dwSize)
{
MHW_CHK_STATUS(pOsInterface->pfnSetIndirectStateSize(
pOsInterface,
(uint32_t)dwRequestedSshSize));
MOS_ZeroMemory(&CmdBuffer, sizeof(CmdBuffer));
MHW_CHK_STATUS(pOsInterface->pfnGetCommandBuffer(pOsInterface, &CmdBuffer, 0));
MHW_CHK_STATUS(pOsInterface->pfnResetCommandBuffer(pOsInterface, &CmdBuffer));
pOsInterface->pfnReturnCommandBuffer(pOsInterface, &CmdBuffer, 0);
pOsInterface->pfnResetOsStates(pOsInterface);
m_SurfaceStateHeap.dwSize = dwRequestedSshSize;
}
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ExtendStateHeapDyn(
MHW_STATE_HEAP_TYPE StateHeapType,
uint32_t dwSizeRequested)
{
PMHW_STATE_HEAP pNewStateHeap = nullptr;
PMHW_STATE_HEAP *ppStateHeapPtr;
MOS_ALLOC_GFXRES_PARAMS AllocParams;
uint32_t dwNumHeaps;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
PMHW_BLOCK_MANAGER pBlockManager = nullptr;
MEDIA_FEATURE_TABLE *skuTable = nullptr;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(m_pOsInterface);
MHW_CHK_NULL(m_pOsInterface->pfnGetSkuTable);
skuTable = m_pOsInterface->pfnGetSkuTable(m_pOsInterface);
MHW_CHK_NULL(skuTable);
pNewStateHeap = (PMHW_STATE_HEAP)MOS_AllocAndZeroMemory(sizeof(MHW_STATE_HEAP));
MHW_CHK_NULL(pNewStateHeap);
pNewStateHeap->dwSize = MOS_ALIGN_CEIL(dwSizeRequested, MHW_CACHELINE_SIZE);
pNewStateHeap->dwUsed = 0;
pNewStateHeap->dwFree = pNewStateHeap->dwSize;
pNewStateHeap->pMhwStateHeapInterface = this;
MOS_ZeroMemory(&AllocParams, sizeof(AllocParams));
AllocParams.Type = MOS_GFXRES_BUFFER;
AllocParams.TileType = MOS_TILE_LINEAR;
AllocParams.Format = Format_Buffer;
AllocParams.dwBytes = pNewStateHeap->dwSize;
AllocParams.pBufName = "DynamicStateHeap";
if (MEDIA_IS_SKU(skuTable, FtrLimitedLMemBar))
{
AllocParams.dwMemType = MOS_MEMPOOL_SYSTEMMEMORY;
}
MHW_CHK_STATUS(m_pOsInterface->pfnAllocateResource(
m_pOsInterface,
&AllocParams,
&pNewStateHeap->resHeap));
MHW_CHK_STATUS(m_pOsInterface->pfnRegisterResource(m_pOsInterface, &pNewStateHeap->resHeap,
true, true));
if (StateHeapType == MHW_ISH_TYPE)
{
if (m_StateHeapSettings.m_keepIshLocked)
{
MHW_CHK_STATUS(LockStateHeap(pNewStateHeap));
pNewStateHeap->bKeepLocked = true;
}
ppStateHeapPtr = &m_pInstructionStateHeaps;
dwNumHeaps = m_dwNumIsh++;
pBlockManager = m_pIshBlockManager;
}
else
{
if (m_StateHeapSettings.m_keepDshLocked)
{
MHW_CHK_STATUS(LockStateHeap(pNewStateHeap));
pNewStateHeap->bKeepLocked = true;
}
ppStateHeapPtr = &m_pDynamicStateHeaps;
dwNumHeaps = m_dwNumDsh++;
pBlockManager = m_pDshBlockManager;
}
pNewStateHeap->pNext = *ppStateHeapPtr;
*ppStateHeapPtr = pNewStateHeap;
if (pNewStateHeap->pNext) pNewStateHeap->pNext->pPrev = pNewStateHeap;
pBlockManager->SetStateHeap(pNewStateHeap);
// Register new state heap with block manager
pBlockManager->RegisterStateHeap(pNewStateHeap);
finish:
if (eStatus != MOS_STATUS_SUCCESS)
{
if (pNewStateHeap)
{
if (m_pOsInterface)
{
m_pOsInterface->pfnFreeResource(m_pOsInterface, &pNewStateHeap->resHeap);
}
MOS_FreeMemory(pNewStateHeap);
}
}
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ExtendStateHeapSta(
MHW_STATE_HEAP_TYPE StateHeapType,
uint32_t dwSizeRequested)
{
PMOS_INTERFACE pOsInterface = nullptr;
PMHW_STATE_HEAP pNewStateHeap = nullptr, pPrevStateHeap, *ppStateHeapPtr;
MOS_ALLOC_GFXRES_PARAMS AllocParams;
uint32_t i, dwNumHeaps;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
pOsInterface = m_pOsInterface;
MHW_CHK_NULL(pOsInterface);
pNewStateHeap = (PMHW_STATE_HEAP)MOS_AllocAndZeroMemory(sizeof(MHW_STATE_HEAP));
MHW_CHK_NULL(pNewStateHeap);
pNewStateHeap->dwSize = MOS_ALIGN_CEIL(dwSizeRequested, MHW_CACHELINE_SIZE);
MOS_ZeroMemory(&AllocParams, sizeof(AllocParams));
AllocParams.Type = MOS_GFXRES_BUFFER;
AllocParams.TileType = MOS_TILE_LINEAR;
AllocParams.Format = Format_Buffer;
AllocParams.dwBytes = pNewStateHeap->dwSize;
AllocParams.pBufName = "StateHeap";
MHW_CHK_STATUS(pOsInterface->pfnAllocateResource(
pOsInterface,
&AllocParams,
&pNewStateHeap->resHeap));
MHW_CHK_STATUS(InitMemoryBlock(
pNewStateHeap,
&pNewStateHeap->pMemoryHead,
pNewStateHeap->dwSize,
false));
if (StateHeapType == MHW_ISH_TYPE)
{
ppStateHeapPtr = &m_pInstructionStateHeaps;
dwNumHeaps = m_dwNumIsh++;
}
else
{
ppStateHeapPtr = &m_pDynamicStateHeaps;
dwNumHeaps = m_dwNumDsh++;
}
MHW_CHK_NULL(ppStateHeapPtr);
pPrevStateHeap = nullptr;
for (i = 0; i < dwNumHeaps; i++)
{
pPrevStateHeap = *ppStateHeapPtr;
ppStateHeapPtr = &(*ppStateHeapPtr)->pNext;
}
*ppStateHeapPtr = pNewStateHeap;
pNewStateHeap->pPrev = pPrevStateHeap;
finish:
if (eStatus != MOS_STATUS_SUCCESS)
{
if (pNewStateHeap)
{
MOS_FreeMemAndSetNull(pNewStateHeap->pMemoryHead);
if (pOsInterface)
{
pOsInterface->pfnFreeResource(pOsInterface, &pNewStateHeap->resHeap);
}
MOS_FreeMemory(pNewStateHeap);
}
}
return eStatus;
}
uint32_t XMHW_STATE_HEAP_INTERFACE::CalculateSpaceNeededDyn(
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
{
PMHW_STATE_HEAP pStateHeap;
PMHW_BLOCK_MANAGER pBlockManager = nullptr;
uint32_t dwNeeded = 0;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pParams);
MHW_CHK_NULL(pParams->piSizes);
if (pParams->iCount <= 0)
{
goto finish;
}
if (StateHeapType == MHW_ISH_TYPE)
{
MHW_CHK_NULL(m_pInstructionStateHeaps);
pStateHeap = m_pInstructionStateHeaps;
pBlockManager = m_pIshBlockManager;
}
else if (StateHeapType == MHW_DSH_TYPE)
{
MHW_CHK_NULL(m_pDynamicStateHeaps);
pStateHeap = m_pDynamicStateHeaps;
pBlockManager = m_pDshBlockManager;
}
else
{
MHW_ASSERTMESSAGE("Unsupported state heap type.");
eStatus = MOS_STATUS_INVALID_PARAMETER;
goto finish;
}
// Allocate simple block
MHW_CHK_NULL(pBlockManager);
dwNeeded = pBlockManager->CalculateSpaceNeeded((uint32_t*)pParams->piSizes, pParams->iCount,
pParams->dwAlignment, pParams->bHeapAffinity, pParams->pHeapAffinity);
finish:
return dwNeeded;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::CalculateSshAndBtSizesRequested(
uint32_t dwBtEntriesRequested,
uint32_t *pdwSshSize,
uint32_t *pdwBtSize)
{
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pdwSshSize);
MHW_CHK_NULL(pdwBtSize);
dwBtEntriesRequested =
MOS_ALIGN_CEIL(dwBtEntriesRequested, m_wBtIdxAlignment);
*pdwBtSize = dwBtEntriesRequested * m_HwSizes.dwSizeBindingTableState;
*pdwSshSize =
(*pdwBtSize) + (dwBtEntriesRequested * m_dwMaxSurfaceStateSize);
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::ReleaseStateHeapDyn(
PMHW_STATE_HEAP pStateHeap)
{
PMHW_STATE_HEAP pFirstHeap;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pStateHeap);
MHW_CHK_NULL(pStateHeap->pBlockManager);
// Mark state heap for deletion (so size is not accounted for)
pStateHeap->bDeleted = true;
// Mark blocks for deletion, release heap when all blocks are released
eStatus = pStateHeap->pBlockManager->UnregisterStateHeap(pStateHeap);
if (eStatus != MOS_STATUS_SUCCESS)
{
// The only reason for this condition is in case some blocks are still in submitted state
// The block manager will call this function from within when the last block is released
// In the meantime, this heap will not contain any free blocks for allocation
eStatus = MOS_STATUS_SUCCESS;
goto finish;
}
// Find first heap of the chain (so we can figure out if its DSH or ISH!)
for (pFirstHeap = pStateHeap; pFirstHeap->pPrev != nullptr; pFirstHeap = pFirstHeap->pPrev) ;
// Detach heap from chain
if (pStateHeap->pPrev)
{
pStateHeap->pPrev->pNext = pStateHeap->pNext;
}
if (pStateHeap->pNext)
{
pStateHeap->pNext->pPrev = pStateHeap->pPrev;
}
// Update heaps
if (pFirstHeap == m_pDynamicStateHeaps)
{
m_dwNumDsh--;
if (pStateHeap == m_pDynamicStateHeaps)
{
m_pDynamicStateHeaps = pStateHeap->pNext;
m_pDshBlockManager->SetStateHeap(pStateHeap->pNext);
}
}
else if (pFirstHeap == m_pInstructionStateHeaps)
{
m_dwNumIsh--;
if (pStateHeap == m_pInstructionStateHeaps)
{
m_pInstructionStateHeaps = pStateHeap->pNext;
m_pIshBlockManager->SetStateHeap(pStateHeap->pNext);
}
}
// Unlock heap
if (pStateHeap->bKeepLocked)
{
pStateHeap->bKeepLocked = false;
UnLockStateHeap(pStateHeap);
}
// Free OS resource
MHW_CHK_NULL(m_pOsInterface);
m_pOsInterface->pfnFreeResource(m_pOsInterface, &pStateHeap->resHeap);
// Free MHW State Heap structure
MOS_FreeMemory(pStateHeap);
finish:
return eStatus;
}
PMHW_STATE_HEAP_MEMORY_BLOCK XMHW_STATE_HEAP_INTERFACE::AllocateDynamicBlockDyn(
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_DYNAMIC_ALLOC_PARAMS pParams)
{
PMHW_STATE_HEAP *ppStateHeap;
PMHW_BLOCK_MANAGER pBlockManager = nullptr;
PMHW_STATE_HEAP_MEMORY_BLOCK pMemoryBlock = nullptr;
PMHW_STATE_HEAP_MEMORY_BLOCK pAuxBlock;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
uint32_t dwMinSize, dwIncrement, dwMaxSize;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pParams);
MHW_CHK_NULL(pParams->piSizes);
MHW_ASSERT(pParams->iCount > 0);
if (StateHeapType == MHW_ISH_TYPE)
{
ppStateHeap = &m_pInstructionStateHeaps;
pBlockManager = m_pIshBlockManager;
dwMinSize = m_StateHeapSettings.dwIshSize;
dwIncrement = m_StateHeapSettings.dwIshIncrement;
dwMaxSize = m_StateHeapSettings.dwIshMaxSize;
}
else if (StateHeapType == MHW_DSH_TYPE)
{
ppStateHeap = &m_pDynamicStateHeaps;
pBlockManager = m_pDshBlockManager;
dwMinSize = m_StateHeapSettings.dwDshSize;
dwIncrement = m_StateHeapSettings.dwDshIncrement;
dwMaxSize = m_StateHeapSettings.dwDshMaxSize;
}
else
{
MHW_ASSERTMESSAGE("Unsupported state heap type.");
eStatus = MOS_STATUS_INVALID_PARAMETER;
goto finish;
}
do
{
// Allocate simple block
MHW_CHK_NULL(pBlockManager);
if (pParams->iCount == 1)
{
if (pParams->dwScratchSpace == 0 )
{
pMemoryBlock = pBlockManager->AllocateBlock((uint32_t)pParams->piSizes[0],
pParams->dwAlignment,
pParams->pHeapAffinity);
}
else
{
pMemoryBlock = pBlockManager->AllocateWithScratchSpace(
(uint32_t)pParams->piSizes[0],
pParams->dwAlignment,
pParams->dwScratchSpace);
}
if (pMemoryBlock)
{
pParams->pScratchSpace = pMemoryBlock->pStateHeap->pScratchSpace;
pParams->dwScratchSpace = pMemoryBlock->pStateHeap->dwScratchSpace;
}
}
else
{
pMemoryBlock = pBlockManager->AllocateMultiple( (uint32_t*)pParams->piSizes,
pParams->iCount,
pParams->dwAlignment,
pParams->bHeapAffinity,
pParams->pHeapAffinity);
}
// Allocation failed
if (!pMemoryBlock)
{
uint32_t dwTotalSize = 0;
// Do not allow heap to grow automatically
// Note: Caller may try to clean up the heap, wait or implement a different heap expansion logic
if (!pParams->bGrow)
{
break;
}
// Calculate size of all heaps (do not account heaps already being removed)
for (PMHW_STATE_HEAP pStateHeap = *ppStateHeap; pStateHeap; pStateHeap = pStateHeap->pNext)
{
if (!pStateHeap->bDeleted)
{
dwTotalSize += pStateHeap->dwSize;
}
}
// Did not reach heap size limit - calculate increment to fit all allocations + scratch space (if GSH)
uint32_t dwExtendSize = 0;
if (dwTotalSize < dwMaxSize)
{
for (int32_t i = 0; i < pParams->iCount; i++)
{
dwExtendSize += MOS_ALIGN_CEIL(pParams->piSizes[i], pParams->dwAlignment);
}
dwExtendSize = MOS_ALIGN_CEIL(dwExtendSize, dwIncrement);
dwExtendSize = MOS_ALIGN_CEIL(dwExtendSize + pParams->dwScratchSpace, dwIncrement);
dwExtendSize = MOS_MAX(dwExtendSize, dwMinSize);
ExtendStateHeap(StateHeapType, dwExtendSize);
}
else
{
break;
}
}
} while (pMemoryBlock == nullptr);
// Zero memory blocks
pAuxBlock = pMemoryBlock;
for (int32_t i = pParams->iCount; (pAuxBlock != nullptr) && (i > 0); i--, pAuxBlock = pAuxBlock->pNext)
{
// Set block static flag
pAuxBlock->bStatic = pParams->bStatic;
// Erase block contents
if (pParams->bZeroAssignedMem)
{
MHW_CHK_STATUS(LockStateHeap(pAuxBlock->pStateHeap));
MOS_ZeroMemory(pAuxBlock->pDataPtr - pAuxBlock->dwAlignment, pAuxBlock->dwBlockSize);
MHW_CHK_STATUS(UnLockStateHeap(pAuxBlock->pStateHeap));
}
}
finish:
// Failed - release memory blocks back to "Free" queue
if (eStatus != MOS_STATUS_SUCCESS && pBlockManager != nullptr)
{
// Something went wrong - release blocks if already allocated
for (; pMemoryBlock != nullptr; pMemoryBlock = pAuxBlock)
{
pAuxBlock = pMemoryBlock->pNext; // Get next block (must be done before Mhw_BlockManager_Free)
pBlockManager->FreeBlock(pMemoryBlock); // Release block back to "Free" queue
}
}
return pMemoryBlock;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::SubmitDynamicBlockDyn(
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_MEMORY_BLOCK pBlock,
const FrameTrackerTokenFlat *trakcerToken)
{
PMHW_BLOCK_MANAGER pBlockManager = nullptr;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pBlock);
if (StateHeapType == MHW_ISH_TYPE)
{
pBlockManager = m_pIshBlockManager;
}
else if (StateHeapType == MHW_DSH_TYPE)
{
pBlockManager = m_pDshBlockManager;
}
else
{
MHW_ASSERTMESSAGE("Unsupported state heap type.");
eStatus = MOS_STATUS_INVALID_PARAMETER;
goto finish;
}
// Submit block
MHW_CHK_NULL(pBlockManager);
MHW_CHK_STATUS(pBlockManager->SubmitBlock(pBlock, trakcerToken));
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::FreeDynamicBlockDyn(
MHW_STATE_HEAP_TYPE StateHeapType,
PMHW_STATE_HEAP_MEMORY_BLOCK pBlock)
{
PMHW_BLOCK_MANAGER pBlockManager = nullptr;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
MHW_CHK_NULL(pBlock);
if (StateHeapType == MHW_ISH_TYPE)
{
pBlockManager = m_pIshBlockManager;
}
else if (StateHeapType == MHW_DSH_TYPE)
{
pBlockManager = m_pDshBlockManager;
}
else
{
MHW_ASSERTMESSAGE("Unsupported state heap type.");
eStatus = MOS_STATUS_INVALID_PARAMETER;
goto finish;
}
// Free block
MHW_CHK_STATUS(pBlockManager->FreeBlock(pBlock));
finish:
return eStatus;
}
MOS_STATUS XMHW_STATE_HEAP_INTERFACE::RefreshDynamicHeapDyn (
MHW_STATE_HEAP_TYPE StateHeapType)
{
PMHW_BLOCK_MANAGER pBlockManager = nullptr;
MOS_STATUS eStatus = MOS_STATUS_SUCCESS;
MHW_FUNCTION_ENTER;
if (StateHeapType == MHW_ISH_TYPE)
{
pBlockManager = m_pIshBlockManager;
}
else if (StateHeapType == MHW_DSH_TYPE)
{
pBlockManager = m_pDshBlockManager;
}
else
{
MHW_ASSERTMESSAGE("Unsupported state heap type.");
eStatus = MOS_STATUS_INVALID_PARAMETER;
goto finish;
}
// Free block
MHW_CHK_NULL(pBlockManager)
MHW_CHK_STATUS(pBlockManager->Refresh());
finish:
return eStatus;
}