diff --git a/media_common/agnostic/common/renderhal/media_srcs.cmake b/media_common/agnostic/common/renderhal/media_srcs.cmake index 821a1c2ac7..f17c7baa1d 100644 --- a/media_common/agnostic/common/renderhal/media_srcs.cmake +++ b/media_common/agnostic/common/renderhal/media_srcs.cmake @@ -21,6 +21,7 @@ set(TMP_HEADERS_ ${CMAKE_CURRENT_LIST_DIR}/renderhal.h ${CMAKE_CURRENT_LIST_DIR}/renderhal_platform_interface.h + ${CMAKE_CURRENT_LIST_DIR}/surface_state_heap_mgr.h ) set(SOFTLET_COMMON_HEADERS_ diff --git a/media_common/agnostic/common/renderhal/renderhal.h b/media_common/agnostic/common/renderhal/renderhal.h index d08ea74e10..1edd60448e 100644 --- a/media_common/agnostic/common/renderhal/renderhal.h +++ b/media_common/agnostic/common/renderhal/renderhal.h @@ -38,6 +38,7 @@ #include "media_perf_profiler.h" #include "frame_tracker.h" #include "media_common_defs.h" +#include "surface_state_heap_mgr.h" class XRenderHal_Platform_Interface; @@ -966,7 +967,7 @@ typedef struct _RENDERHAL_STATE_HEAP RENDERHAL_KRN_ALLOC_LIST KernelAllocationPool; // Pool of kernel allocation objects RENDERHAL_KRN_ALLOC_LIST KernelsSubmitted; // Kernel submission list RENDERHAL_KRN_ALLOC_LIST KernelsAllocated; // kernel allocation list (kernels in ISH not currently being executed) - + SurfaceStateHeapManager *surfaceStateMgr; // Surface state manager } RENDERHAL_STATE_HEAP, *PRENDERHAL_STATE_HEAP; typedef struct _RENDERHAL_DYNAMIC_MEDIA_STATE_PARAMS @@ -1371,6 +1372,13 @@ typedef struct _RENDERHAL_INTERFACE PRENDERHAL_INTERFACE pRenderHal, int32_t *piBindingTable); + MOS_STATUS (* pfnAssignBindlessSurfaceStates) ( + PRENDERHAL_INTERFACE pRenderHal); + + MOS_STATUS (*pfnSendBindlessSurfaceStates) ( + PRENDERHAL_INTERFACE pRenderHal, + bool bNeedNullPatch); + MOS_STATUS (* pfnBindSurfaceState) ( PRENDERHAL_INTERFACE pRenderHal, int32_t iBindingTableIndex, diff --git a/media_common/agnostic/common/renderhal/surface_state_heap_mgr.h b/media_common/agnostic/common/renderhal/surface_state_heap_mgr.h new file mode 100644 index 0000000000..f466108ec3 --- /dev/null +++ b/media_common/agnostic/common/renderhal/surface_state_heap_mgr.h @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2024, 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 surface_state_heap_mgr.h +//! \brief Render Engine Interfaces shared across platforms +//! \details Platform Independent Hardware Interfaces +//! +#ifndef __SURFACE_STATE_HEAP_MGR_H__ +#define __SURFACE_STATE_HEAP_MGR_H__ + +#include +#include "mos_os.h" +#include "mhw_utilities.h" +#include "mos_os_specific.h" +#include "mos_interface.h" +#include + +#define MAX_SURFACE_STATES 512 +using SURF_STATES_LIST = std::vector; +//! +//! \brief Default size of area for sync, debugging, performance collecting +//! +#define SYNC_SIZE 128 // range: (128 ... 4096) + +//! +//! \brief VEBOX Heap State Structure +//! +typedef struct _SURFACE_STATES_OBJ +{ + bool bBusy; // true if the state is in use (must sync before use) + uint32_t dwSyncTag; // surface heap state sync tag +} SURFACE_STATES_OBJ, *PSURFACE_STATES_OBJ; + +typedef struct _SURFACE_STATES_HEAP_OBJ +{ + uint32_t uiCurState; // Current surface State + uint32_t uiNextState; // Next surface State + uint32_t uiOffsetSync; // Offset of sync data in Heap + uint32_t uiInstanceSize; // Size of single instance + uint32_t uiStateHeapSize; // Total size of Surface States heap + PSURFACE_STATES_OBJ pSurfStateObj; // Array of SURFACE_STATES_SYNC_OBJ + MOS_RESOURCE osResource; // Graphics memory + uint8_t *pLockedOsResourceMem; // Locked resource memory + + // Synchronization + volatile uint32_t *pSync; // Pointer to sync area (when locked) + uint32_t dwNextTag; // Next sync tag value to use + uint32_t dwSyncTag; // Last sync tag completed +} SURFACE_STATES_HEAP_OBJ, *PSURFACE_STATES_HEAP_OBJ; + +class SurfaceStateHeapManager +{ +public: + SurfaceStateHeapManager(PMOS_INTERFACE pOsInterface); + MOS_STATUS CreateHeap(size_t surfStateSize); + + void RefreshSync(); + + MOS_STATUS DestroyHeap(); + + MOS_STATUS AssignSurfaceState(); + + MOS_STATUS AssignUsedSurfaceState(int32_t index) + { + m_usedStates.push_back(index); + return MOS_STATUS_SUCCESS; + } + + ~SurfaceStateHeapManager(); + +public: + PMOS_INTERFACE m_osInterface = nullptr; + SURFACE_STATES_HEAP_OBJ *m_surfStateHeap = nullptr; + int m_surfHeapInUse = 0; + SURF_STATES_LIST m_usedStates = {}; +}; + +#endif // __SURFACE_STATE_HEAP_MGR_H__ \ No newline at end of file diff --git a/media_driver/linux/common/renderhal/renderhal_linux.cpp b/media_driver/linux/common/renderhal/renderhal_linux.cpp index e2393e02cf..321de66b20 100644 --- a/media_driver/linux/common/renderhal/renderhal_linux.cpp +++ b/media_driver/linux/common/renderhal/renderhal_linux.cpp @@ -176,6 +176,13 @@ MOS_STATUS RenderHal_SendSurfaces_PatchList( pOsInterface = pRenderHal->pOsInterface; iSurfacesPerBT = pRenderHal->StateHeapSettings.iSurfacesPerBT; + if (pRenderHal->isBindlessHeapInUse) + { + bool bNeedNullPatch = MEDIA_IS_SKU(pOsInterface->pfnGetSkuTable(pOsInterface), FtrMediaPatchless); + MHW_RENDERHAL_CHK_STATUS_RETURN(pRenderHal->pfnSendBindlessSurfaceStates(pRenderHal, bNeedNullPatch)); + return MOS_STATUS_SUCCESS; + } + // 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; diff --git a/media_softlet/agnostic/common/renderhal/media_srcs.cmake b/media_softlet/agnostic/common/renderhal/media_srcs.cmake index 33eb9908da..cb8693f35a 100644 --- a/media_softlet/agnostic/common/renderhal/media_srcs.cmake +++ b/media_softlet/agnostic/common/renderhal/media_srcs.cmake @@ -21,12 +21,12 @@ set(TMP_SOURCES_ ${CMAKE_CURRENT_LIST_DIR}/renderhal.cpp ${CMAKE_CURRENT_LIST_DIR}/renderhal_platform_interface_next.cpp + ${CMAKE_CURRENT_LIST_DIR}/surface_state_heap_mgr.cpp ) set(TMP_HEADERS ${CMAKE_CURRENT_LIST_DIR}/renderhal_platform_interface_next.h ${CMAKE_CURRENT_LIST_DIR}/hal_oca_interface_next.h - ) diff --git a/media_softlet/agnostic/common/renderhal/renderhal.cpp b/media_softlet/agnostic/common/renderhal/renderhal.cpp index a45993228b..973630c113 100644 --- a/media_softlet/agnostic/common/renderhal/renderhal.cpp +++ b/media_softlet/agnostic/common/renderhal/renderhal.cpp @@ -1405,26 +1405,40 @@ MOS_STATUS RenderHal_AllocateStateHeaps( pStateHeap->iCurrentBindingTable = 0; pStateHeap->iCurrentSurfaceState = 0; - // Set BT sizes - pStateHeap->iBindingTableSize = MOS_ALIGN_CEIL(pSettings->iSurfacesPerBT * pHwSizes->dwSizeBindingTableState, - pSettings->iBTAlignment); + if (pRenderHal->isBindlessHeapInUse == false) + { + // Set BT sizes + pStateHeap->iBindingTableSize = MOS_ALIGN_CEIL(pSettings->iSurfacesPerBT * pHwSizes->dwSizeBindingTableState, + pSettings->iBTAlignment); - // Set offsets to BT and SS entries - pStateHeap->iBindingTableOffset = 0; - pStateHeap->iSurfaceStateOffset = pSettings->iBindingTables * pStateHeap->iBindingTableSize; + // Set offsets to BT and SS entries + pStateHeap->iBindingTableOffset = 0; + pStateHeap->iSurfaceStateOffset = pSettings->iBindingTables * pStateHeap->iBindingTableSize; - // Calculate size of a single SSH instance and total SSH buffer size - dwSizeSSH = pStateHeap->iSurfaceStateOffset + - pSettings->iSurfaceStates * pRenderHal->pRenderHalPltInterface->GetSurfaceStateCmdSize(); - pStateHeap->dwSshIntanceSize = dwSizeSSH; - pRenderHal->dwIndirectHeapSize = MOS_ALIGN_CEIL(dwSizeSSH, MHW_PAGE_SIZE); + // Calculate size of a single SSH instance and total SSH buffer size + dwSizeSSH = pStateHeap->iSurfaceStateOffset + + pSettings->iSurfaceStates * pRenderHal->pRenderHalPltInterface->GetSurfaceStateCmdSize(); + pStateHeap->dwSshIntanceSize = dwSizeSSH; + pRenderHal->dwIndirectHeapSize = MOS_ALIGN_CEIL(dwSizeSSH, MHW_PAGE_SIZE); + + // Allocate SSH buffer in system memory, not Gfx + pStateHeap->dwSizeSSH = dwSizeSSH; // Single SSH instance + pStateHeap->pSshBuffer = (uint8_t *)MOS_AllocAndZeroMemory(dwSizeSSH); + } + else + { + if (!pStateHeap->surfaceStateMgr) + { + pStateHeap->surfaceStateMgr = MOS_New(SurfaceStateHeapManager, pRenderHal->pOsInterface); + MHW_RENDERHAL_CHK_NULL_RETURN(pStateHeap->surfaceStateMgr); + MHW_RENDERHAL_CHK_STATUS_RETURN(pStateHeap->surfaceStateMgr->CreateHeap(pRenderHal->pRenderHalPltInterface->GetSurfaceStateCmdSize())); + pStateHeap->iCurrentSurfaceState = pStateHeap->surfaceStateMgr->m_surfStateHeap->uiCurState; + } + } - // Allocate SSH buffer in system memory, not Gfx - pStateHeap->dwSizeSSH = dwSizeSSH; // Single SSH instance - pStateHeap->pSshBuffer = (uint8_t*)MOS_AllocAndZeroMemory(dwSizeSSH); do { - if (!pStateHeap->pSshBuffer) + if (pStateHeap->dwSizeSSH > 0 && !pStateHeap->pSshBuffer) { MHW_RENDERHAL_ASSERTMESSAGE("Fail to Allocate SSH buffer."); eStatus = MOS_STATUS_NO_SPACE; @@ -1784,6 +1798,12 @@ MOS_STATUS RenderHal_FreeStateHeaps(PRENDERHAL_INTERFACE pRenderHal) pStateHeap->pSshBuffer = nullptr; } + if (pStateHeap->surfaceStateMgr) + { + MOS_Delete(pStateHeap->surfaceStateMgr); + pStateHeap->surfaceStateMgr = nullptr; + } + // Free MOS surface in surface state entry for (int32_t index = 0; index < pRenderHal->StateHeapSettings.iSurfaceStates; ++index) { PRENDERHAL_SURFACE_STATE_ENTRY entry = pStateHeap->pSurfaceEntry + index; @@ -2956,20 +2976,43 @@ MOS_STATUS RenderHal_AssignSurfaceState( eStatus = MOS_STATUS_UNKNOWN; pStateHeap = pRenderHal->pStateHeap; - if (pStateHeap->iCurrentSurfaceState >= pRenderHal->StateHeapSettings.iSurfaceStates) + uint8_t *pCurSurfaceState; + // Calculate the Offset to the Surface State + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pRenderHalPltInterface); + + if (pRenderHal->isBindlessHeapInUse == false) { - MHW_RENDERHAL_ASSERTMESSAGE("Unable to allocate Surface State. Exceeds Maximum."); - return eStatus; + if (pStateHeap->iCurrentSurfaceState >= pRenderHal->StateHeapSettings.iSurfaceStates) + { + MHW_RENDERHAL_ASSERTMESSAGE("Unable to allocate Surface State. Exceeds Maximum."); + return eStatus; + } + + dwOffset = pStateHeap->iSurfaceStateOffset + + (pStateHeap->iCurrentSurfaceState * + pRenderHal->pRenderHalPltInterface->GetSurfaceStateCmdSize()); // Moves the pointer to a Currently assigned Surface State + // Increment the Current Surface State Entry + // Obtain new surface entry and initialize + iSurfaceEntry = pStateHeap->iCurrentSurfaceState; + pCurSurfaceState = pStateHeap->pSshBuffer + dwOffset; + ++pStateHeap->iCurrentSurfaceState; } + else + { + MHW_RENDERHAL_CHK_NULL_RETURN(pStateHeap->surfaceStateMgr); + MHW_RENDERHAL_CHK_STATUS_RETURN(pStateHeap->surfaceStateMgr->AssignSurfaceState()); + SURFACE_STATES_HEAP_OBJ *sufStateHeap = pStateHeap->surfaceStateMgr->m_surfStateHeap; + MHW_RENDERHAL_CHK_NULL_RETURN(sufStateHeap); + MHW_RENDERHAL_CHK_NULL_RETURN(sufStateHeap->pLockedOsResourceMem); + dwOffset = sufStateHeap->uiCurState * sufStateHeap->uiInstanceSize; + pCurSurfaceState =sufStateHeap->pLockedOsResourceMem + dwOffset; + pStateHeap->iCurrentSurfaceState = sufStateHeap->uiCurState; - // Calculate the Offset to the Surface State - MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pRenderHalPltInterface); - dwOffset = pStateHeap->iSurfaceStateOffset + - (pStateHeap->iCurrentSurfaceState * - pRenderHal->pRenderHalPltInterface->GetSurfaceStateCmdSize()); // Moves the pointer to a Currently assigned Surface State + MHW_RENDERHAL_CHK_STATUS_RETURN(pStateHeap->surfaceStateMgr->AssignUsedSurfaceState(pStateHeap->iCurrentSurfaceState)); + // Obtain new surface entry and initialize + iSurfaceEntry = pStateHeap->iCurrentSurfaceState; + } - // Obtain new surface entry and initialize - iSurfaceEntry = pStateHeap->iCurrentSurfaceState; pSurfaceEntry = &pStateHeap->pSurfaceEntry[iSurfaceEntry]; if (pSurfaceEntry->pSurface) { @@ -2982,7 +3025,7 @@ MOS_STATUS RenderHal_AssignSurfaceState( pSurfaceEntry->iSurfStateID = iSurfaceEntry; pSurfaceEntry->Type = Type; pSurfaceEntry->dwSurfStateOffset = (uint32_t)-1; // Each platform to setup - pSurfaceEntry->pSurfaceState = pStateHeap->pSshBuffer + dwOffset; + pSurfaceEntry->pSurfaceState = pCurSurfaceState; pSurfaceEntry->pSurface = (PMOS_SURFACE)MOS_AllocAndZeroMemory(sizeof(MOS_SURFACE)); if (pSurfaceEntry->pSurface == nullptr) { @@ -2993,9 +3036,6 @@ MOS_STATUS RenderHal_AssignSurfaceState( *ppSurfaceEntry = pSurfaceEntry; - // Increment the Current Surface State Entry - ++pStateHeap->iCurrentSurfaceState; - eStatus = MOS_STATUS_SUCCESS; return eStatus; @@ -4991,6 +5031,13 @@ MOS_STATUS RenderHal_AssignSshInstance( eStatus = MOS_STATUS_SUCCESS; pStateHeap = pRenderHal->pStateHeap; + if (pRenderHal->isBindlessHeapInUse) + { + MHW_RENDERHAL_NORMALMESSAGE("BindlessHeap does not need SSH Instance!"); + MHW_RENDERHAL_CHK_STATUS_RETURN(pRenderHal->pfnAssignBindlessSurfaceStates(pRenderHal)); + return eStatus; + } + // Init SSH Params if (pStateHeap) { @@ -5558,6 +5605,69 @@ MOS_STATUS RenderHal_SendMediaStates( return eStatus; } +MOS_STATUS RenderHal_AssignBindlessSurfaceStates( + PRENDERHAL_INTERFACE pRenderHal) +{ + PRENDERHAL_STATE_HEAP pStateHeap = nullptr; + MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; + + //---------------------------------------- + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal); + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pStateHeap); + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pStateHeap->surfaceStateMgr); + + pStateHeap = pRenderHal->pStateHeap; + if (pStateHeap->surfaceStateMgr->m_usedStates.size() >0) + { + pStateHeap->surfaceStateMgr->m_usedStates.clear(); + } + + eStatus = MOS_STATUS_SUCCESS; + + return eStatus; +} + +MOS_STATUS RenderHal_SendSurfaces_Bindelss( + PRENDERHAL_INTERFACE pRenderHal, + bool bNeedNullPatch) +{ + PRENDERHAL_STATE_HEAP pStateHeap = nullptr; + MOS_STATUS eStatus = MOS_STATUS_SUCCESS; + MHW_SURFACE_STATE_SEND_PARAMS SendSurfaceParams; + PMOS_INTERFACE pOsInterface; + //---------------------------------------- + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal); + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pStateHeap); + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pStateHeap->surfaceStateMgr); + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pStateHeap->surfaceStateMgr->m_surfStateHeap); + MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pOsInterface); + + pStateHeap = pRenderHal->pStateHeap; + pOsInterface = pRenderHal->pOsInterface; + + if (pStateHeap->surfaceStateMgr->m_usedStates.size() == 0) + { + MHW_RENDERHAL_NORMALMESSAGE("m_usedStates is null!"); + return eStatus; + } + + for (uint32_t i = 0; i < pStateHeap->surfaceStateMgr->m_usedStates.size(); i++) + { + uint32_t index = pStateHeap->surfaceStateMgr->m_usedStates[i]; + // Null Patch is only enabled for Media Patchless + SendSurfaceParams.bNeedNullPatch = bNeedNullPatch; + SendSurfaceParams.pIndirectStateBase = pStateHeap->surfaceStateMgr->m_surfStateHeap->pLockedOsResourceMem; + SendSurfaceParams.iIndirectStateBase = 0; // No need + + SendSurfaceParams.pSurfaceToken = (uint8_t *)&pStateHeap->pSurfaceEntry[index].SurfaceToken; + SendSurfaceParams.pSurfaceStateSource = (uint8_t *)pStateHeap->pSurfaceEntry[index].pSurfaceState; + SendSurfaceParams.iSurfaceStateOffset = index * pStateHeap->surfaceStateMgr->m_surfStateHeap->uiInstanceSize; + pRenderHal->pfnSendSurfaceStateEntry(pRenderHal, nullptr, &SendSurfaceParams); + } + + return eStatus; +} + //! //! \brief Assign binding Table //! \details Assigns binding Table @@ -5586,6 +5696,12 @@ MOS_STATUS RenderHal_AssignBindingTable( pStateHeap = pRenderHal->pStateHeap; eStatus = MOS_STATUS_UNKNOWN; + if (pRenderHal->isBindlessHeapInUse) + { + MHW_RENDERHAL_NORMALMESSAGE("BindlessHeap does not need binding table!"); + return MOS_STATUS_SUCCESS; + } + if (pStateHeap->iCurrentBindingTable >= pRenderHal->StateHeapSettings.iBindingTables) { MHW_RENDERHAL_ASSERTMESSAGE("Unable to allocate Binding Table. Exceeds Maximum."); @@ -5677,9 +5793,17 @@ MOS_STATUS RenderHal_SetupBufferSurfaceState( // Update surface state offset in SSH *pSurfaceEntry->pSurface = pRenderHalSurface->OsSurface; - pSurfaceEntry->dwSurfStateOffset = + + if (pRenderHal->isBindlessHeapInUse) + { + pSurfaceEntry->dwSurfStateOffset = pSurfaceEntry->iSurfStateID * pRenderHal->pHwSizes->dwSizeSurfaceState; // No binding table + } + else + { + pSurfaceEntry->dwSurfStateOffset = pRenderHal->pStateHeap->iSurfaceStateOffset + pSurfaceEntry->iSurfStateID * pRenderHal->pHwSizes->dwSizeSurfaceState; + } // Setup MHW parameters MOS_ZeroMemory(&RcsSurfaceParams, sizeof(MHW_RCS_SURFACE_PARAMS)); @@ -6972,9 +7096,19 @@ MOS_STATUS RenderHal_SendSurfaceStateEntry( //----------------------------------------------- MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal); MHW_RENDERHAL_CHK_NULL_RETURN(pRenderHal->pOsInterface); - MHW_RENDERHAL_CHK_NULL_RETURN(pCmdBuffer); MHW_RENDERHAL_CHK_NULL_RETURN(pParams); //----------------------------------------------- + uint8_t *pbPtrCmdBuf; + if (pRenderHal->isBindlessHeapInUse) + { + MHW_RENDERHAL_CHK_NULL_RETURN(pParams->pIndirectStateBase); + pbPtrCmdBuf = pParams->pIndirectStateBase; + } + else + { + MHW_RENDERHAL_CHK_NULL_RETURN(pCmdBuffer); + pbPtrCmdBuf = (uint8_t *)pCmdBuffer->pCmdBase; + } PMOS_INTERFACE pOsInterface = pRenderHal->pOsInterface; uint8_t *pSurfaceState = pParams->pSurfaceStateSource; @@ -7022,8 +7156,6 @@ MOS_STATUS RenderHal_SendSurfaceStateEntry( MOS_PATCH_ENTRY_PARAMS PatchEntryParams; - uint8_t *pbPtrCmdBuf = (uint8_t *)pCmdBuffer->pCmdBase; - MOS_ZeroMemory(&PatchEntryParams, sizeof(PatchEntryParams)); PatchEntryParams.uiAllocationIndex = pSurfaceStateToken->DW1.SurfaceAllocationIndex; PatchEntryParams.uiResourceOffset = pSurfaceStateToken->DW2.SurfaceOffset; @@ -7278,6 +7410,8 @@ MOS_STATUS RenderHal_InitInterface( pRenderHal->pfnSetSurfaceStateToken = RenderHal_SetSurfaceStateToken; pRenderHal->pfnSetSurfaceStateBuffer = RenderHal_SetSurfaceStateBuffer; pRenderHal->pfnCalculateYOffset = RenderHal_CalculateYOffset; + pRenderHal->pfnAssignBindlessSurfaceStates = RenderHal_AssignBindlessSurfaceStates; + pRenderHal->pfnSendBindlessSurfaceStates = RenderHal_SendSurfaces_Bindelss; pRenderHal->pfnGetPlaneDefinitionForCommonMessage = RenderHal_GetPlaneDefinitionForCommonMessage; diff --git a/media_softlet/agnostic/common/renderhal/surface_state_heap_mgr.cpp b/media_softlet/agnostic/common/renderhal/surface_state_heap_mgr.cpp new file mode 100644 index 0000000000..71f378060f --- /dev/null +++ b/media_softlet/agnostic/common/renderhal/surface_state_heap_mgr.cpp @@ -0,0 +1,275 @@ +/* +* Copyright (c) 2024, 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 surface_state_heap_mgr.cpp +//! \brief Render Engine state heap manager for VP and CM +//! \details Platform/OS Independent Render Engine state heap management interfaces +//! +#include "surface_state_heap_mgr.h" +#include "vp_utils.h" + +SurfaceStateHeapManager::SurfaceStateHeapManager(PMOS_INTERFACE pOsInterface) : m_osInterface(pOsInterface) +{ +} + +SurfaceStateHeapManager::~SurfaceStateHeapManager() +{ + DestroyHeap(); +} + +MOS_STATUS SurfaceStateHeapManager::CreateHeap(size_t surfStateSize) +{ + uint8_t *pMem; + uint32_t uiSize; + uint32_t uiOffset; + MOS_ALLOC_GFXRES_PARAMS AllocParams; + MOS_LOCK_PARAMS LockFlags; + MOS_STATUS eStatus = MOS_STATUS_SUCCESS; + + uiSize = sizeof(SURFACE_STATES_HEAP_OBJ); + uiSize += MAX_SURFACE_STATES * + sizeof(SURFACE_STATES_OBJ); + + // Allocate memory for render surface state heap + pMem = (uint8_t *)MOS_AllocAndZeroMemory(uiSize); + MHW_CHK_NULL_RETURN(pMem); + + m_surfStateHeap = (SURFACE_STATES_HEAP_OBJ *)pMem; + + m_surfStateHeap->pSurfStateObj = + (SURFACE_STATES_OBJ *)(pMem + sizeof(SURFACE_STATES_HEAP_OBJ)); + + // Appending sync data after all heap instances + m_surfStateHeap->uiOffsetSync = surfStateSize * MAX_SURFACE_STATES; + + // Allocate GPU memory + uiSize = surfStateSize * MAX_SURFACE_STATES + SYNC_SIZE; + + m_surfStateHeap->uiStateHeapSize = uiSize; + m_surfStateHeap->uiInstanceSize = surfStateSize; + + MOS_ZeroMemory(&AllocParams, sizeof(MOS_ALLOC_GFXRES_PARAMS)); + + AllocParams.Type = MOS_GFXRES_BUFFER; + AllocParams.TileType = MOS_TILE_LINEAR; + AllocParams.Format = Format_Buffer; + AllocParams.dwBytes = uiSize; + AllocParams.pBufName = "VphalSurfaceState"; + AllocParams.ResUsageType = MOS_HW_RESOURCE_USAGE_VP_INTERNAL_READ_WRITE_RENDER; + AllocParams.dwMemType = MOS_MEMPOOL_VIDEOMEMORY; + + MHW_CHK_STATUS_RETURN(m_osInterface->pfnAllocateResource( + m_osInterface, + &AllocParams, + &m_surfStateHeap->osResource)); + + // Lock the driver resource + MOS_ZeroMemory(&LockFlags, sizeof(MOS_LOCK_PARAMS)); + + LockFlags.NoOverWrite = 1; + + m_surfStateHeap->pLockedOsResourceMem = + (uint8_t *)m_osInterface->pfnLockResource( + m_osInterface, + &m_surfStateHeap->osResource, + &LockFlags); + MHW_CHK_NULL_RETURN(m_surfStateHeap->pLockedOsResourceMem); + + // Initialize VeboxHeap controls that depend on mapping + m_surfStateHeap->pSync = + (uint32_t *)(m_surfStateHeap->pLockedOsResourceMem + + m_surfStateHeap->uiOffsetSync); + + if (eStatus != MOS_STATUS_SUCCESS) + { + DestroyHeap(); + } + return eStatus; +} + +MOS_STATUS SurfaceStateHeapManager::DestroyHeap() +{ + if (m_surfStateHeap) + { + if (!Mos_ResourceIsNull(&m_surfStateHeap->osResource)) + { + if (m_surfStateHeap->pLockedOsResourceMem) + { + m_osInterface->pfnUnlockResource( + m_osInterface, + &m_surfStateHeap->osResource); + } + + m_osInterface->pfnFreeResource( + m_osInterface, + &m_surfStateHeap->osResource); + } + + MOS_FreeMemory(m_surfStateHeap); + m_surfStateHeap = nullptr; + } + return MOS_STATUS_SUCCESS; +} + +void SurfaceStateHeapManager::RefreshSync() +{ + SURFACE_STATES_OBJ *pCurInstance; + SURFACE_STATES_HEAP_OBJ *pSurfStateHeap; + uint32_t dwCurrentTag; + int32_t i; + int32_t iInstanceInUse; + MOS_NULL_RENDERING_FLAGS NullRenderingFlags; + + MHW_FUNCTION_ENTER; + if (m_surfStateHeap == nullptr || + m_osInterface == nullptr) + { + MHW_ASSERTMESSAGE("RefreshSync failed due to m_veboxHeap or m_osInterface is invalid "); + return; + } + iInstanceInUse = 0; + + // Vebox Heap will always be locked by driver + pSurfStateHeap = m_surfStateHeap; + + // Most recent tag + if (m_osInterface->bEnableKmdMediaFrameTracking) + { + dwCurrentTag = m_osInterface->pfnGetGpuStatusSyncTag(m_osInterface, MOS_GPU_CONTEXT_COMPUTE); + } + else + { + dwCurrentTag = pSurfStateHeap->pSync[0]; + } + pSurfStateHeap->dwSyncTag = dwCurrentTag - 1; + + NullRenderingFlags = m_osInterface->pfnGetNullHWRenderFlags( + m_osInterface); + + // Refresh VeboxHeap states + pCurInstance = pSurfStateHeap->pSurfStateObj; + for (i = MAX_SURFACE_STATES; i > 0; i--, pCurInstance++) + { + if (!pCurInstance->bBusy) + continue; + + // The condition below is valid when sync tag wraps from 2^32-1 to 0 + if (((int32_t)(dwCurrentTag - pCurInstance->dwSyncTag) >= 0) || + NullRenderingFlags.VPGobal) + { + pCurInstance->bBusy = false; + } + else + { + iInstanceInUse++; + } + } + + // Save number of instance in use + m_surfHeapInUse = iInstanceInUse; +} + +MOS_STATUS SurfaceStateHeapManager::AssignSurfaceState() +{ + VP_FUNC_CALL(); + + uint32_t dwWaitMs, dwWaitTag; + MOS_STATUS eStatus = MOS_STATUS_SUCCESS; + + SURFACE_STATES_OBJ *pSurfStateCurObj; + SURFACE_STATES_HEAP_OBJ *pSurfStateHeap; + uint32_t uiOffset; + + MHW_FUNCTION_ENTER; + MHW_CHK_NULL_RETURN(m_surfStateHeap); + MHW_CHK_NULL_RETURN(m_osInterface); + + pSurfStateHeap = m_surfStateHeap; + pSurfStateCurObj = &m_surfStateHeap->pSurfStateObj[m_surfStateHeap->uiNextState]; + + // Refresh sync tag for all heap instance + RefreshSync(); + + // Check validity of current vebox heap instance + // The code below is unlikely to be executed - unless all Vebox states are in use + // If this ever happens, please consider increasing the number of media states + MHW_CHK_NULL_RETURN(pSurfStateCurObj); + if (pSurfStateCurObj->bBusy) + { + // Get current vebox instance sync tag + dwWaitTag = pSurfStateCurObj->dwSyncTag; + + // Wait for Batch Buffer complete event OR timeout + for (dwWaitMs = MHW_TIMEOUT_MS_DEFAULT; dwWaitMs > 0; dwWaitMs--) + { + uint32_t dwCurrentTag; + + MHW_CHK_STATUS_RETURN(m_osInterface->pfnWaitForBBCompleteNotifyEvent( + m_osInterface, + MOS_GPU_CONTEXT_COMPUTE, + MHW_EVENT_TIMEOUT_MS)); + + if (m_osInterface->bEnableKmdMediaFrameTracking) + { + dwCurrentTag = m_osInterface->pfnGetGpuStatusSyncTag(m_osInterface, MOS_GPU_CONTEXT_COMPUTE); + } + else + { + dwCurrentTag = pSurfStateHeap->pSync[0]; + } + // Mark current instance status as availabe. Wait if this sync tag came back from GPU + if ((int32_t)(dwCurrentTag - dwWaitTag) >= 0) + { + pSurfStateCurObj->bBusy = false; + break; + } + } + + // Timeout + if (dwWaitMs == 0) + { + MHW_ASSERTMESSAGE("Timeout on waiting for free Vebox Heap."); + eStatus = MOS_STATUS_UNKNOWN; + return eStatus; + } + } + + // Prepare syncTag for GPU write back + if (m_osInterface->bEnableKmdMediaFrameTracking) + { + pSurfStateCurObj->dwSyncTag = m_osInterface->pfnGetGpuStatusTag(m_osInterface, MOS_GPU_CONTEXT_COMPUTE); + } + else + { + pSurfStateCurObj->dwSyncTag = pSurfStateHeap->dwNextTag; + } + + // Assign current state and increase next state + pSurfStateHeap->uiCurState = pSurfStateHeap->uiNextState; + pSurfStateHeap->uiNextState = (pSurfStateHeap->uiNextState + 1) % MAX_SURFACE_STATES; + + //Clean the memory of current veboxheap to avoid the history states + uiOffset = pSurfStateHeap->uiCurState * pSurfStateHeap->uiInstanceSize; + MOS_ZeroMemory(pSurfStateHeap->pLockedOsResourceMem + uiOffset, pSurfStateHeap->uiInstanceSize); + + return eStatus; +} \ No newline at end of file diff --git a/media_softlet/agnostic/common/vp/hal/packet/vp_render_cmd_packet.cpp b/media_softlet/agnostic/common/vp/hal/packet/vp_render_cmd_packet.cpp index 0a593ec46d..d140e04e07 100644 --- a/media_softlet/agnostic/common/vp/hal/packet/vp_render_cmd_packet.cpp +++ b/media_softlet/agnostic/common/vp/hal/packet/vp_render_cmd_packet.cpp @@ -214,31 +214,10 @@ MOS_STATUS VpRenderCmdPacket::Prepare() *m_surfMemCacheCtl, m_packetSharedContext)); - if (m_submissionMode == MULTI_KERNELS_MULTI_MEDIA_STATES || m_submissionMode == SINGLE_KERNEL_ONLY) + if (m_submissionMode == SINGLE_KERNEL_ONLY) { m_kernelRenderData.clear(); - if (m_submissionMode == MULTI_KERNELS_MULTI_MEDIA_STATES) - { - bool bAllocated = false; - VP_RENDER_CHK_STATUS_RETURN(m_renderHal->pfnReAllocateStateHeapsforAdvFeatureWithSshEnlarged(m_renderHal, bAllocated)); - - if (bAllocated && m_renderHal->pStateHeap) - { - MHW_STATE_BASE_ADDR_PARAMS *pStateBaseParams = &m_renderHal->StateBaseAddressParams; - - pStateBaseParams->presGeneralState = &m_renderHal->pStateHeap->GshOsResource; - pStateBaseParams->dwGeneralStateSize = m_renderHal->pStateHeap->dwSizeGSH; - pStateBaseParams->presDynamicState = &m_renderHal->pStateHeap->GshOsResource; - pStateBaseParams->dwDynamicStateSize = m_renderHal->pStateHeap->dwSizeGSH; - pStateBaseParams->bDynamicStateRenderTarget = false; - pStateBaseParams->presIndirectObjectBuffer = &m_renderHal->pStateHeap->GshOsResource; - pStateBaseParams->dwIndirectObjectBufferSize = m_renderHal->pStateHeap->dwSizeGSH; - pStateBaseParams->presInstructionBuffer = &m_renderHal->pStateHeap->IshOsResource; - pStateBaseParams->dwInstructionBufferSize = m_renderHal->pStateHeap->dwSizeISH; - } - } - VP_RENDER_CHK_NULL_RETURN(m_renderHal->pStateHeap); m_renderHal->pStateHeap->iCurrentBindingTable = 0; @@ -432,13 +411,8 @@ MOS_STATUS VpRenderCmdPacket::Submit(MOS_COMMAND_BUFFER *commandBuffer, uint8_t VP_RENDER_ASSERTMESSAGE("No Kernel Object Creation"); return MOS_STATUS_NULL_POINTER; } - if (m_submissionMode == MULTI_KERNELS_MULTI_MEDIA_STATES) - { - VP_RENDER_CHK_STATUS_RETURN(SetupMediaWalker()); - VP_RENDER_CHK_STATUS_RETURN(SubmitWithMultiKernel(commandBuffer, packetPhase)); - } - else if (m_submissionMode == SINGLE_KERNEL_ONLY) + if (m_submissionMode == SINGLE_KERNEL_ONLY) { VP_RENDER_CHK_STATUS_RETURN(SetupMediaWalker()); @@ -2038,14 +2012,7 @@ MOS_STATUS VpRenderCmdPacket::SendMediaStates( MHW_RENDERHAL_CHK_STATUS(PrepareComputeWalkerParams(it->second.walkerParam, m_gpgpuWalkerParams)); - if (m_submissionMode == MULTI_KERNELS_MULTI_MEDIA_STATES) - { - pRenderHal->pStateHeap->pCurMediaState = it->second.mediaState; - MHW_RENDERHAL_CHK_NULL(pRenderHal->pStateHeap->pCurMediaState); - pRenderHal->iKernelAllocationID = it->second.kernelAllocationID; - pRenderHal->pStateHeap->pCurMediaState->bBusy = true; - } - else if (m_submissionMode == MULTI_KERNELS_SINGLE_MEDIA_STATE) + if (m_submissionMode == MULTI_KERNELS_SINGLE_MEDIA_STATE) { pRenderHal->iKernelAllocationID = it->second.kernelAllocationID; } diff --git a/media_softlet/agnostic/common/vp/hal/packet/vp_render_common.h b/media_softlet/agnostic/common/vp/hal/packet/vp_render_common.h index 03020d8811..4dabe5bde7 100644 --- a/media_softlet/agnostic/common/vp/hal/packet/vp_render_common.h +++ b/media_softlet/agnostic/common/vp/hal/packet/vp_render_common.h @@ -137,7 +137,6 @@ enum KERNEL_SUBMISSION_MODE { SINGLE_KERNEL_ONLY = 0, MULTI_KERNELS_SINGLE_MEDIA_STATE, - MULTI_KERNELS_MULTI_MEDIA_STATES }; typedef struct _VP_RENDER_CACHE_CNTL