| /* |
| * Copyright (c) 2009-2021, 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 mos_os_specific.c |
| //! \brief Common interface used in MOS LINUX OS |
| //! \details Common interface used in MOS LINUX OS |
| //! |
| |
| #include "mos_os.h" |
| #include "mos_util_debug.h" |
| #include "mos_resource_defs.h" |
| #include <unistd.h> |
| #include <dlfcn.h> |
| #include "hwinfo_linux.h" |
| #include "media_fourcc.h" |
| #include <stdlib.h> |
| |
| #include "mos_graphicsresource.h" |
| #include "mos_context_specific.h" |
| #include "mos_gpucontext_specific.h" |
| #include "mos_gpucontextmgr.h" |
| |
| #include "mos_graphicsresource_next.h" |
| #include "mos_context_specific_next.h" |
| #include "mos_gpucontext_specific_next.h" |
| #include "mos_gpucontextmgr_next.h" |
| #include "mos_interface.h" |
| |
| #if MOS_MEDIASOLO_SUPPORTED |
| #include "mos_os_solo.h" |
| #endif // MOS_MEDIASOLO_SUPPORTED |
| #include "mos_solo_generic.h" |
| |
| #ifndef ANDROID |
| #include <sys/ipc.h> |
| #include <sys/shm.h> |
| #include <sys/sem.h> |
| #include <sys/types.h> |
| #endif |
| |
| #include "mos_os_virtualengine.h" |
| #include "mos_util_user_interface.h" |
| |
| #include "mos_os_virtualengine_singlepipe_next.h" |
| #include "mos_os_virtualengine_scalability_next.h" |
| |
| #include "memory_policy_manager.h" |
| |
| #if defined(USE_MAGMA) |
| #include "magma_fd.h" |
| #endif |
| |
| //! |
| //! \brief DRM VMAP patch |
| //! |
| #define Y_TILE_WIDTH 128 |
| #define Y_TILE_HEIGHT 32 |
| #define X_TILE_WIDTH 512 |
| #define X_TILE_HEIGHT 8 |
| |
| #define MI_BATCHBUFFER_END 0x05000000 |
| |
| //! |
| //! \brief Two VDBOX shared memory key |
| //! |
| #define DUAL_VDBOX_KEY ('D'<<24|'V'<<8|'X'<<0) |
| |
| //============= PRIVATE FUNCTIONS <BEGIN>========================================= |
| |
| bool SetupApoMosSwitch(int32_t fd) |
| { |
| if (fd < 0) |
| { |
| return false; |
| } |
| |
| //Read user feature to determine if apg mos is enabled. |
| uint32_t userfeatureValue = 0; |
| MOS_STATUS estatus = MosUtilities::MosReadApoMosEnabledUserFeature(userfeatureValue); |
| |
| if(estatus == MOS_STATUS_SUCCESS) |
| { |
| return (userfeatureValue != 0); |
| } |
| PRODUCT_FAMILY eProductFamily = IGFX_UNKNOWN; |
| HWInfo_GetGfxProductFamily(fd, eProductFamily); |
| |
| if (eProductFamily >= IGFX_TIGERLAKE_LP) |
| { |
| return true; |
| } |
| |
| return false; |
| } |
| |
| |
| //! |
| //! \brief Clear Gpu Context |
| //! \details OS GPU context clear |
| //! \param PMOS_RESOURCE pContext |
| //! [in] Pointer to OS context |
| //! \return void |
| //! Return NONE |
| //! |
| void Mos_Specific_ClearGpuContext(MOS_CONTEXT *pContext) |
| { |
| int32_t iLoop = 0; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| if (nullptr == pContext) |
| { |
| MOS_OS_ASSERTMESSAGE("Input mos context is null"); |
| return; |
| } |
| |
| for (iLoop = 0; iLoop < MOS_GPU_CONTEXT_MAX; iLoop++) |
| { |
| if (pContext->OsGpuContext[iLoop].pCB != nullptr) |
| { |
| MOS_FreeMemory(pContext->OsGpuContext[iLoop].pCB); |
| pContext->OsGpuContext[iLoop].pCB = nullptr; |
| } |
| |
| if (pContext->OsGpuContext[iLoop].pAllocationList != nullptr) |
| { |
| MOS_FreeMemory(pContext->OsGpuContext[iLoop].pAllocationList); |
| pContext->OsGpuContext[iLoop].pAllocationList = nullptr; |
| } |
| |
| if (pContext->OsGpuContext[iLoop].pPatchLocationList) |
| { |
| MOS_FreeMemory(pContext->OsGpuContext[iLoop].pPatchLocationList); |
| pContext->OsGpuContext[iLoop].pPatchLocationList = nullptr; |
| } |
| |
| if (pContext->OsGpuContext[iLoop].pResources != nullptr) |
| { |
| MOS_FreeMemory(pContext->OsGpuContext[iLoop].pResources); |
| pContext->OsGpuContext[iLoop].pResources = nullptr; |
| } |
| |
| if (pContext->OsGpuContext[iLoop].pbWriteMode != nullptr) |
| { |
| MOS_FreeMemory(pContext->OsGpuContext[iLoop].pbWriteMode); |
| pContext->OsGpuContext[iLoop].pbWriteMode = nullptr; |
| } |
| |
| pContext->OsGpuContext[iLoop].uiMaxNumAllocations = 0; |
| pContext->OsGpuContext[iLoop].uiMaxPatchLocationsize = 0; |
| } |
| } |
| |
| //! |
| //! \brief Unified OS get command buffer |
| //! \details Return the pointer to the next available space in Cmd Buffer |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS Context |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [out] Pointer to Command Buffer |
| //! \param int32_t iSize |
| //! [out] Size of command in bytes |
| //! \return int32_t |
| //! Return true is there is space |
| //! |
| int32_t Linux_GetCommandBuffer( |
| PMOS_CONTEXT pOsContext, |
| PMOS_COMMAND_BUFFER pCmdBuffer, |
| int32_t iSize) |
| { |
| int32_t bResult = false; |
| MOS_LINUX_BO *cmd_bo = nullptr; |
| |
| if ( pOsContext == nullptr || |
| pCmdBuffer == nullptr) |
| { |
| bResult = false; |
| MOS_OS_ASSERTMESSAGE("Linux_GetCommandBuffer:pOsContext == nullptr || pCmdBuffer == NULL"); |
| goto finish; |
| } |
| |
| // Allocate the command buffer from GEM |
| cmd_bo = mos_bo_alloc(pOsContext->bufmgr,"MOS CmdBuf",iSize,4096, MOS_MEMPOOL_SYSTEMMEMORY); // Align to page boundary |
| if (cmd_bo == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Allocation of command buffer failed."); |
| bResult = false; |
| goto finish; |
| } |
| //MOS_OS_NORMALMESSAGE("alloc CMB, bo is 0x%x.", cmd_bo); |
| |
| // Map command buffer to user virtual address |
| if (mos_bo_map(cmd_bo,1) != 0) // Write enable set |
| { |
| MOS_OS_ASSERTMESSAGE("Mapping of command buffer failed."); |
| bResult = false; |
| goto finish; |
| } |
| |
| Mos_ResetResource(&pCmdBuffer->OsResource); |
| |
| // Fill in resource information |
| pCmdBuffer->OsResource.Format = Format_Buffer; |
| pCmdBuffer->OsResource.iWidth = cmd_bo->size; |
| pCmdBuffer->OsResource.iHeight = 1; |
| pCmdBuffer->OsResource.iPitch = cmd_bo->size; |
| pCmdBuffer->OsResource.iSize = pCmdBuffer->OsResource.iPitch * pCmdBuffer->OsResource.iHeight; |
| pCmdBuffer->OsResource.iCount = 1; |
| pCmdBuffer->OsResource.pData = (uint8_t*)cmd_bo->virt; |
| pCmdBuffer->OsResource.TileType = MOS_TILE_LINEAR; |
| pCmdBuffer->OsResource.bo = cmd_bo; |
| pCmdBuffer->OsResource.bMapped = true; |
| |
| // for MOS wrapper to avoid memory leak |
| pCmdBuffer->OsResource.bConvertedFromDDIResource = true; |
| |
| pCmdBuffer->pCmdBase = (uint32_t*)cmd_bo->virt; |
| pCmdBuffer->pCmdPtr = (uint32_t*)cmd_bo->virt; |
| pCmdBuffer->iOffset = 0; |
| pCmdBuffer->iRemaining = cmd_bo->size; |
| pCmdBuffer->iCmdIndex = -1; |
| pCmdBuffer->iVdboxNodeIndex = MOS_VDBOX_NODE_INVALID; |
| pCmdBuffer->iVeboxNodeIndex = MOS_VEBOX_NODE_INVALID; |
| pCmdBuffer->is1stLvlBB = true; |
| MOS_ZeroMemory(pCmdBuffer->pCmdBase, cmd_bo->size); |
| pCmdBuffer->iSubmissionType = SUBMISSION_TYPE_SINGLE_PIPE; |
| MOS_ZeroMemory(&pCmdBuffer->Attributes, sizeof(pCmdBuffer->Attributes)); |
| bResult = true; |
| |
| finish: |
| if ((false == bResult)&&(nullptr != cmd_bo)){ |
| //need to unreference command buffer allocated. |
| mos_bo_unreference(cmd_bo); |
| } |
| return bResult; |
| } |
| |
| //! |
| //! \brief Get unused command buffer space |
| //! \details Return unused command buffer space |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS Context |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU context |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [out] Pointer to Command buffer |
| //! \return void |
| //! |
| void Linux_ReturnCommandBuffer( |
| PMOS_CONTEXT pOsContext, |
| MOS_GPU_CONTEXT GpuContext, |
| PMOS_COMMAND_BUFFER pCmdBuffer) |
| { |
| MOS_OS_GPU_CONTEXT *pOsGpuContext; |
| |
| if (pOsContext == nullptr || pCmdBuffer == nullptr || |
| Mos_ResourceIsNull(&(pCmdBuffer->OsResource))) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter pOsContext or pCmdBuffer."); |
| goto finish; |
| } |
| |
| if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| goto finish; |
| } |
| |
| pOsGpuContext = &pOsContext->OsGpuContext[GpuContext]; |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Os gpucontext is null."); |
| goto finish; |
| } |
| |
| pOsGpuContext->pCB->iOffset = pCmdBuffer->iOffset ; |
| pOsGpuContext->pCB->iRemaining = pCmdBuffer->iRemaining; |
| pOsGpuContext->pCB->pCmdPtr = pCmdBuffer->pCmdPtr; |
| pOsGpuContext->pCB->iVdboxNodeIndex = pCmdBuffer->iVdboxNodeIndex; |
| pOsGpuContext->pCB->iVeboxNodeIndex = pCmdBuffer->iVeboxNodeIndex; |
| pOsGpuContext->pCB->is1stLvlBB = pCmdBuffer->is1stLvlBB; |
| |
| finish: |
| return; |
| } |
| |
| //! |
| //! \brief Flush Command Buffer |
| //! \details Flush Command Buffer space |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS Context |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU context |
| //! \return int32_t |
| //! true if succeeded, false if failed or invalid parameters |
| //! |
| int32_t Linux_FlushCommandBuffer( |
| PMOS_CONTEXT pOsContext, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| PCOMMAND_BUFFER pCurrCB; |
| int32_t bResult = false; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext; |
| |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter pOsContext.") |
| goto finish; |
| } |
| |
| if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| goto finish; |
| } |
| |
| pOsGpuContext = &pOsContext->OsGpuContext[GpuContext]; |
| if (pOsGpuContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid OsGpuContext"); |
| goto finish; |
| } |
| |
| // Refresh command buffer usage |
| pOsContext->pfnRefresh(pOsContext); |
| |
| pOsGpuContext->uiCurrentNumPatchLocations = 0; |
| |
| // CB already active |
| pCurrCB = pOsGpuContext->pCurrentCB; |
| if (pCurrCB == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid current CB in OsGpuContext."); |
| goto finish; |
| } |
| |
| if (pCurrCB->bActive) |
| { |
| goto finish; |
| } |
| |
| pCurrCB->bActive = true; |
| bResult = true; |
| |
| finish: |
| return bResult; |
| } |
| |
| //! |
| //! \brief Init command buffer pool |
| //! \details Initilize the command buffer pool |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS Context |
| //! \return void |
| //! |
| void Linux_InitCmdBufferPool( |
| PMOS_CONTEXT pOsContext) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_ZeroMemory(&pOsContext->CmdBufferPool, sizeof(CMD_BUFFER_BO_POOL)); |
| pOsContext->CmdBufferPool.iFetch = 0; |
| } |
| |
| //! |
| //! \brief Wait and release command buffer |
| //! \details Command buffer Wait and release |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \param int32_t index |
| //! [in] Command buffer's index in Command buffer pool |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Linux_WaitAndReleaseCmdBuffer( |
| PMOS_CONTEXT pOsContext, |
| int32_t index) |
| { |
| MOS_LINUX_BO *cmd_bo; |
| MOS_STATUS eStatus; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| if (index < 0 || index >= MAX_CMD_BUF_NUM) |
| { |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| |
| // According to the logic of CmdBufferPool now, the command buffer is used in a circular way. |
| // The input index always points to the next(oldest) buffer after the latest(newest) buffer. |
| // If the next buffer is not empty (!= nullptr), all the buffers in the pool will also be not empty. |
| // So it's not necessary to check all buffers to see whether there's empty buffer. |
| cmd_bo = pOsContext->CmdBufferPool.pCmd_bo[index]; |
| if (cmd_bo != nullptr) |
| { |
| mos_bo_wait_rendering(cmd_bo); |
| mos_bo_unreference(cmd_bo); |
| pOsContext->CmdBufferPool.pCmd_bo[index] = nullptr; |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Release command buffer pool |
| //! \details Release command buffer pool until all of commands are finished. |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Linux_ReleaseCmdBufferPool(PMOS_CONTEXT pOsContext) |
| { |
| int32_t i; |
| MOS_STATUS eStatus; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| for (i = 0; i < MAX_CMD_BUF_NUM; i++) |
| { |
| MOS_OS_CHK_STATUS(Linux_WaitAndReleaseCmdBuffer(pOsContext, i)); |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Wait for the fetch command |
| //! \details Wait for the fetch command bo until it is available |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Linux_WaitForAvailableCmdBo( |
| PMOS_CONTEXT pOsContext) |
| { |
| int32_t index; |
| MOS_STATUS eStatus; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| index = pOsContext->CmdBufferPool.iFetch; |
| MOS_OS_CHK_STATUS(Linux_WaitAndReleaseCmdBuffer(pOsContext, index)); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Insert command buffer |
| //! \details Insert command buffer into pool |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [in] Pointer to command buffer struct |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Linux_InsertCmdBufferToPool( |
| PMOS_CONTEXT pOsContext, |
| PMOS_COMMAND_BUFFER pCmdBuffer) |
| { |
| int32_t index = 0; |
| MOS_STATUS eStatus; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsContext); |
| MOS_OS_CHK_NULL(pCmdBuffer); |
| MOS_OS_CHK_STATUS(Linux_WaitForAvailableCmdBo(pOsContext)); |
| |
| index = pOsContext->CmdBufferPool.iFetch; |
| |
| pOsContext->CmdBufferPool.pCmd_bo[index] = pCmdBuffer->OsResource.bo; |
| pCmdBuffer->iCmdIndex = index; |
| |
| pOsContext->CmdBufferPool.iFetch++; |
| if (pOsContext->CmdBufferPool.iFetch >= MAX_CMD_BUF_NUM) |
| { |
| pOsContext->CmdBufferPool.iFetch = 0; |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Linux Refresh |
| //! \details Linux Refresh |
| //! \param MOS_CONTEXT * pOsContext |
| //! [in] Pointer to OS context structure |
| //! \return int32_t |
| //! true always |
| //! |
| int32_t Linux_Refresh(MOS_CONTEXT *pOsContext) |
| { |
| MOS_UNUSED(pOsContext); |
| return true; |
| } |
| |
| #ifndef ANDROID |
| |
| #define MOS_LINUX_IPC_INVALID_ID -1 |
| #define MOS_LINUX_SHM_INVALID (void *)-1 |
| #define MOS_LINUX_SEM_MAX_TRIES 10 |
| |
| static MOS_STATUS DetachDestroyShm(int32_t shmid, void *pShm) |
| { |
| struct shmid_ds buf; |
| MOS_ZeroMemory(&buf, sizeof(buf)); |
| |
| if (shmid < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| if ((pShm != MOS_LINUX_SHM_INVALID) && (pShm != nullptr) && shmdt(pShm) < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| if (shmctl(shmid, IPC_STAT, &buf) < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| if (buf.shm_nattch == 0) |
| { |
| if (shmctl(shmid, IPC_RMID, nullptr) < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| } |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| static MOS_STATUS ConnectCreateShm(long key, uint32_t size, int32_t *pShmid, void **ppShm) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| MOS_OS_CHK_NULL_RETURN(pShmid); |
| MOS_OS_CHK_NULL_RETURN(ppShm); |
| |
| struct shmid_ds buf; |
| int32_t shmid = -1; |
| key_t key_value = (key_t)key; |
| void * shmptr = nullptr; |
| MOS_ZeroMemory(&buf, sizeof(buf)); |
| |
| shmid = shmget(key_value, size, IPC_CREAT | 0666); |
| if (shmid < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| shmptr = shmat(shmid, 0, 0); |
| if (shmptr == MOS_LINUX_SHM_INVALID) |
| { |
| DetachDestroyShm(shmid, shmptr); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| if (shmctl(shmid, IPC_STAT, &buf) < 0) |
| { |
| // can't get any status info |
| DetachDestroyShm(shmid, shmptr); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| *ppShm = shmptr; |
| *pShmid = shmid; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| static MOS_STATUS ConnectCreateSemaphore(long key, int32_t *pSemid) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| MOS_OS_CHK_NULL_RETURN(pSemid); |
| int32_t semid = -1; |
| struct sembuf sop; |
| struct semid_ds buf; |
| uint32_t i = 0; |
| key_t key_value = (key_t)key; |
| int32_t val = 0; |
| MOS_ZeroMemory(&sop, sizeof(sop)); |
| MOS_ZeroMemory(&buf, sizeof(buf)); |
| |
| semid = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666); |
| |
| if (semid != MOS_LINUX_IPC_INVALID_ID) |
| { |
| // initialize it to 0 |
| if (semctl(semid, 0, SETVAL, val) == -1) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| // Perform a "no-op" semaphore operation - changes sem_otime |
| // so other processes can see we've initialized the set. |
| sop.sem_num = 0; |
| sop.sem_op = 0; //Wait for value to equal 0 |
| sop.sem_flg = 0; |
| if (semop(semid, &sop, 1) == -1) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| } |
| else |
| { |
| // errno EEXIST |
| semid = semget(key, 1, 0666); |
| if (semid == MOS_LINUX_IPC_INVALID_ID) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| } |
| |
| *pSemid = semid; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| static MOS_STATUS DestroySemaphore(int32_t semid) |
| { |
| int32_t nwait = -1; |
| |
| if (semid < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| nwait = semctl(semid, 0, GETZCNT, 0); |
| |
| if (nwait > 0) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| if (semctl(semid, 0, IPC_RMID, nullptr) < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| static int16_t ShmAttachedNumber(int32_t shmid) |
| { |
| struct shmid_ds buf; |
| MOS_ZeroMemory(&buf, sizeof(buf)); |
| |
| if (shmctl(shmid, IPC_STAT, &buf) < 0) |
| { |
| return -1; |
| } |
| |
| return buf.shm_nattch; |
| } |
| |
| static MOS_STATUS LockSemaphore(int32_t semid) |
| { |
| struct sembuf op[2]; |
| op[0].sem_num = 0; // wait for [0] to be 0 |
| op[0].sem_op = 0; |
| op[0].sem_flg = 0; |
| op[1].sem_num = 0; |
| op[1].sem_op = 1; // increment |
| op[1].sem_flg = SEM_UNDO; |
| |
| if (semid < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| if (semop(semid, op, 2) < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| static MOS_STATUS UnLockSemaphore(int32_t semid) |
| { |
| struct sembuf op; |
| op.sem_num = 0; |
| op.sem_op = -1; // decrement back to 0 |
| op.sem_flg = SEM_UNDO; |
| |
| if (semid < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| if (semop(semid, &op, 1) < 0) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| void DestroyIPC(PMOS_CONTEXT pOsContext) |
| { |
| if (MOS_LINUX_IPC_INVALID_ID != pOsContext->semid) |
| { |
| int16_t iAttachedNum = 0; |
| |
| if (MOS_LINUX_IPC_INVALID_ID != pOsContext->shmid) |
| { |
| LockSemaphore(pOsContext->semid); |
| iAttachedNum = ShmAttachedNumber(pOsContext->shmid); |
| |
| DetachDestroyShm(pOsContext->shmid, pOsContext->pShm); |
| pOsContext->shmid = MOS_LINUX_IPC_INVALID_ID; |
| pOsContext->pShm = MOS_LINUX_SHM_INVALID; |
| |
| if (iAttachedNum) --iAttachedNum; |
| UnLockSemaphore(pOsContext->semid); |
| } |
| } |
| } |
| |
| MOS_STATUS CreateIPC(PMOS_CONTEXT pOsContext) |
| { |
| MOS_STATUS eStatus; |
| |
| MOS_OS_CHK_NULL(pOsContext); |
| pOsContext->semid = MOS_LINUX_IPC_INVALID_ID; |
| pOsContext->shmid = MOS_LINUX_IPC_INVALID_ID; |
| pOsContext->pShm = MOS_LINUX_SHM_INVALID; |
| |
| struct semid_ds buf; |
| MOS_ZeroMemory(&buf, sizeof(buf)); |
| |
| //wait and retry untill to get a valid semaphore |
| for (int i = 0; i < MOS_LINUX_SEM_MAX_TRIES; i ++) |
| { |
| ConnectCreateSemaphore(DUAL_VDBOX_KEY, &pOsContext->semid); |
| |
| //check whether the semid is initialized or not |
| if (semctl(pOsContext->semid, 0, IPC_STAT, &buf) == -1) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| if (buf.sem_otime != 0) |
| { |
| break; |
| } |
| |
| MOS_Sleep(1); //wait and retry |
| } |
| |
| LockSemaphore(pOsContext->semid); |
| eStatus = ConnectCreateShm(DUAL_VDBOX_KEY, sizeof(VDBOX_WORKLOAD), &pOsContext->shmid, &pOsContext->pShm); |
| UnLockSemaphore(pOsContext->semid); |
| MOS_CHK_STATUS_SAFE(eStatus); |
| |
| finish: |
| return eStatus; |
| } |
| #endif |
| |
| GpuContextSpecific* Linux_GetGpuContext(PMOS_INTERFACE pOsInterface, uint32_t gpuContextHandle) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| if (pOsInterface == nullptr || pOsInterface->osContextPtr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid input parameters!"); |
| return nullptr; |
| } |
| |
| auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| |
| auto gpuContextMgr = osCxtSpecific->GetGpuContextMgr(); |
| if (gpuContextMgr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("m_gpuContextMgr cannot be nullptr"); |
| return nullptr; |
| } |
| |
| auto gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle); |
| if (gpuContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active gpuContextHandle"); |
| return nullptr; |
| } |
| |
| auto gpuContextSpecific = static_cast<GpuContextSpecific *>(gpuContext); |
| |
| return gpuContextSpecific; |
| } |
| |
| //! |
| //! \brief Initialize the GPU Status Buffer |
| //! \details Initialize the GPU Status Buffer |
| //! \param MOS_CONTEXT * pOsContext |
| //! [in, out] Pointer to OS context structure |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Linux_InitGPUStatus( |
| PMOS_CONTEXT pOsContext) |
| { |
| MOS_LINUX_BO *bo = nullptr; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Linux_InitGPUStatus:pOsContext == NULL"); |
| eStatus = MOS_STATUS_NULL_POINTER; |
| goto finish; |
| } |
| |
| pOsContext->pGPUStatusBuffer = |
| (MOS_RESOURCE*)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * MOS_GPU_CONTEXT_MAX); |
| if (nullptr == pOsContext->pGPUStatusBuffer) |
| { |
| MOS_OS_ASSERTMESSAGE("pContext->pGPUStatusBuffer malloc failed."); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| |
| // Allocate the command buffer from GEM |
| bo = mos_bo_alloc(pOsContext->bufmgr,"GPU Status Buffer", sizeof(MOS_GPU_STATUS_DATA) * MOS_GPU_CONTEXT_MAX, 4096, MOS_MEMPOOL_SYSTEMMEMORY); // Align to page boundary |
| if (bo == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Allocation of GPU Status Buffer failed."); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| |
| // Map command buffer to user virtual address |
| if (mos_bo_map(bo, 1) != 0) // Write enable set |
| { |
| MOS_OS_ASSERTMESSAGE("Mapping of GPU Status Buffer failed."); |
| eStatus = MOS_STATUS_INVALID_HANDLE; |
| goto finish; |
| } |
| |
| Mos_ResetResource(pOsContext->pGPUStatusBuffer); |
| |
| // Fill in resource information |
| pOsContext->pGPUStatusBuffer->Format = Format_Buffer; |
| pOsContext->pGPUStatusBuffer->iWidth = bo->size; |
| pOsContext->pGPUStatusBuffer->iHeight = 1; |
| pOsContext->pGPUStatusBuffer->iPitch = bo->size; |
| pOsContext->pGPUStatusBuffer->iCount = 1; |
| pOsContext->pGPUStatusBuffer->pData = (uint8_t*)bo->virt; |
| pOsContext->pGPUStatusBuffer->TileType = MOS_TILE_LINEAR; |
| pOsContext->pGPUStatusBuffer->bo = bo; |
| pOsContext->pGPUStatusBuffer->bMapped = true; |
| |
| MOS_ZeroMemory(pOsContext->pGPUStatusBuffer->pData, bo->size); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Release the GPU Status Buffer |
| //! \details Release the GPU Status Buffer |
| //! \param MOS_CONTEXT * pOsContext |
| //! [in, out] Pointer to OS context structure |
| //! \return void |
| //! |
| void Linux_ReleaseGPUStatus( |
| PMOS_CONTEXT pOsContext) |
| { |
| MOS_LINUX_BO *bo = nullptr; |
| |
| if ( pOsContext == nullptr || pOsContext->pGPUStatusBuffer == nullptr) |
| { |
| return; |
| } |
| |
| bo = pOsContext->pGPUStatusBuffer->bo; |
| if (bo != nullptr) |
| { |
| mos_bo_unmap(bo); |
| mos_bo_wait_rendering(bo); |
| mos_bo_unreference(bo); |
| } |
| pOsContext->pGPUStatusBuffer->bo = nullptr; |
| |
| MOS_FreeMemAndSetNull(pOsContext->pGPUStatusBuffer); |
| } |
| |
| //! |
| //! \brief Get GPU status tag for the given GPU context |
| //! \details Get GPU status tag for the given GPU context |
| //! \param MOS_CONTEXT * pOsContext |
| //! [in] Pointer to OS context structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in, out] GPU Context |
| //! \return uint32_t |
| //! GPU status tag |
| //! |
| uint32_t Linux_GetGpuCtxBufferTag( |
| PMOS_CONTEXT pOsContext, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| if ( pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid pOsContext."); |
| return 0; |
| } |
| |
| if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return 0; |
| } |
| |
| return pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag; |
| } |
| |
| //! |
| //! \brief Increment GPU status tag for the given GPU context |
| //! \details Increment GPU status tag for the given GPU context |
| //! \param MOS_CONTEXT * pOsContext |
| //! [in] Pointer to OS context structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return void |
| //! |
| void Linux_IncGpuCtxBufferTag( |
| PMOS_CONTEXT pOsContext, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| uint32_t uiGPUStatusTag; |
| |
| if ( pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid pOsContext."); |
| return; |
| } |
| |
| if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return; |
| } |
| |
| uiGPUStatusTag = pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag; |
| |
| pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag = uiGPUStatusTag % UINT_MAX + 1; |
| if(pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag == 0) |
| { |
| pOsContext->OsGpuContext[GpuContext].uiGPUStatusTag = 1; |
| } |
| } |
| |
| GMM_CLIENT_CONTEXT* Linux_GetGmmClientContext(PMOS_CONTEXT pOsContext) |
| { |
| if (pOsContext == nullptr) |
| { |
| return nullptr; |
| } |
| return pOsContext->pGmmClientContext; |
| } |
| |
| MosOcaInterface* Linux_GetOcaInterface() |
| { |
| return nullptr; |
| } |
| |
| //! |
| //! \brief Get GPU tag for the given GPU context from the status buffer |
| //! \details Get GPU tag for the given GPU context from the status buffer |
| //! \param MOS_CONTEXT * pOsContext |
| //! [in] Pointer to OS context structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return uint32_t |
| //! GPU tag |
| //! |
| uint32_t Linux_GetGPUTag( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT mosGpuCtx) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| if (pOsInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid input parameters!"); |
| return 0; |
| } |
| |
| if (mosGpuCtx == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return 0; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| if (pOsInterface->osContextPtr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid input parameters!"); |
| return 0; |
| } |
| |
| auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| |
| auto handle = osCxtSpecific->GetGpuContextHandle(mosGpuCtx); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| PMOS_RESOURCE gpuStatusResource = nullptr; |
| MOS_OS_CHK_STATUS_RETURN(MosInterface::GetGpuStatusBufferResource(pOsInterface->osStreamState, gpuStatusResource, handle)); |
| MOS_OS_CHK_NULL_RETURN(gpuStatusResource); |
| auto gpuStatusData = (MOS_GPU_STATUS_DATA *)gpuStatusResource->pData; |
| if (gpuStatusData == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot find "); |
| return 0; |
| } |
| return gpuStatusData->GPUTag; |
| } |
| |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, handle); |
| |
| if (gpuContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot get corresponding gpu context!"); |
| return 0; |
| } |
| |
| auto resource = gpuContext->GetStatusBufferResource(); |
| |
| if (resource == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active resource."); |
| return 0; |
| } |
| |
| MOS_RESOURCE gpuStatusResource; |
| MOS_OS_CHK_STATUS_RETURN(resource->ConvertToMosResource(&gpuStatusResource)); |
| auto gpuStatusData = (MOS_GPU_STATUS_DATA *)gpuStatusResource.pData; |
| if (gpuStatusData == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot find "); |
| return 0; |
| } |
| return gpuStatusData->GPUTag; |
| } |
| |
| MOS_GPU_STATUS_DATA *pGPUStatusData = nullptr; |
| |
| if ( pOsInterface->pOsContext == nullptr || |
| pOsInterface->pOsContext->pGPUStatusBuffer == nullptr || |
| pOsInterface->pOsContext->pGPUStatusBuffer->pData == nullptr) |
| { |
| return 0; |
| } |
| |
| pGPUStatusData = (MOS_GPU_STATUS_DATA *)(pOsInterface->pOsContext->pGPUStatusBuffer->pData + (sizeof(MOS_GPU_STATUS_DATA) * mosGpuCtx)); |
| if (pGPUStatusData == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active resource"); |
| return 0; |
| } |
| return pGPUStatusData->GPUTag; |
| } |
| |
| //! |
| //! \brief Destroy Linux context |
| //! \details Destroy Linux context |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \return void |
| //! |
| void Linux_Destroy( |
| PMOS_CONTEXT pOsContext, |
| int32_t MODSEnabled, |
| int32_t modularizedGpuCtxEnabled) |
| { |
| PCOMMAND_BUFFER pCurrCB = nullptr; |
| PCOMMAND_BUFFER pNextCB = nullptr; |
| int32_t iSize = 0; |
| int i = 0; |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("OsContext is null."); |
| return; |
| } |
| |
| #ifndef ANDROID |
| if (pOsContext->bKMDHasVCS2) |
| { |
| DestroyIPC(pOsContext); |
| } |
| #endif |
| |
| if (!modularizedGpuCtxEnabled) |
| { |
| Linux_ReleaseCmdBufferPool(pOsContext); |
| |
| for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| MOS_FreeMemAndSetNull(pOsContext->OsGpuContext[i].pCB); |
| |
| pCurrCB = pOsContext->OsGpuContext[i].pStartCB; |
| for (; (pCurrCB); pCurrCB = pNextCB) |
| { |
| pNextCB = pCurrCB->pNext; |
| MOS_FreeMemAndSetNull(pCurrCB); |
| } |
| } |
| |
| Linux_ReleaseGPUStatus(pOsContext); |
| } |
| |
| if (pOsContext->contextOffsetList.size()) |
| { |
| pOsContext->contextOffsetList.clear(); |
| pOsContext->contextOffsetList.shrink_to_fit(); |
| } |
| |
| if (!MODSEnabled && (pOsContext->intel_context)) |
| { |
| if (pOsContext->intel_context->vm) |
| { |
| mos_gem_vm_destroy(pOsContext->intel_context->bufmgr,pOsContext->intel_context->vm); |
| pOsContext->intel_context->vm = nullptr; |
| } |
| mos_gem_context_destroy(pOsContext->intel_context); |
| } |
| |
| pOsContext->GmmFuncs.pfnDeleteClientContext(pOsContext->pGmmClientContext); |
| |
| MOS_FreeMemAndSetNull(pOsContext); |
| } |
| |
| //! |
| //! \brief Get DMA Buffer ID |
| //! \details Get the DMA perf Buffer ID |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \return uint32_t |
| //! Return the buffer ID |
| //! |
| uint32_t Linux_GetDmaBufID (PMOS_CONTEXT pOsContext ) |
| { |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("OsContext is null."); |
| return 0; |
| } |
| |
| uint32_t dmaBufID = 0; |
| if (pOsContext->pPerfData != nullptr) |
| { |
| dmaBufID = pOsContext->pPerfData->dmaBufID; |
| } |
| return dmaBufID; |
| } |
| |
| //! |
| //! \brief Get Buffer Type |
| //! \details Returns the type of buffer, 1D, 2D or volume |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS Resource |
| //! \return GFX resource Type |
| //! |
| MOS_GFXRES_TYPE GetResType(PMOS_RESOURCE pOsResource) |
| { |
| GMM_RESOURCE_INFO *pGmmResourceInfo = nullptr; |
| MOS_GFXRES_TYPE ResType = MOS_GFXRES_INVALID; |
| GMM_RESOURCE_TYPE GMMResType = RESOURCE_INVALID; |
| |
| if (pOsResource == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("OsContext is null."); |
| return MOS_GFXRES_INVALID; |
| } |
| |
| pGmmResourceInfo = (GMM_RESOURCE_INFO *)pOsResource->pGmmResInfo; |
| GMMResType = pGmmResourceInfo->GetResourceType(); |
| |
| switch (GMMResType) |
| { |
| case RESOURCE_BUFFER: |
| ResType = MOS_GFXRES_BUFFER; |
| break; |
| case RESOURCE_3D: |
| ResType = MOS_GFXRES_VOLUME; |
| break; |
| case RESOURCE_2D: |
| ResType = MOS_GFXRES_2D; |
| break; |
| default: |
| break; |
| } |
| return ResType; |
| } |
| //! |
| //! \brief Set the DMA Buffer ID |
| //! \details Sets the buffer ID in perf data |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \param uint32_t dwDmaBufID |
| //! [in] Buffer ID to be set |
| //! \return void |
| //! |
| void Linux_SetDmaBufID ( PMOS_CONTEXT pOsContext, uint32_t dwDmaBufID ) |
| { |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("OsContext is null."); |
| return; |
| } |
| |
| if (pOsContext->pPerfData != nullptr) |
| { |
| pOsContext->pPerfData->dmaBufID = dwDmaBufID; |
| } |
| } |
| |
| //! |
| //! \brief Set the DMA Kernel ID |
| //! \details Sets the Kernel ID in perf data |
| //! \param PMOS_CONTEXT pOsContext |
| //! [in] Pointer to OS context structure |
| //! \param uint32_t KernelID |
| //! [in] Buffer ID to be set |
| //! \return void |
| //! |
| void Linux_SetPerfHybridKernelID ( PMOS_CONTEXT pOsContext, uint32_t KernelID) |
| { |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("OsContext is null."); |
| return; |
| } |
| |
| if (pOsContext->pPerfData != nullptr) |
| { |
| pOsContext->pPerfData->dmaBufID = (pOsContext->pPerfData->dmaBufID & 0xF0FF) | ((KernelID <<8) & 0x0F00); |
| } |
| } |
| |
| //! |
| //! \brief Init Linux context |
| //! \details Initialize the linux context |
| //! \param MOS_OS_CONTEXT * pContext |
| //! [in] Pointer to OS context structure |
| //! \param PMOS_CONTEXT pOsDriverContext |
| //! [in] Pointer to OS Driver context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Linux_InitContext( |
| MOS_OS_CONTEXT *pContext, |
| PMOS_CONTEXT pOsDriverContext, |
| int32_t MODSEnabled, |
| int32_t modularizedGpuCtxEnabled) |
| { |
| int32_t iDeviceId = -1; |
| MOS_STATUS eStatus; |
| int32_t i = -1; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| if (nullptr == pContext || |
| nullptr == pOsDriverContext || |
| nullptr == pOsDriverContext->bufmgr || |
| (nullptr == pOsDriverContext->m_gpuContextMgr && modularizedGpuCtxEnabled && !pOsDriverContext->m_apoMosEnabled) || |
| (nullptr == pOsDriverContext->m_cmdBufMgr && modularizedGpuCtxEnabled && !pOsDriverContext->m_apoMosEnabled) || |
| 0 >= pOsDriverContext->fd) |
| { |
| MOS_OS_ASSERT(false); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| pContext->bufmgr = pOsDriverContext->bufmgr; |
| pContext->m_gpuContextMgr = pOsDriverContext->m_gpuContextMgr; |
| pContext->m_cmdBufMgr = pOsDriverContext->m_cmdBufMgr; |
| pContext->fd = pOsDriverContext->fd; |
| pContext->pPerfData = pOsDriverContext->pPerfData; |
| pContext->m_auxTableMgr = pOsDriverContext->m_auxTableMgr; |
| |
| mos_bufmgr_gem_enable_reuse(pOsDriverContext->bufmgr); |
| |
| // DDI layer can pass over the DeviceID. |
| iDeviceId = pOsDriverContext->iDeviceId; |
| if (0 == iDeviceId) |
| { |
| //Such as CP, it calls InitMosInterface() dretly without creating MediaContext. |
| iDeviceId = mos_bufmgr_gem_get_devid(pOsDriverContext->bufmgr); |
| pOsDriverContext->iDeviceId = iDeviceId; |
| |
| MOS_OS_CHK_STATUS_MESSAGE( |
| HWInfo_GetGfxInfo(pOsDriverContext->fd, pOsDriverContext->bufmgr, &pContext->platform, &pContext->SkuTable, &pContext->WaTable, &pContext->gtSystemInfo), |
| "Fatal error - unsuccesfull Sku/Wa/GtSystemInfo initialization"); |
| |
| pOsDriverContext->SkuTable = pContext->SkuTable; |
| pOsDriverContext->WaTable = pContext->WaTable; |
| pOsDriverContext->gtSystemInfo = pContext->gtSystemInfo; |
| pOsDriverContext->platform = pContext->platform; |
| MOS_OS_NORMALMESSAGE("DeviceID was created DeviceID = %d, platform product %d", iDeviceId, pContext->platform.eProductFamily); |
| } |
| else |
| { |
| // pOsDriverContext's parameters were passed by CmCreateDevice. |
| // Get SkuTable/WaTable/systemInfo/platform from OSDriver directly. |
| pContext->SkuTable = pOsDriverContext->SkuTable; |
| pContext->WaTable = pOsDriverContext->WaTable; |
| pContext->gtSystemInfo = pOsDriverContext->gtSystemInfo; |
| pContext->platform = pOsDriverContext->platform; |
| } |
| |
| pContext->bUse64BitRelocs = true; |
| pContext->bUseSwSwizzling = pContext->bSimIsActive || MEDIA_IS_SKU(&pContext->SkuTable, FtrUseSwSwizzling); |
| pContext->bTileYFlag = MEDIA_IS_SKU(&pContext->SkuTable, FtrTileY); |
| // when MODS enabled, intel_context will be created by pOsContextSpecific, should not recreate it here, or will cause memory leak. |
| if (!MODSEnabled) |
| { |
| pContext->intel_context = mos_gem_context_create_ext(pOsDriverContext->bufmgr,0); |
| if (!Mos_Solo_IsEnabled(nullptr) && pContext->intel_context) |
| { |
| pContext->intel_context->vm = mos_gem_vm_create(pOsDriverContext->bufmgr); |
| if (pContext->intel_context->vm == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to create vm.\n"); |
| return MOS_STATUS_UNKNOWN; |
| } |
| } |
| else //try legacy context create ioctl if DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT is not supported |
| { |
| pContext->intel_context = mos_gem_context_create(pOsDriverContext->bufmgr); |
| if (pContext->intel_context) |
| { |
| pContext->intel_context->vm = nullptr; |
| } |
| } |
| |
| if (pContext->intel_context == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to create drm intel context"); |
| return MOS_STATUS_UNKNOWN; |
| } |
| } |
| |
| pContext->intel_context->pOsContext = pContext; |
| |
| pContext->bIsAtomSOC = IS_ATOMSOC(iDeviceId); |
| |
| if(!modularizedGpuCtxEnabled) |
| { |
| Linux_InitCmdBufferPool(pContext); |
| |
| // Initialize GPU Status Buffer |
| eStatus = Linux_InitGPUStatus(pContext); |
| if (MOS_STATUS_SUCCESS != eStatus) |
| { |
| goto finish; |
| } |
| |
| for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| pContext->OsGpuContext[i].pStartCB = nullptr; |
| pContext->OsGpuContext[i].pCurrentCB = nullptr; |
| pContext->OsGpuContext[i].bCBFlushed = true; |
| pContext->OsGpuContext[i].uiCommandBufferSize = COMMAND_BUFFER_SIZE; |
| pContext->OsGpuContext[i].pCB = |
| (PMOS_COMMAND_BUFFER)MOS_AllocAndZeroMemory(sizeof(MOS_COMMAND_BUFFER)); |
| |
| if (nullptr == pContext->OsGpuContext[i].pCB) |
| { |
| MOS_OS_ASSERTMESSAGE("No More Avaliable Memory"); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| |
| // each thread has its own GPU context, so do not need any lock as guarder here |
| pContext->OsGpuContext[i].pAllocationList = |
| (ALLOCATION_LIST*)MOS_AllocAndZeroMemory(sizeof(ALLOCATION_LIST) * ALLOCATIONLIST_SIZE); |
| if (nullptr == pContext->OsGpuContext[i].pAllocationList) |
| { |
| MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pAllocationList malloc failed.", i); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| pContext->OsGpuContext[i].uiMaxNumAllocations = ALLOCATIONLIST_SIZE; |
| |
| pContext->OsGpuContext[i].pPatchLocationList = |
| (PATCHLOCATIONLIST*)MOS_AllocAndZeroMemory(sizeof(PATCHLOCATIONLIST) * PATCHLOCATIONLIST_SIZE); |
| if (nullptr == pContext->OsGpuContext[i].pPatchLocationList) |
| { |
| MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pPatchLocationList malloc failed.", i); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| pContext->OsGpuContext[i].uiMaxPatchLocationsize = PATCHLOCATIONLIST_SIZE; |
| |
| pContext->OsGpuContext[i].pResources = |
| (PMOS_RESOURCE)MOS_AllocAndZeroMemory(sizeof(MOS_RESOURCE) * ALLOCATIONLIST_SIZE); |
| if (nullptr == pContext->OsGpuContext[i].pResources) |
| { |
| MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pResources malloc failed.", i); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| |
| pContext->OsGpuContext[i].pbWriteMode = |
| (int32_t*)MOS_AllocAndZeroMemory(sizeof(int32_t) * ALLOCATIONLIST_SIZE); |
| if (nullptr == pContext->OsGpuContext[i].pbWriteMode) |
| { |
| MOS_OS_ASSERTMESSAGE("pContext->OsGpuContext[%d].pbWriteMode malloc failed.", i); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| |
| pContext->OsGpuContext[i].uiGPUStatusTag = 1; |
| } |
| } |
| |
| #if !defined(ANDROID) |
| { |
| drm_i915_getparam_t gp; |
| int32_t ret = -1; |
| int32_t value = 0; |
| |
| //KMD support VCS2? |
| gp.value = &value; |
| gp.param = I915_PARAM_HAS_BSD2; |
| if (pContext->fd < 0) |
| { |
| MOS_OS_ASSERTMESSAGE("pContext->fd is not valid."); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| #if defined(USE_MAGMA) |
| { |
| uint32_t unsigned_value; |
| if (query_magma_fd(pContext->fd, gp.param, &unsigned_value)) { |
| ret = 0; |
| value = unsigned_value; |
| } |
| } |
| #else |
| ret = drmIoctl(pContext->fd, DRM_IOCTL_I915_GETPARAM, &gp); |
| #endif |
| if (ret == 0 && value != 0) |
| { |
| pContext->bKMDHasVCS2 = true; |
| } |
| else |
| { |
| pContext->bKMDHasVCS2 = false; |
| } |
| } |
| if (pContext->bKMDHasVCS2) |
| { |
| eStatus = CreateIPC(pContext); |
| MOS_CHK_STATUS_SAFE(eStatus); |
| } |
| #endif |
| |
| pContext->pTranscryptedKernels = nullptr; |
| pContext->uiTranscryptedKernelsSize = 0; |
| |
| // For Media Memory compression |
| pContext->ppMediaMemDecompState = pOsDriverContext->ppMediaMemDecompState; |
| pContext->pfnMemoryDecompress = pOsDriverContext->pfnMemoryDecompress; |
| pContext->pfnMediaMemoryCopy = pOsDriverContext->pfnMediaMemoryCopy; |
| pContext->pfnMediaMemoryCopy2D = pOsDriverContext->pfnMediaMemoryCopy2D; |
| |
| // Set interface functions |
| pContext->pfnDestroy = Linux_Destroy; |
| pContext->pfnGetCommandBuffer = Linux_GetCommandBuffer; |
| pContext->pfnReturnCommandBuffer = Linux_ReturnCommandBuffer; |
| pContext->pfnFlushCommandBuffer = Linux_FlushCommandBuffer; |
| pContext->pfnInsertCmdBufferToPool = Linux_InsertCmdBufferToPool; |
| pContext->pfnWaitAndReleaseCmdBuffer = Linux_WaitAndReleaseCmdBuffer; |
| pContext->pfnRefresh = Linux_Refresh; |
| pContext->GetDmaBufID = Linux_GetDmaBufID; |
| pContext->SetDmaBufID = Linux_SetDmaBufID; |
| pContext->SetPerfHybridKernelID = Linux_SetPerfHybridKernelID; |
| pContext->pfnGetGpuCtxBufferTag = Linux_GetGpuCtxBufferTag; |
| pContext->pfnIncGpuCtxBufferTag = Linux_IncGpuCtxBufferTag; |
| pContext->GetGPUTag = Linux_GetGPUTag; |
| pContext->GetGmmClientContext = Linux_GetGmmClientContext; |
| pContext->GetOcaInterface = Linux_GetOcaInterface; |
| |
| finish: |
| if (!modularizedGpuCtxEnabled) |
| { |
| // init context failed, roll back |
| if (eStatus != MOS_STATUS_SUCCESS) |
| Mos_Specific_ClearGpuContext(pContext); |
| } |
| |
| return eStatus; |
| } |
| //============= PRIVATE FUNCTIONS <END>========================================= |
| |
| //! |
| //! \brief Set GPU context |
| //! \details Set GPU context for the following rendering operations |
| //! \param MOS_OS_CONTEXT * pContext |
| //! [in] Pointer to OS context structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SetGpuContext( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (GpuContext == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| // Set GPU context handle |
| pOsInterface->CurrentGpuContextOrdinal = GpuContext; |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr); |
| |
| auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| MOS_OS_CHK_NULL_RETURN(pOsContextSpecific); |
| |
| // Set GPU context handle |
| pOsInterface->CurrentGpuContextHandle = pOsContextSpecific->GetGpuContextHandle(GpuContext); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| MOS_OS_CHK_STATUS_RETURN(MosInterface::SetGpuContext( |
| pOsInterface->osStreamState, |
| pOsContextSpecific->GetGpuContextHandle(GpuContext))); |
| } |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS Mos_Specific_SetGpuContextFromHandle(MOS_INTERFACE *osInterface, |
| MOS_GPU_CONTEXT contextName, |
| GPU_CONTEXT_HANDLE contextHandle) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| MOS_OS_CHK_NULL_RETURN(osInterface); |
| |
| if (MOS_GPU_CONTEXT_INVALID_HANDLE == contextName) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter contextName."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| // Set GPU context handle |
| osInterface->CurrentGpuContextOrdinal = contextName; |
| |
| if (osInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| MOS_OS_CHK_NULL_RETURN(osInterface->osContextPtr); |
| |
| auto os_context_specific |
| = static_cast<OsContextSpecific*>(osInterface->osContextPtr); |
| MOS_OS_CHK_NULL_RETURN(os_context_specific); |
| |
| // Set GPU context handle |
| osInterface->CurrentGpuContextHandle = contextHandle; |
| |
| if (osInterface->apoMosEnabled) |
| { |
| MOS_OS_CHK_STATUS_RETURN( |
| MosInterface::SetGpuContext(osInterface->osStreamState, |
| contextHandle)); |
| } |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get current GPU context |
| //! \details Get current GPU context for the following rendering operations |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return MOS_GPU_CONTEXT |
| //! Return current GPU context |
| //! |
| MOS_GPU_CONTEXT Mos_Specific_GetGpuContext( |
| PMOS_INTERFACE pOsInterface) |
| { |
| if (pOsInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("OsInterface is null."); |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| |
| return pOsInterface->CurrentGpuContextOrdinal; |
| } |
| |
| //! |
| //! \brief Set GPU context Handle |
| //! \details Set GPU context handle for the following rendering operations |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param GPU_CONTEXT_HANDLE gpuContextHandle |
| //! [in] GPU Context Handle |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SetGpuContextHandle( |
| PMOS_INTERFACE pOsInterface, |
| GPU_CONTEXT_HANDLE gpuContextHandle, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr); |
| |
| auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| MOS_OS_CHK_NULL_RETURN(pOsContextSpecific); |
| |
| pOsContextSpecific->SetGpuContextHandle(GpuContext, gpuContextHandle); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get GPU context pointer |
| //! \details Get GPU context pointer |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param GPU_CONTEXT_HANDLE gpuContextHandle |
| //! [in] GPU Context Handle |
| //! \return void * |
| //! a pointer to a gpu context |
| //! |
| void *Mos_Specific_GetGpuContextbyHandle( |
| PMOS_INTERFACE pOsInterface, |
| GPU_CONTEXT_HANDLE gpuContextHandle) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| if (!pOsInterface) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid nullptr"); |
| return nullptr; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetGpuContextbyHandle(pOsInterface->osStreamState, gpuContextHandle); |
| } |
| |
| OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr); |
| if(!pOsContextSpecific) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid nullptr"); |
| return nullptr; |
| } |
| |
| GpuContextMgr *gpuContextMgr = pOsContextSpecific->GetGpuContextMgr(); |
| if (!gpuContextMgr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid nullptr"); |
| return nullptr; |
| } |
| |
| GpuContext *gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle); |
| if (!gpuContext) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid nullptr"); |
| return nullptr; |
| } |
| |
| return (void *)gpuContext; |
| } |
| |
| //! |
| //! \brief Get GPU context Manager |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return GpuContextMgr |
| //! GPU context Manager got from Os interface |
| //! |
| GpuContextMgr* Mos_Specific_GetGpuContextMgr( |
| PMOS_INTERFACE pOsInterface) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| if (pOsInterface && pOsInterface->osContextPtr) |
| { |
| auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| return pOsContextSpecific->GetGpuContextMgr(); |
| } |
| else |
| { |
| return nullptr; |
| } |
| } |
| |
| //! |
| //! \brief Get current GMM client context |
| //! \details Get current GMM client context |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return GMM_CLIENT_CONTEXT |
| //! Return current GMM client context |
| //! |
| GMM_CLIENT_CONTEXT *Mos_Specific_GetGmmClientContext( |
| PMOS_INTERFACE pOsInterface) |
| { |
| if (pOsInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("OsInterface is null."); |
| return nullptr; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetGmmClientContext(pOsInterface->osStreamState); |
| } |
| |
| if (pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr); |
| if (pOsContextSpecific) |
| { |
| return pOsContextSpecific->GetGmmClientContext(); |
| } |
| } |
| else |
| { |
| if (pOsInterface->pOsContext) |
| { |
| return pOsInterface->pOsContext->GetGmmClientContext(pOsInterface->pOsContext); |
| } |
| } |
| return nullptr; |
| } |
| |
| //! |
| //! \brief Get Platform |
| //! \details Get platform info |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PLATFORM pPlatform |
| //! [out] Pointer to platform |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| void Mos_Specific_GetPlatform( |
| PMOS_INTERFACE pOsInterface, |
| PLATFORM *pPlatform) |
| { |
| MOS_STATUS eStatus; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsInterface->pOsContext); |
| MOS_OS_CHK_NULL(pPlatform); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| // apo wrapper |
| auto platform = MosInterface::GetPlatform(pOsInterface->osStreamState); |
| if (platform) |
| { |
| *pPlatform = *platform; |
| } |
| return; |
| } |
| |
| *pPlatform = pOsInterface->pOsContext->platform; |
| |
| finish: |
| return; |
| } |
| |
| MOS_STATUS Mos_DestroyInterface(PMOS_INTERFACE pOsInterface) |
| { |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| MOS_STREAM_HANDLE streamState = pOsInterface->osStreamState; |
| MOS_OS_CHK_NULL_RETURN(streamState); |
| |
| auto deviceContext = streamState->osDeviceContext; |
| MOS_OS_CHK_NULL_RETURN(deviceContext); |
| |
| if (!Mos_Solo_IsEnabled((PMOS_CONTEXT)streamState->perStreamParameters)) |
| { |
| OsContext *pOsContext = pOsInterface->osContextPtr; |
| MOS_OS_CHK_NULL_RETURN(pOsContext); |
| // APO MOS destory GPU contexts here instead of inside osContextPtr |
| OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsContext); |
| |
| auto gpuContextMgr = deviceContext->GetGpuContextMgr(); |
| for (uint32_t i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| if (pOsContextSpecific->GetGpuContextHandleByIndex(i) != MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| if (gpuContextMgr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("GpuContextMgr is null when destroy GpuContext"); |
| break; |
| } |
| auto gpuContext = gpuContextMgr->GetGpuContext(pOsContextSpecific->GetGpuContextHandleByIndex(i)); |
| if (gpuContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active gpuContextHandle"); |
| continue; |
| } |
| gpuContextMgr->DestroyGpuContext(gpuContext); |
| pOsContextSpecific->SetGpuContextHandleByIndex(i, MOS_GPU_CONTEXT_INVALID_HANDLE); |
| } |
| } |
| |
| pOsContext->CleanUp(); |
| |
| MOS_Delete(pOsContext); |
| pOsInterface->osContextPtr = nullptr; |
| } |
| |
| if (pOsInterface->osCpInterface) |
| { |
| Delete_MosCpInterface(pOsInterface->osCpInterface); |
| pOsInterface->osCpInterface = NULL; |
| } |
| |
| PMOS_CONTEXT perStreamParameters = (PMOS_CONTEXT)streamState->perStreamParameters; |
| |
| if (perStreamParameters && perStreamParameters->bFreeContext) |
| { |
| perStreamParameters->SkuTable.reset(); |
| perStreamParameters->WaTable.reset(); |
| Mos_Specific_ClearGpuContext(perStreamParameters); |
| |
| if (perStreamParameters->contextOffsetList.size()) |
| { |
| perStreamParameters->contextOffsetList.clear(); |
| perStreamParameters->contextOffsetList.shrink_to_fit(); |
| } |
| |
| if(Mos_Solo_IsEnabled(perStreamParameters)) |
| { |
| Linux_ReleaseCmdBufferPool(perStreamParameters); |
| PCOMMAND_BUFFER pCurrCB = nullptr; |
| PCOMMAND_BUFFER pNextCB = nullptr; |
| for (uint32_t i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| MOS_FreeMemAndSetNull(perStreamParameters->OsGpuContext[i].pCB); |
| |
| pCurrCB = perStreamParameters->OsGpuContext[i].pStartCB; |
| for (; (pCurrCB); pCurrCB = pNextCB) |
| { |
| pNextCB = pCurrCB->pNext; |
| MOS_FreeMemAndSetNull(pCurrCB); |
| } |
| } |
| Linux_ReleaseGPUStatus(perStreamParameters); |
| } |
| if (perStreamParameters->intel_context) |
| { |
| if (perStreamParameters->intel_context->vm) |
| { |
| mos_gem_vm_destroy(perStreamParameters->intel_context->bufmgr, perStreamParameters->intel_context->vm); |
| perStreamParameters->intel_context->vm = nullptr; |
| } |
| mos_gem_context_destroy(perStreamParameters->intel_context); |
| perStreamParameters->intel_context = nullptr; |
| } |
| perStreamParameters->GmmFuncs.pfnDeleteClientContext(perStreamParameters->pGmmClientContext); |
| MOS_FreeMemAndSetNull(perStreamParameters); |
| streamState->perStreamParameters = nullptr; |
| } |
| |
| MosInterface::DestroyVirtualEngineState(streamState); |
| MOS_FreeMemAndSetNull(pOsInterface->pVEInterf); |
| |
| MOS_OS_CHK_STATUS_RETURN(MosInterface::DestroyOsStreamState(streamState)); |
| pOsInterface->osStreamState = nullptr; |
| return MOS_STATUS_SUCCESS; |
| } |
| //! |
| //! \brief Destroys OS specific allocations |
| //! \details Destroys OS specific allocations including destroying OS context |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param int32_t bDestroyVscVppDeviceTag |
| //! [in] Destroy VscVppDeviceTagId Flag, no use in Linux |
| //! \return void |
| //! |
| void Mos_Specific_Destroy( |
| PMOS_INTERFACE pOsInterface, |
| int32_t bDestroyVscVppDeviceTag) |
| { |
| MOS_UNUSED(bDestroyVscVppDeviceTag); |
| |
| if (nullptr == pOsInterface) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter, pOsInterface is NULL."); |
| return; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| MOS_STATUS status = Mos_DestroyInterface(pOsInterface); |
| if (status != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Mos Destroy Interface failed."); |
| } |
| return; |
| } |
| |
| if (pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| OsContext* pOsContext = pOsInterface->osContextPtr; |
| if (pOsContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Unable to get the active OS context."); |
| return; |
| } |
| |
| // APO MOS destory GPU contexts here instead of inside osContextPtr |
| if (pOsInterface->apoMosEnabled) |
| { |
| OsContextSpecific* pOsContextSpecific = static_cast<OsContextSpecific*>(pOsContext); |
| if (pOsInterface->osStreamState == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("osStreamState is null when destroy GpuContext"); |
| return; |
| } |
| if (pOsInterface->osStreamState->osDeviceContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("osDeviceContext is null when destroy GpuContext"); |
| return; |
| } |
| auto gpuContextMgr = pOsInterface->osStreamState->osDeviceContext->GetGpuContextMgr(); |
| for (uint32_t i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| if (pOsContextSpecific->GetGpuContextHandleByIndex(i) != MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| if (gpuContextMgr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("GpuContextMgr is null when destroy GpuContext"); |
| break; |
| } |
| auto gpuContext = gpuContextMgr->GetGpuContext(pOsContextSpecific->GetGpuContextHandleByIndex(i)); |
| if (gpuContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("cannot find the gpuContext corresponding to the active gpuContextHandle"); |
| continue; |
| } |
| gpuContextMgr->DestroyGpuContext(gpuContext); |
| pOsContextSpecific->SetGpuContextHandleByIndex(i, MOS_GPU_CONTEXT_INVALID_HANDLE); |
| } |
| } |
| } |
| pOsContext->CleanUp(); |
| |
| MOS_Delete(pOsContext); |
| pOsInterface->osContextPtr = nullptr; |
| } |
| |
| if (pOsInterface->osCpInterface) |
| { |
| Delete_MosCpInterface(pOsInterface->osCpInterface); |
| pOsInterface->osCpInterface = NULL; |
| } |
| |
| if (pOsInterface && |
| pOsInterface->pOsContext && |
| pOsInterface->pOsContext->bFreeContext) |
| { |
| pOsInterface->pOsContext->SkuTable.reset(); |
| pOsInterface->pOsContext->WaTable.reset(); |
| Mos_Specific_ClearGpuContext(pOsInterface->pOsContext); |
| bool modularizedGpuCtxEnabled = pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr); |
| pOsInterface->pOsContext->pfnDestroy(pOsInterface->pOsContext, pOsInterface->modulizedMosEnabled, modularizedGpuCtxEnabled); |
| pOsInterface->pOsContext = nullptr; |
| } |
| if (pOsInterface->pVEInterf) |
| { |
| if (pOsInterface->apoMosEnabled && pOsInterface->pVEInterf->veInterface) |
| { |
| pOsInterface->pVEInterf->veInterface->Destroy(); |
| MOS_Delete(pOsInterface->pVEInterf->veInterface); |
| } |
| MOS_FreeMemAndSetNull(pOsInterface->pVEInterf); |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| auto status = MosInterface::DestroyOsStreamState(pOsInterface->osStreamState); |
| if (status != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to destroy stream state."); |
| return; |
| } |
| } |
| } |
| |
| //! |
| //! \brief Gets the SKU table |
| //! \details Gets the SKU table for the platform |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return MEDIA_FEATURE_TABLE * |
| //! Returns the pointer to sku table |
| //! |
| MEDIA_FEATURE_TABLE *Mos_Specific_GetSkuTable( |
| PMOS_INTERFACE pOsInterface) |
| { |
| if (pOsInterface && pOsInterface->apoMosEnabled) |
| { |
| // apo wrapper |
| return MosInterface::GetSkuTable(pOsInterface->osStreamState); |
| } |
| |
| if (pOsInterface && pOsInterface->pOsContext) |
| { |
| return &pOsInterface->pOsContext->SkuTable; |
| } |
| return nullptr; |
| } |
| |
| //! |
| //! \brief Gets the WA table |
| //! \details Gets the WA table for the platform |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return MEDIA_WA_TABLE * |
| //! Returns the pointer to WA table |
| //! |
| MEDIA_WA_TABLE *Mos_Specific_GetWaTable( |
| PMOS_INTERFACE pOsInterface) |
| { |
| if (pOsInterface && pOsInterface->apoMosEnabled) |
| { |
| // apo wrapper |
| return MosInterface::GetWaTable(pOsInterface->osStreamState); |
| } |
| |
| if (pOsInterface && pOsInterface->pOsContext) |
| { |
| return &pOsInterface->pOsContext->WaTable; |
| } |
| return nullptr; |
| } |
| |
| //! |
| //! \brief Gets the GT System Info |
| //! \details Gets the GT System Info |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \return MEDIA_SYSTEM_INFO * |
| //! pointer to the GT System Info |
| //! |
| MEDIA_SYSTEM_INFO *Mos_Specific_GetGtSystemInfo( |
| PMOS_INTERFACE pOsInterface) |
| { |
| if( nullptr == pOsInterface) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL."); |
| return nullptr; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| // apo wrapper |
| return MosInterface::GetGtSystemInfo(pOsInterface->osStreamState); |
| } |
| |
| if( nullptr == pOsInterface->pOsContext) |
| { |
| MOS_OS_ASSERTMESSAGE("pOsContext is NULL."); |
| return nullptr; |
| } |
| |
| return &pOsInterface->pOsContext->gtSystemInfo; |
| } |
| |
| MOS_STATUS Mos_Specific_GetMediaEngineInfo( |
| PMOS_INTERFACE pOsInterface, MEDIA_ENGINE_INFO &info) |
| { |
| if (pOsInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid pointer!"); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| // apo wrapper |
| MOS_OS_CHK_STATUS_RETURN(MosInterface::GetMediaEngineInfo(pOsInterface->osStreamState, info)); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| auto systemInfo = pOsInterface->pfnGetGtSystemInfo(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(systemInfo); |
| MosUtilities::MosZeroMemory(&info, sizeof(info)); |
| info.VDBoxInfo = systemInfo->VDBoxInfo; |
| info.VEBoxInfo = systemInfo->VEBoxInfo; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Resets OS States |
| //! \details Resets OS States for linux |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return void |
| //! |
| void Mos_Specific_ResetOsStates( |
| PMOS_INTERFACE pOsInterface) // [in] OS Interface |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| PMOS_OS_CONTEXT pOsContext; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext; |
| |
| if (pOsInterface == nullptr || |
| pOsInterface->pOsContext == nullptr) |
| { |
| return; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| auto status = MosInterface::ResetCommandBuffer(pOsInterface->osStreamState, 0); |
| if (MOS_FAILED(status)) |
| { |
| MOS_OS_ASSERTMESSAGE("ResetCommandBuffer failed."); |
| } |
| return; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| if (gpuContext == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("GPU Context pointer is nullptr!"); |
| return; |
| } |
| |
| gpuContext->ResetGpuContextStatus(); |
| return; |
| } |
| |
| pOsContext = pOsInterface->pOsContext; |
| pOsGpuContext = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| // Reset resource allocation |
| pOsGpuContext->uiNumAllocations = 0; |
| MOS_ZeroMemory(pOsGpuContext->pAllocationList, sizeof(ALLOCATION_LIST) * pOsGpuContext->uiMaxNumAllocations); |
| pOsGpuContext->uiCurrentNumPatchLocations = 0; |
| MOS_ZeroMemory(pOsGpuContext->pPatchLocationList, sizeof(PATCHLOCATIONLIST) * pOsGpuContext->uiMaxPatchLocationsize); |
| pOsGpuContext->uiResCount = 0; |
| |
| MOS_ZeroMemory(pOsGpuContext->pResources, sizeof(MOS_RESOURCE) * pOsGpuContext->uiMaxNumAllocations); |
| MOS_ZeroMemory(pOsGpuContext->pbWriteMode, sizeof(int32_t) * pOsGpuContext->uiMaxNumAllocations); |
| |
| if((pOsGpuContext->bCBFlushed == true) && pOsGpuContext->pCB->OsResource.bo) |
| { |
| pOsGpuContext->pCB->OsResource.bo = nullptr; |
| } |
| |
| } |
| |
| //! |
| //! \brief Convert MOS format to gmm format |
| //! \details convert MOS format to gmm format |
| //! \param MOS_FORMAT format |
| //! [in] Surface |
| //! \return MEDIA_WA_TABLE * |
| //! Returns the pointer to WA table |
| //! |
| GMM_RESOURCE_FORMAT Mos_Specific_ConvertMosFmtToGmmFmt( |
| MOS_FORMAT format) |
| { |
| switch (format) |
| { |
| case Format_Buffer : return GMM_FORMAT_GENERIC_8BIT; |
| case Format_Buffer_2D : return GMM_FORMAT_GENERIC_8BIT; // matching size as format |
| case Format_L8 : return GMM_FORMAT_GENERIC_8BIT; // matching size as format |
| case Format_L16 : return GMM_FORMAT_L16_UNORM_TYPE; |
| case Format_STMM : return GMM_FORMAT_R8_UNORM_TYPE; // matching size as format |
| case Format_AI44 : return GMM_FORMAT_GENERIC_8BIT; // matching size as format |
| case Format_IA44 : return GMM_FORMAT_GENERIC_8BIT; // matching size as format |
| case Format_R5G6B5 : return GMM_FORMAT_B5G6R5_UNORM_TYPE; |
| case Format_R8G8B8 : return GMM_FORMAT_R8G8B8_UNORM; |
| case Format_X8R8G8B8 : return GMM_FORMAT_B8G8R8X8_UNORM_TYPE; |
| case Format_A8R8G8B8 : return GMM_FORMAT_B8G8R8A8_UNORM_TYPE; |
| case Format_X8B8G8R8 : return GMM_FORMAT_R8G8B8X8_UNORM_TYPE; |
| case Format_A8B8G8R8 : return GMM_FORMAT_R8G8B8A8_UNORM_TYPE; |
| case Format_R32F : return GMM_FORMAT_R32_FLOAT_TYPE; |
| case Format_V8U8 : return GMM_FORMAT_GENERIC_16BIT; // matching size as format |
| case Format_YUY2 : return GMM_FORMAT_YUY2; |
| case Format_UYVY : return GMM_FORMAT_UYVY; |
| case Format_P8 : return GMM_FORMAT_RENDER_8BIT_TYPE; // matching size as format |
| case Format_A8 : return GMM_FORMAT_A8_UNORM_TYPE; |
| case Format_AYUV : return GMM_FORMAT_R8G8B8A8_UINT_TYPE; |
| case Format_NV12 : return GMM_FORMAT_NV12_TYPE; |
| case Format_NV21 : return GMM_FORMAT_NV21_TYPE; |
| case Format_YV12 : return GMM_FORMAT_YV12_TYPE; |
| case Format_R32U : return GMM_FORMAT_R32_UINT_TYPE; |
| case Format_R32S : return GMM_FORMAT_R32_SINT_TYPE; |
| case Format_RAW : return GMM_FORMAT_GENERIC_8BIT; |
| case Format_444P : return GMM_FORMAT_MFX_JPEG_YUV444_TYPE; |
| case Format_422H : return GMM_FORMAT_MFX_JPEG_YUV422H_TYPE; |
| case Format_422V : return GMM_FORMAT_MFX_JPEG_YUV422V_TYPE; |
| case Format_IMC3 : return GMM_FORMAT_IMC3_TYPE; |
| case Format_411P : return GMM_FORMAT_MFX_JPEG_YUV411_TYPE; |
| case Format_411R : return GMM_FORMAT_MFX_JPEG_YUV411R_TYPE; |
| case Format_RGBP : return GMM_FORMAT_RGBP_TYPE; |
| case Format_BGRP : return GMM_FORMAT_BGRP_TYPE; |
| case Format_R8U : return GMM_FORMAT_R8_UINT_TYPE; |
| case Format_R8UN : return GMM_FORMAT_R8_UNORM; |
| case Format_R16U : return GMM_FORMAT_R16_UINT_TYPE; |
| case Format_R16F : return GMM_FORMAT_R16_FLOAT_TYPE; |
| case Format_P010 : return GMM_FORMAT_P010_TYPE; |
| case Format_P016 : return GMM_FORMAT_P016_TYPE; |
| case Format_Y216 : return GMM_FORMAT_Y216_TYPE; |
| case Format_Y416 : return GMM_FORMAT_Y416_TYPE; |
| case Format_P208 : return GMM_FORMAT_P208_TYPE; |
| case Format_Y210 : return GMM_FORMAT_Y210_TYPE; |
| case Format_Y410 : return GMM_FORMAT_Y410_TYPE; |
| default : return GMM_FORMAT_INVALID; |
| } |
| } |
| |
| //! |
| //! \brief Allocate resource |
| //! \details To Allocate Buffer, pass Format as Format_Buffer and set the iWidth as size of the buffer. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_ALLOC_GFXRES_PARAMS pParams |
| //! [in] Pointer to resource params |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in/out] Pointer to OS resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_AllocateResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_ALLOC_GFXRES_PARAMS pParams, |
| #if MOS_MESSAGES_ENABLED |
| PCCHAR functionName, |
| PCCHAR filename, |
| int32_t line, |
| #endif // MOS_MESSAGES_ENABLED |
| PMOS_RESOURCE pOsResource) |
| { |
| void * caller = nullptr; |
| const char * bufname; |
| void * ptr; |
| int32_t iSize = 0; |
| int32_t iPitch = 0; |
| unsigned long ulPitch = 0; |
| MOS_STATUS eStatus; |
| MOS_LINUX_BO * bo = nullptr; |
| MOS_TILE_TYPE tileformat; |
| uint32_t tileformat_linux = 0; |
| int32_t iHeight = 0; |
| int32_t iAlignedHeight = 0; |
| GMM_RESCREATE_PARAMS GmmParams; |
| GMM_RESOURCE_INFO * pGmmResourceInfo = nullptr; |
| GMM_RESOURCE_TYPE resourceType = RESOURCE_INVALID; |
| int mem_type = MOS_MEMPOOL_VIDEOMEMORY; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_ZeroMemory(&GmmParams, sizeof(GmmParams)); |
| |
| if( nullptr == pOsResource) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOSResource is NULL."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if( nullptr == pOsInterface) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| bufname = pParams->pBufName; |
| pOsResource->bConvertedFromDDIResource = false; |
| |
| bool osContextValid = false; |
| if (pOsInterface->osContextPtr != nullptr) |
| { |
| if (pOsInterface->osContextPtr->GetOsContextValid() == true) |
| { |
| osContextValid = true; |
| } |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| pParams->bBypassMODImpl = !((pOsInterface->modulizedMosEnabled) && (!Mos_Solo_IsEnabled(nullptr)) && (osContextValid == true)); |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface->osStreamState); |
| |
| pOsInterface->osStreamState->component = pOsInterface->Component; |
| |
| eStatus = MosInterface::AllocateResource( |
| pOsInterface->osStreamState, |
| pParams, |
| pOsResource |
| #if MOS_MESSAGES_ENABLED |
| , |
| functionName, |
| filename, |
| line |
| #endif // MOS_MESSAGES_ENABLED |
| ); |
| |
| return eStatus; |
| } |
| |
| if ((pOsInterface->modulizedMosEnabled) && (!Mos_Solo_IsEnabled(nullptr)) && (osContextValid == true)) |
| { |
| pOsResource->pGfxResource = GraphicsResource::CreateGraphicResource(GraphicsResource::osSpecificResource); |
| if (pOsResource->pGfxResource == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("input nullptr returned by GraphicsResource::CreateGraphicResource."); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| if (pOsInterface->osContextPtr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid osContextPtr."); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| GraphicsResource::SetMemAllocCounterGfx(MosUtilities::m_mosMemAllocCounterGfx); |
| |
| GraphicsResource::CreateParams params(pParams); |
| eStatus = pOsResource->pGfxResource->Allocate(pOsInterface->osContextPtr, params); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Allocate graphic resource failed"); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| eStatus = pOsResource->pGfxResource->ConvertToMosResource(pOsResource); |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Convert graphic resource failed"); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| |
| MosUtilities::m_mosMemAllocCounterGfx = GraphicsResource::GetMemAllocCounterGfx(); |
| MOS_OS_CHK_NULL(pOsResource->pGmmResInfo); |
| MOS_MEMNINJA_GFX_ALLOC_MESSAGE(pOsResource->pGmmResInfo, bufname, pOsInterface->Component, |
| (uint32_t)pOsResource->pGmmResInfo->GetSizeSurface(), pParams->dwArraySize, functionName, filename, line); |
| |
| return eStatus; |
| } |
| |
| caller = nullptr; |
| tileformat_linux = I915_TILING_NONE; |
| iAlignedHeight = iHeight = pParams->dwHeight; |
| eStatus = MOS_STATUS_SUCCESS; |
| resourceType = RESOURCE_2D; |
| tileformat = pParams->TileType; |
| |
| MOS_ZeroMemory(&GmmParams, sizeof(GmmParams)); |
| |
| if( nullptr == pOsInterface->pOsContext ) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| switch (pParams->Format) |
| { |
| case Format_Buffer: |
| case Format_RAW: |
| resourceType = RESOURCE_BUFFER; |
| iAlignedHeight = 1; |
| //indicate buffer Restriction is Vertex. |
| GmmParams.Flags.Gpu.State = true; |
| break; |
| case Format_L8: |
| case Format_L16: |
| case Format_STMM: |
| case Format_AI44: |
| case Format_IA44: |
| case Format_R5G6B5: |
| case Format_R8G8B8: |
| case Format_X8R8G8B8: |
| case Format_A8R8G8B8: |
| case Format_X8B8G8R8: |
| case Format_A8B8G8R8: |
| case Format_R32S: |
| case Format_R32F: |
| case Format_V8U8: |
| case Format_YUY2: |
| case Format_UYVY: |
| case Format_P8: |
| case Format_A8: |
| case Format_AYUV: |
| case Format_NV12: |
| case Format_NV21: |
| case Format_YV12: |
| case Format_Buffer_2D: |
| case Format_R32U: |
| case Format_444P: |
| case Format_422H: |
| case Format_422V: |
| case Format_IMC3: |
| case Format_411P: |
| case Format_411R: |
| case Format_RGBP: |
| case Format_BGRP: |
| case Format_R16U: |
| case Format_R8U: |
| case Format_R8UN: |
| case Format_P010: |
| case Format_P016: |
| case Format_Y216: |
| case Format_Y416: |
| case Format_P208: |
| case Format_Y210: |
| case Format_Y410: |
| case Format_R16F: |
| resourceType = RESOURCE_2D; |
| //indicate buffer Restriction is Planar surface restrictions. |
| GmmParams.Flags.Gpu.Video = true; |
| break; |
| default: |
| MOS_OS_ASSERTMESSAGE("Unsupported format"); |
| eStatus = MOS_STATUS_UNIMPLEMENTED; |
| goto finish; |
| } |
| |
| // Create GmmResourceInfo |
| GmmParams.BaseWidth = pParams->dwWidth; |
| GmmParams.BaseHeight = iAlignedHeight; |
| GmmParams.ArraySize = 1; |
| GmmParams.Type = resourceType; |
| GmmParams.Format = Mos_Specific_ConvertMosFmtToGmmFmt(pParams->Format); |
| |
| MOS_OS_CHECK_CONDITION(GmmParams.Format == GMM_FORMAT_INVALID, |
| "Unsupported format", |
| MOS_STATUS_UNKNOWN); |
| |
| switch(tileformat) |
| { |
| case MOS_TILE_Y: |
| tileformat_linux = I915_TILING_Y; |
| if (pParams->bIsCompressible && MEDIA_IS_SKU(&pOsInterface->pOsContext->SkuTable, FtrE2ECompression)) |
| { |
| GmmParams.Flags.Gpu.MMC = true; |
| GmmParams.Flags.Info.MediaCompressed = 1; |
| GmmParams.Flags.Gpu.CCS = 1; |
| GmmParams.Flags.Gpu.RenderTarget = 1; |
| GmmParams.Flags.Gpu.UnifiedAuxSurface = 1; |
| |
| if(MEDIA_IS_SKU(&pOsInterface->pOsContext->SkuTable, FtrFlatPhysCCS)) |
| { |
| GmmParams.Flags.Gpu.UnifiedAuxSurface = 0; |
| } |
| } |
| break; |
| case MOS_TILE_X: |
| GmmParams.Flags.Info.TiledX = true; |
| tileformat_linux = I915_TILING_X; |
| break; |
| default: |
| GmmParams.Flags.Info.Linear = true; |
| tileformat_linux = I915_TILING_NONE; |
| } |
| GmmParams.Flags.Info.LocalOnly = MEDIA_IS_SKU(&pOsInterface->pOsContext->SkuTable, FtrLocalMemory); |
| |
| pOsResource->pGmmResInfo = pGmmResourceInfo = pOsInterface->pOsContext->pGmmClientContext->CreateResInfoObject(&GmmParams); |
| |
| MOS_OS_CHK_NULL(pGmmResourceInfo); |
| |
| switch (pGmmResourceInfo->GetTileType()) |
| { |
| case GMM_TILED_X: |
| tileformat = MOS_TILE_X; |
| tileformat_linux = I915_TILING_X; |
| break; |
| case GMM_TILED_Y: |
| tileformat = MOS_TILE_Y; |
| tileformat_linux = I915_TILING_Y; |
| break; |
| case GMM_NOT_TILED: |
| tileformat = MOS_TILE_LINEAR; |
| tileformat_linux = I915_TILING_NONE; |
| break; |
| default: |
| tileformat = MOS_TILE_Y; |
| tileformat_linux = I915_TILING_Y; |
| break; |
| } |
| |
| if (pParams->TileType == MOS_TILE_Y) |
| { |
| pGmmResourceInfo->SetMmcMode((GMM_RESOURCE_MMC_INFO)pParams->CompressionMode, 0); |
| } |
| |
| iPitch = GFX_ULONG_CAST(pGmmResourceInfo->GetRenderPitch()); |
| iSize = GFX_ULONG_CAST(pGmmResourceInfo->GetSizeSurface()); |
| iHeight = pGmmResourceInfo->GetBaseHeight(); |
| |
| MemoryPolicyParameter memPolicyPar; |
| MOS_ZeroMemory(&memPolicyPar, sizeof(MemoryPolicyParameter)); |
| |
| memPolicyPar.skuTable = &pOsInterface->pOsContext->SkuTable; |
| memPolicyPar.waTable = &pOsInterface->pOsContext->WaTable; |
| memPolicyPar.resInfo = pGmmResourceInfo; |
| memPolicyPar.resName = pParams->pBufName; |
| memPolicyPar.preferredMemType = pParams->dwMemType; |
| |
| mem_type = MemoryPolicyManager::UpdateMemoryPolicy(&memPolicyPar); |
| |
| // Only Linear and Y TILE supported |
| if( tileformat_linux == I915_TILING_NONE ) |
| { |
| bo = mos_bo_alloc(pOsInterface->pOsContext->bufmgr, bufname, iSize, 4096, mem_type); |
| } |
| else |
| { |
| bo = mos_bo_alloc_tiled(pOsInterface->pOsContext->bufmgr, bufname, iPitch, iSize/iPitch, 1, &tileformat_linux, &ulPitch, 0, mem_type); |
| iPitch = (int32_t)ulPitch; |
| } |
| |
| pOsResource->bMapped = false; |
| if (bo) |
| { |
| pOsResource->Format = pParams->Format; |
| pOsResource->iWidth = pParams->dwWidth; |
| pOsResource->iHeight = iHeight; |
| pOsResource->iPitch = iPitch; |
| pOsResource->iCount = 0; |
| pOsResource->bufname = bufname; |
| pOsResource->bo = bo; |
| pOsResource->TileType = tileformat; |
| pOsResource->TileModeGMM = (MOS_TILE_MODE_GMM)pGmmResourceInfo->GetTileModeSurfaceState(); |
| pOsResource->bGMMTileEnabled = true; |
| pOsResource->pData = (uint8_t*) bo->virt; //It is useful for batch buffer to fill commands |
| MOS_OS_VERBOSEMESSAGE("Alloc %7d bytes (%d x %d resource).",iSize, pParams->dwWidth, iHeight); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Fail to Alloc %7d bytes (%d x %d resource).",iSize, pParams->dwWidth, pParams->dwHeight); |
| eStatus = MOS_STATUS_NO_SPACE; |
| } |
| |
| MosUtilities::m_mosMemAllocCounterGfx++; |
| MOS_MEMNINJA_GFX_ALLOC_MESSAGE(pOsResource->pGmmResInfo, bufname, pOsInterface->Component, |
| (uint32_t)pOsResource->pGmmResInfo->GetSizeSurface(), pParams->dwArraySize, functionName, filename, line); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Get Resource Information |
| //! \details Linux get resource info |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to input OS resource |
| //! \param PMOS_SURFACE pResDetails |
| //! [out] Pointer to output resource information details |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetResourceInfo( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| PMOS_SURFACE pResDetails) |
| { |
| GMM_RESOURCE_INFO * pGmmResourceInfo = nullptr; |
| GMM_DISPLAY_FRAME gmmChannel = GMM_DISPLAY_FRAME_MAX; |
| GMM_REQ_OFFSET_INFO reqInfo[3] = {}; |
| GMM_RESOURCE_FLAG GmmFlags = {}; |
| MOS_STATUS eStatus; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsResource); |
| MOS_OS_CHK_NULL(pResDetails); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetResourceInfo(pOsInterface->osStreamState, pOsResource, *pResDetails); |
| } |
| |
| // Get Gmm resource info |
| pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo; |
| MOS_OS_CHK_NULL(pGmmResourceInfo); |
| |
| GmmFlags = pGmmResourceInfo->GetResFlags(); |
| |
| pResDetails->dwWidth = GFX_ULONG_CAST(pGmmResourceInfo->GetBaseWidth()); |
| pResDetails->dwHeight = pGmmResourceInfo->GetBaseHeight(); |
| pResDetails->dwPitch = GFX_ULONG_CAST(pGmmResourceInfo->GetRenderPitch()); |
| pResDetails->dwSize = GFX_ULONG_CAST(pGmmResourceInfo->GetSizeSurface()); |
| pResDetails->dwDepth = MOS_MAX(1, pGmmResourceInfo->GetBaseDepth()); |
| pResDetails->dwLockPitch = GFX_ULONG_CAST(pGmmResourceInfo->GetRenderPitch()); |
| if (GFX_GET_CURRENT_RENDERCORE(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetPlatformInfo().Platform) < IGFX_GEN8_CORE) |
| { |
| pResDetails->bArraySpacing = pGmmResourceInfo->IsArraySpacingSingleLod(); |
| } |
| if (GFX_GET_CURRENT_RENDERCORE(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetPlatformInfo().Platform) >= IGFX_GEN9_CORE) |
| { |
| pResDetails->dwQPitch = pGmmResourceInfo->GetQPitch(); |
| } |
| |
| pResDetails->bCompressible = GmmFlags.Gpu.MMC ? |
| (pGmmResourceInfo->GetMmcHint(0) == GMM_MMC_HINT_ON) : false; |
| pResDetails->bIsCompressed = pGmmResourceInfo->IsMediaMemoryCompressed(0); |
| pResDetails->CompressionMode = (MOS_RESOURCE_MMC_MODE)pGmmResourceInfo->GetMmcMode(0); |
| |
| if (0 == pResDetails->dwPitch) |
| { |
| MOS_OS_ASSERTMESSAGE("Pitch from GmmResource is 0, unexpected."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| // check resource's tile type |
| pResDetails->TileModeGMM = (MOS_TILE_MODE_GMM)pGmmResourceInfo->GetTileModeSurfaceState(); |
| pResDetails->bGMMTileEnabled = true; |
| switch (pGmmResourceInfo->GetTileType()) |
| { |
| case GMM_TILED_Y: |
| if (GmmFlags.Info.TiledYf) |
| { |
| pResDetails->TileType = MOS_TILE_YF; |
| } |
| else if (GmmFlags.Info.TiledYs) |
| { |
| pResDetails->TileType = MOS_TILE_YS; |
| } |
| else |
| { |
| pResDetails->TileType = MOS_TILE_Y; |
| } |
| break; |
| case GMM_TILED_X: |
| pResDetails->TileType = MOS_TILE_X; |
| break; |
| case GMM_NOT_TILED: |
| pResDetails->TileType = MOS_TILE_LINEAR; |
| break; |
| default: |
| pResDetails->TileType = MOS_TILE_Y; |
| break; |
| } |
| pResDetails->Format = pOsResource->Format; |
| |
| MOS_ZeroMemory(reqInfo, sizeof(reqInfo)); |
| gmmChannel = GMM_DISPLAY_BASE; |
| // Get the base offset of the surface (plane Y) |
| reqInfo[2].ReqRender = true; |
| reqInfo[2].Plane = GMM_PLANE_Y; |
| reqInfo[2].Frame = gmmChannel; |
| reqInfo[2].CubeFace = __GMM_NO_CUBE_MAP; |
| reqInfo[2].ArrayIndex = 0; |
| pGmmResourceInfo->GetOffset(reqInfo[2]); |
| pResDetails->RenderOffset.YUV.Y.BaseOffset = reqInfo[2].Render.Offset; |
| |
| // Get U/UV plane information (plane offset, X/Y offset) |
| reqInfo[0].ReqRender = true; |
| reqInfo[0].Plane = GMM_PLANE_U; |
| reqInfo[0].Frame = gmmChannel; |
| reqInfo[0].CubeFace = __GMM_NO_CUBE_MAP; |
| reqInfo[0].ArrayIndex = 0; |
| pGmmResourceInfo->GetOffset(reqInfo[0]); |
| |
| pResDetails->RenderOffset.YUV.U.BaseOffset = reqInfo[0].Render.Offset; |
| pResDetails->RenderOffset.YUV.U.XOffset = reqInfo[0].Render.XOffset; |
| pResDetails->RenderOffset.YUV.U.YOffset = reqInfo[0].Render.YOffset; |
| |
| // Get V plane information (plane offset, X/Y offset) |
| reqInfo[1].ReqRender = true; |
| reqInfo[1].Plane = GMM_PLANE_V; |
| reqInfo[1].Frame = gmmChannel; |
| reqInfo[1].CubeFace = __GMM_NO_CUBE_MAP; |
| reqInfo[1].ArrayIndex = 0; |
| pGmmResourceInfo->GetOffset(reqInfo[1]); |
| |
| pResDetails->RenderOffset.YUV.V.BaseOffset = reqInfo[1].Render.Offset; |
| pResDetails->RenderOffset.YUV.V.XOffset = reqInfo[1].Render.XOffset; |
| pResDetails->RenderOffset.YUV.V.YOffset = reqInfo[1].Render.YOffset; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Free the resource |
| //! \details Free the allocated resource |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to input OS resource |
| //! \return void |
| //! |
| void Mos_Specific_FreeResource( |
| PMOS_INTERFACE pOsInterface, |
| #if MOS_MESSAGES_ENABLED |
| PCCHAR functionName, |
| PCCHAR filename, |
| int32_t line, |
| #endif // MOS_MESSAGES_ENABLED |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| if( nullptr == pOsInterface ) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL."); |
| return; |
| } |
| |
| if( nullptr == pOsResource ) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOsResource is NULL."); |
| return; |
| } |
| |
| bool osContextValid = false; |
| if (pOsInterface->osContextPtr != nullptr) |
| { |
| if (pOsInterface->osContextPtr->GetOsContextValid() == true) |
| { |
| osContextValid = true; |
| } |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| MosInterface::FreeResource( |
| pOsInterface->osStreamState, |
| pOsResource, |
| 0 |
| #if MOS_MESSAGES_ENABLED |
| , |
| functionName, |
| filename, |
| line |
| #endif |
| ); |
| |
| return; |
| } |
| |
| if ((pOsInterface->modulizedMosEnabled) |
| && (!pOsResource->bConvertedFromDDIResource) |
| && (osContextValid == true) |
| && (!Mos_Solo_IsEnabled(nullptr)) |
| && (pOsResource->pGfxResource)) |
| { |
| if (pOsInterface->osContextPtr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid osContextPtr."); |
| return; |
| } |
| |
| GraphicsResource::SetMemAllocCounterGfx(MosUtilities::m_mosMemAllocCounterGfx); |
| |
| if (pOsResource && pOsResource->pGfxResource) |
| { |
| pOsResource->pGfxResource->Free(pOsInterface->osContextPtr); |
| } |
| else |
| { |
| MOS_OS_VERBOSEMESSAGE("Received an empty Graphics Resource, skip free"); |
| } |
| MOS_Delete(pOsResource->pGfxResource); |
| pOsResource->pGfxResource = nullptr; |
| |
| MosUtilities::m_mosMemAllocCounterGfx = GraphicsResource::GetMemAllocCounterGfx(); |
| MOS_MEMNINJA_GFX_FREE_MESSAGE(pOsResource->pGmmResInfo, functionName, filename, line); |
| MOS_ZeroMemory(pOsResource, sizeof(*pOsResource)); |
| return; |
| } |
| |
| if (pOsResource && pOsResource->bo) |
| { |
| OsContextSpecific *osCtx = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr); |
| if(osCtx == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("osCtx is nullptr!"); |
| return; |
| } |
| else |
| { |
| AuxTableMgr *auxTableMgr = osCtx->GetAuxTableMgr(); |
| |
| // Unmap Resource from Aux Table |
| if (auxTableMgr) |
| { |
| auxTableMgr->UnmapResource(pOsResource->pGmmResInfo, pOsResource->bo); |
| } |
| } |
| |
| mos_bo_unreference((MOS_LINUX_BO *)(pOsResource->bo)); |
| |
| if ( pOsInterface->pOsContext != nullptr && pOsInterface->pOsContext->contextOffsetList.size()) |
| { |
| MOS_CONTEXT *pOsCtx = pOsInterface->pOsContext; |
| auto item_ctx = pOsCtx->contextOffsetList.begin(); |
| |
| for (;item_ctx != pOsCtx->contextOffsetList.end();) |
| { |
| if (item_ctx->target_bo == pOsResource->bo) |
| { |
| item_ctx = pOsCtx->contextOffsetList.erase(item_ctx); |
| } |
| else |
| { |
| item_ctx++; |
| } |
| } |
| } |
| |
| pOsResource->bo = nullptr; |
| if (pOsResource->pGmmResInfo != nullptr && |
| pOsInterface->pOsContext != nullptr && |
| pOsInterface->pOsContext->pGmmClientContext != nullptr) |
| { |
| MosUtilities::m_mosMemAllocCounterGfx--; |
| MOS_MEMNINJA_GFX_FREE_MESSAGE(pOsResource->pGmmResInfo, functionName, filename, line); |
| |
| pOsInterface->pOsContext->pGmmClientContext->DestroyResInfoObject(pOsResource->pGmmResInfo); |
| pOsResource->pGmmResInfo = nullptr; |
| } |
| } |
| |
| } |
| |
| //! |
| //! \brief Free OS resource |
| //! \details Free OS resource |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in/out] OS Resource to be freed |
| //! \param uint32_t uiFlag |
| //! [in] Flag to free resources. This one is useless on Linux, just for compatibility. |
| //! \return void |
| //! |
| void Mos_Specific_FreeResourceWithFlag( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| #if MOS_MESSAGES_ENABLED |
| PCCHAR functionName, |
| PCCHAR filename, |
| int32_t line, |
| #endif // MOS_MESSAGES_ENABLED |
| uint32_t uiFlag) |
| { |
| MOS_UNUSED(uiFlag); |
| |
| if (pOsInterface == nullptr || |
| pOsResource == nullptr) |
| { |
| return; |
| } |
| |
| #if MOS_MESSAGES_ENABLED |
| Mos_Specific_FreeResource(pOsInterface, functionName, filename, line, pOsResource); |
| #else |
| Mos_Specific_FreeResource(pOsInterface, pOsResource); |
| #endif // MOS_MESSAGES_ENABLED |
| } |
| |
| //! |
| //! \brief Locks Resource request |
| //! \details Locks Resource request |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS Interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in/out] Resource object |
| //! \param PMOS_LOCK_PARAMS pLockFlags |
| //! [in] Lock Flags |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if successful |
| //! |
| MOS_STATUS Mos_Specific_LockSyncRequest( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| PMOS_LOCK_PARAMS pLockFlags) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pOsInterface); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Lock resource |
| //! \details Lock allocated resource |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to input OS resource |
| //! \param PMOS_LOCK_PARAMS pLockFlags |
| //! [in] Lock Flags - MOS_LOCKFLAG_* flags |
| //! \return void * |
| //! |
| void *Mos_Specific_LockResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| PMOS_LOCK_PARAMS pLockFlags) |
| { |
| void *pData = nullptr; |
| MOS_OS_CONTEXT *pContext = nullptr; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pOsResource); |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| |
| if( nullptr == pOsInterface ) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL."); |
| return nullptr; |
| } |
| |
| if( nullptr == pOsResource) |
| { |
| MOS_OS_ASSERTMESSAGE("input parameter pOsInterface is NULL."); |
| return nullptr; |
| } |
| |
| bool osContextValid = false; |
| if (pOsInterface->osContextPtr != nullptr) |
| { |
| if (pOsInterface->osContextPtr->GetOsContextValid() == true) |
| { |
| osContextValid = true; |
| } |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::LockMosResource(pOsInterface->osStreamState, pOsResource, pLockFlags); |
| } |
| |
| if ((pOsInterface->modulizedMosEnabled) |
| && (!pOsResource->bConvertedFromDDIResource) |
| && (osContextValid == true) |
| && (!Mos_Solo_IsEnabled(nullptr)) |
| && (pOsResource->pGfxResource)) |
| { |
| if (nullptr == pOsInterface->osContextPtr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid osContextPtr, skip lock"); |
| } |
| |
| if (pOsResource->pGfxResource) |
| { |
| GraphicsResource::LockParams params(pLockFlags); |
| pData = pOsResource->pGfxResource->Lock(pOsInterface->osContextPtr, params); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Received an empty Graphics Resource, skip lock"); |
| } |
| return pData; |
| } |
| |
| pContext = pOsInterface->pOsContext; |
| if (pOsResource && pOsResource->bo && pOsResource->pGmmResInfo) |
| { |
| MOS_LINUX_BO *bo = pOsResource->bo; |
| GMM_RESOURCE_FLAG GmmFlags; |
| |
| MOS_ZeroMemory(&GmmFlags, sizeof(GmmFlags)); |
| GmmFlags = pOsResource->pGmmResInfo->GetResFlags(); |
| |
| // Do decompression for a compressed surface before lock |
| if (!pLockFlags->NoDecompress && |
| (((GmmFlags.Gpu.MMC || GmmFlags.Gpu.CCS) && GmmFlags.Gpu.UnifiedAuxSurface)|| |
| pOsResource->pGmmResInfo->IsMediaMemoryCompressed(0))) |
| { |
| PMOS_CONTEXT pOsContext = pOsInterface->pOsContext; |
| |
| MOS_OS_ASSERT(pOsContext); |
| MOS_OS_ASSERT(pOsContext->ppMediaMemDecompState); |
| MOS_OS_ASSERT(pOsContext->pfnMemoryDecompress); |
| pOsContext->pfnMemoryDecompress(pOsContext, pOsResource); |
| } |
| |
| if(false == pOsResource->bMapped) |
| { |
| if (pContext->bIsAtomSOC) |
| { |
| mos_gem_bo_map_gtt(bo); |
| } |
| else |
| { |
| if (pOsResource->TileType != MOS_TILE_LINEAR && !pLockFlags->TiledAsTiled) |
| { |
| if (pContext->bUseSwSwizzling) |
| { |
| mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY&pLockFlags->WriteOnly)); |
| pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP; |
| if (pOsResource->pSystemShadow == nullptr) |
| { |
| pOsResource->pSystemShadow = (uint8_t *)MOS_AllocMemory(bo->size); |
| MOS_OS_CHECK_CONDITION((pOsResource->pSystemShadow == nullptr), "Failed to allocate shadow surface", nullptr); |
| } |
| if (pOsResource->pSystemShadow) |
| { |
| int32_t flags = pContext->bTileYFlag ? 0 : 1; |
| MOS_OS_CHECK_CONDITION((pOsResource->TileType != MOS_TILE_Y), "Unsupported tile type", nullptr); |
| MOS_OS_CHECK_CONDITION((bo->size <= 0 || pOsResource->iPitch <= 0), "Invalid BO size or pitch", nullptr); |
| Mos_SwizzleData((uint8_t*)bo->virt, pOsResource->pSystemShadow, |
| MOS_TILE_Y, MOS_TILE_LINEAR, bo->size / pOsResource->iPitch, pOsResource->iPitch, flags); |
| } |
| } |
| else |
| { |
| mos_gem_bo_map_gtt(bo); |
| pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP_GTT; |
| } |
| } |
| else if (pLockFlags->Uncached) |
| { |
| mos_gem_bo_map_wc(bo); |
| pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP_WC; |
| } |
| else |
| { |
| mos_bo_map(bo, (OSKM_LOCKFLAG_WRITEONLY&pLockFlags->WriteOnly)); |
| pOsResource->MmapOperation = MOS_MMAP_OPERATION_MMAP; |
| } |
| } |
| pOsResource->pData = pOsResource->pSystemShadow ? pOsResource->pSystemShadow : (uint8_t*)bo->virt; |
| pOsResource->bMapped = true; |
| } |
| |
| pData = pOsResource->pData; |
| |
| } |
| |
| finish: |
| MOS_OS_ASSERT(pData); |
| return pData; |
| } |
| |
| //! |
| //! \brief Unlock resource |
| //! \details Unlock the locked resource |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to input OS resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_UnlockResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_STATUS eStatus; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CONTEXT *pContext = nullptr; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsResource); |
| MOS_OS_CHK_NULL(pOsInterface->pOsContext); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::UnlockMosResource(pOsInterface->osStreamState, pOsResource); |
| } |
| |
| bool osContextValid; |
| osContextValid = false; |
| if (pOsInterface->osContextPtr != nullptr) |
| { |
| if (pOsInterface->osContextPtr->GetOsContextValid() == true) |
| { |
| osContextValid = true; |
| } |
| } |
| |
| if ((pOsInterface->modulizedMosEnabled) |
| && (!pOsResource->bConvertedFromDDIResource) |
| && (osContextValid == true) |
| && (!Mos_Solo_IsEnabled(nullptr)) |
| && (pOsResource->pGfxResource)) |
| { |
| if (nullptr == pOsInterface->osContextPtr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid osContextPtr, skip lock"); |
| } |
| |
| if (pOsResource->pGfxResource) |
| { |
| eStatus = pOsResource->pGfxResource->Unlock(pOsInterface->osContextPtr); |
| } |
| else |
| { |
| MOS_OS_VERBOSEMESSAGE("Received an empty Graphics Resource, skip unlock"); |
| } |
| return eStatus; |
| } |
| |
| pContext = pOsInterface->pOsContext; |
| |
| if(pOsResource->bo) |
| { |
| if(true == pOsResource->bMapped) |
| { |
| if (pContext->bIsAtomSOC) |
| { |
| mos_gem_bo_unmap_gtt(pOsResource->bo); |
| } |
| else |
| { |
| if (pOsResource->pSystemShadow) |
| { |
| int32_t flags = pContext->bTileYFlag ? 0 : 1; |
| Mos_SwizzleData(pOsResource->pSystemShadow, (uint8_t*)pOsResource->bo->virt, |
| MOS_TILE_LINEAR, MOS_TILE_Y, pOsResource->bo->size / pOsResource->iPitch, pOsResource->iPitch, flags); |
| MOS_FreeMemory(pOsResource->pSystemShadow); |
| pOsResource->pSystemShadow = nullptr; |
| } |
| |
| switch(pOsResource->MmapOperation) |
| { |
| case MOS_MMAP_OPERATION_MMAP_GTT: |
| mos_gem_bo_unmap_gtt(pOsResource->bo); |
| break; |
| case MOS_MMAP_OPERATION_MMAP_WC: |
| mos_gem_bo_unmap_wc(pOsResource->bo); |
| break; |
| case MOS_MMAP_OPERATION_MMAP: |
| mos_bo_unmap(pOsResource->bo); |
| break; |
| default: |
| MOS_OS_ASSERTMESSAGE("Invalid mmap operation type"); |
| break; |
| } |
| } |
| pOsResource->bo->virt = nullptr; |
| pOsResource->bMapped = false; |
| } |
| pOsResource->pData = nullptr; |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Decompress Resource |
| //! \details Decompress Resource |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS Interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in/out] Resource object |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if successful |
| //! |
| MOS_STATUS Mos_Specific_DecompResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_CONTEXT *pContext = nullptr; |
| |
| //--------------------------------------- |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsResource); |
| MOS_OS_CHK_NULL(pOsInterface->pOsContext); |
| //--------------------------------------- |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::DecompResource(pOsInterface->osStreamState, pOsResource); |
| } |
| |
| pContext = pOsInterface->pOsContext; |
| |
| if (pOsResource && pOsResource->bo && pOsResource->pGmmResInfo) |
| { |
| MOS_LINUX_BO *bo = pOsResource->bo; |
| if (pOsResource->pGmmResInfo->IsMediaMemoryCompressed(0)) |
| { |
| PMOS_CONTEXT pOsContext = pOsInterface->pOsContext; |
| |
| MOS_OS_CHK_NULL(pOsContext); |
| MOS_OS_CHK_NULL(pOsContext->ppMediaMemDecompState); |
| MOS_OS_CHK_NULL(pOsContext->pfnMemoryDecompress); |
| pOsContext->pfnMemoryDecompress(pOsContext, pOsResource); |
| } |
| } |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Decompress and Copy Resource to Another Buffer |
| //! \details Decompress and Copy Resource to Another Buffer |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS Interface structure |
| //! \param PMOS_RESOURCE inputOsResource |
| //! [in] Input Resource object |
| //! \param PMOS_RESOURCE outputOsResource |
| //! [out] output Resource object |
| //! \param [in] bOutputCompressed |
| //! true means apply compression on output surface, else output uncompressed surface |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if successful |
| //! |
| MOS_STATUS Mos_Specific_DoubleBufferCopyResource( |
| PMOS_INTERFACE osInterface, |
| PMOS_RESOURCE inputOsResource, |
| PMOS_RESOURCE outputOsResource, |
| bool bOutputCompressed) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_CONTEXT *pContext = nullptr; |
| |
| //--------------------------------------- |
| MOS_OS_CHK_NULL(osInterface); |
| MOS_OS_CHK_NULL(inputOsResource); |
| MOS_OS_CHK_NULL(outputOsResource); |
| //--------------------------------------- |
| |
| if (osInterface->apoMosEnabled) |
| { |
| return MosInterface::DoubleBufferCopyResource(osInterface->osStreamState, inputOsResource, outputOsResource, bOutputCompressed); |
| } |
| |
| pContext = osInterface->pOsContext; |
| |
| if (inputOsResource && inputOsResource->bo && inputOsResource->pGmmResInfo && |
| outputOsResource && outputOsResource->bo && outputOsResource->pGmmResInfo) |
| { |
| // Double Buffer Copy can support any tile status surface with/without compression |
| pContext->pfnMediaMemoryCopy(pContext, inputOsResource, outputOsResource, bOutputCompressed); |
| } |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Decompress and Copy Resource to Another Buffer |
| //! \details Decompress and Copy Resource to Another Buffer |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS Interface structure |
| //! \param PMOS_RESOURCE inputOsResource |
| //! [in] Input Resource object |
| //! \param PMOS_RESOURCE outputOsResource |
| //! [out] output Resource object |
| //! \param [in] copyWidth |
| //! The 2D surface Width |
| //! \param [in] copyHeight |
| //! The 2D surface height |
| //! \param [in] copyInputOffset |
| //! The offset of copied surface from |
| //! \param [in] copyOutputOffset |
| //! The offset of copied to |
| //! \param [in] bOutputCompressed |
| //! true means apply compression on output surface, else output uncompressed surface |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if successful |
| //! |
| MOS_STATUS Mos_Specific_MediaCopyResource2D( |
| PMOS_INTERFACE osInterface, |
| PMOS_RESOURCE inputOsResource, |
| PMOS_RESOURCE outputOsResource, |
| uint32_t copyWidth, |
| uint32_t copyHeight, |
| uint32_t copyInputOffset, |
| uint32_t copyOutputOffset, |
| uint32_t bpp, |
| bool bOutputCompressed) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_CONTEXT *pContext = nullptr; |
| |
| //--------------------------------------- |
| MOS_OS_CHK_NULL(osInterface); |
| MOS_OS_CHK_NULL(inputOsResource); |
| MOS_OS_CHK_NULL(outputOsResource); |
| //--------------------------------------- |
| |
| if (osInterface->apoMosEnabled) |
| { |
| return MosInterface::MediaCopyResource2D(osInterface->osStreamState, inputOsResource, outputOsResource, |
| copyWidth, copyHeight, copyInputOffset, copyOutputOffset, bpp, bOutputCompressed); |
| } |
| |
| pContext = osInterface->pOsContext; |
| |
| if (inputOsResource && inputOsResource->bo && inputOsResource->pGmmResInfo && |
| outputOsResource && outputOsResource->bo && outputOsResource->pGmmResInfo) |
| { |
| // Double Buffer Copy can support any tile status surface with/without compression |
| pContext->pfnMediaMemoryCopy2D(pContext, inputOsResource, outputOsResource, copyWidth, copyHeight, copyInputOffset, copyOutputOffset, bpp, bOutputCompressed); |
| } |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Get Mos Context |
| //! \details Get Mos Context info |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param mosContext void ** |
| //! [out] pointer of mos_context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetMosContext( |
| PMOS_INTERFACE osInterface, |
| PMOS_CONTEXT* mosContext) |
| { |
| MOS_OS_CHK_NULL_RETURN(osInterface); |
| if (osInterface->apoMosEnabled) |
| { |
| void *apo_mos_context = nullptr; |
| MOS_OS_CHK_STATUS_RETURN(MosInterface::GetperStreamParameters(osInterface->osStreamState, &apo_mos_context)); |
| *mosContext = (PMOS_CONTEXT)apo_mos_context; |
| } |
| else |
| { |
| *mosContext = (PMOS_CONTEXT)osInterface->pOsContext; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Set patch entry |
| //! \details Sets the patch entry in MS's patch list |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_PATCH_ENTRY_PARAMS pParams |
| //! [in] patch entry params |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SetPatchEntry( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_PATCH_ENTRY_PARAMS pParams) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pParams); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if (!pParams->bUpperBoundPatch && pParams->presResource) |
| { |
| uint32_t handle = pParams->presResource->bo?pParams->presResource->bo->handle:0; |
| uint32_t eventData[] = {handle, pParams->uiResourceOffset, |
| pParams->uiPatchOffset, pParams->bWrite, |
| pParams->HwCommandType, pParams->forceDwordOffset, |
| pParams->patchType}; |
| MOS_TraceEventExt(EVENT_RESOURCE_PATCH, EVENT_TYPE_INFO2, |
| &eventData, sizeof(eventData), |
| nullptr, 0); |
| } |
| #endif |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::SetPatchEntry(pOsInterface->osStreamState, pParams); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->SetPatchEntry(pOsInterface, pParams)); |
| } |
| |
| PMOS_OS_CONTEXT pOsContext; |
| MOS_OS_GPU_CONTEXT *pOsGpuContext; |
| PPATCHLOCATIONLIST pPatchList; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| pOsContext = pOsInterface->pOsContext; |
| pOsGpuContext = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| pPatchList = pOsGpuContext->pPatchLocationList; |
| |
| pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].AllocationIndex = pParams->uiAllocationIndex; |
| pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].AllocationOffset = pParams->uiResourceOffset; |
| pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].PatchOffset = pParams->uiPatchOffset; |
| pPatchList[pOsGpuContext->uiCurrentNumPatchLocations].uiWriteOperation = pParams->bWrite ? true : false; |
| |
| if (pOsInterface->osCpInterface && |
| pOsInterface->osCpInterface->IsHMEnabled()) |
| { |
| pOsInterface->osCpInterface->RegisterPatchForHM( |
| (uint32_t*)(pParams->cmdBufBase + pParams->uiPatchOffset), |
| pParams->bWrite, |
| pParams->HwCommandType, |
| pParams->forceDwordOffset, |
| pParams->presResource, |
| &pPatchList[pOsGpuContext->uiCurrentNumPatchLocations]); |
| } |
| |
| pOsGpuContext->uiCurrentNumPatchLocations++; |
| |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Update resource usage type |
| //! \details update the resource usage for cache policy |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in/out] Pointer to OS Resource |
| //! \param MOS_HW_RESOURCE_DEF resUsageType |
| //! [in] resosuce usage type |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_UpdateResourceUsageType( |
| PMOS_RESOURCE pOsResource, |
| MOS_HW_RESOURCE_DEF resUsageType) |
| { |
| return MosInterface::UpdateResourceUsageType(pOsResource, resUsageType); |
| } |
| |
| //! |
| //! \brief Registers Resource |
| //! \details Set the Allocation Index in OS resource structure |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in/out] Pointer to OS Resource |
| //! \param int32_t bWrite |
| //! [in] Write Flag |
| //! \param int32_t bWritebSetResourceSyncTag |
| //! [in] Resource registration Flag, no use for Linux |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_RegisterResource ( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| int32_t bWrite, |
| int32_t bWritebSetResourceSyncTag) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pOsResource); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED |
| GpuCmdResInfoDumpNext::GetInstance(pOsInterface->pOsContext)->StoreCmdResPtr(pOsInterface, (const void *)pOsResource); |
| #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED |
| |
| return MosInterface::RegisterResource( |
| pOsInterface->osStreamState, |
| pOsResource, |
| bWrite); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED |
| GpuCmdResInfoDump::GetInstance(pOsInterface->pOsContext)->StoreCmdResPtr(pOsInterface, (const void *)pOsResource); |
| #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED |
| |
| return (gpuContext->RegisterResource(pOsResource, bWrite)); |
| } |
| |
| PMOS_OS_CONTEXT pOsContext = nullptr; |
| PMOS_RESOURCE pResources = nullptr; |
| uint32_t uiAllocation = 0; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| MOS_OS_GPU_CONTEXT *pOsGpuContext = nullptr; |
| MOS_UNUSED(bWritebSetResourceSyncTag); |
| |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| |
| pOsContext = pOsInterface->pOsContext; |
| |
| if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("CurrentGpuContextOrdinal exceed max."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| pOsGpuContext = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| |
| // Find previous registration |
| pResources = pOsGpuContext->pResources; |
| if( nullptr == pResources) |
| { |
| MOS_OS_ASSERTMESSAGE("pResouce is NULL."); |
| return MOS_STATUS_SUCCESS; |
| } |
| for (uiAllocation = 0; |
| uiAllocation < pOsGpuContext->uiResCount; |
| uiAllocation++, pResources++) |
| { |
| if (pOsResource->bo == pResources->bo) break; |
| } |
| // Allocation list to be updated |
| if (uiAllocation < pOsGpuContext->uiMaxNumAllocations) |
| { |
| // New buffer |
| if (uiAllocation == pOsGpuContext->uiResCount) |
| { |
| pOsGpuContext->uiResCount++; |
| } |
| |
| // Set allocation |
| pOsResource->iAllocationIndex[pOsInterface->CurrentGpuContextOrdinal] = uiAllocation; |
| pOsGpuContext->pResources[uiAllocation] = *pOsResource; |
| pOsGpuContext->pbWriteMode[uiAllocation] |= bWrite; |
| pOsGpuContext->pAllocationList[uiAllocation].hAllocation = &pOsGpuContext->pResources[uiAllocation]; |
| pOsGpuContext->pAllocationList[uiAllocation].WriteOperation|= bWrite; |
| pOsGpuContext->uiNumAllocations = pOsGpuContext->uiResCount; |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Reached max # registrations."); |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Verify command buffer size |
| //! \details Verifys the buffer to be used for rendering GPU commands is large enough |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param uint32_t dwRequestedSize |
| //! [in] Buffer size requested |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful (command buffer will be large enough to hold dwMaxSize) |
| //! otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_VerifyCommandBufferSize( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t dwRequestedSize, |
| uint32_t dwFlags) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::VerifyCommandBufferSize(pOsInterface->osStreamState, 0, dwRequestedSize, dwFlags); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->VerifyCommandBufferSize(dwRequestedSize)); |
| } |
| |
| PMOS_OS_CONTEXT pOsContext = nullptr; |
| MOS_OS_GPU_CONTEXT OsGpuContext; |
| |
| //--------------------------------------- |
| MOS_UNUSED(dwFlags); |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| //--------------------------------------- |
| |
| if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("CurrentGpuContextOrdinal exceed max."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| pOsContext = pOsInterface->pOsContext; |
| OsGpuContext = pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| |
| if (OsGpuContext.uiCommandBufferSize < dwRequestedSize) |
| { |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Resets Resource Allocation |
| //! \details Resets Resource Allocation |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to input OS resource |
| //! \return void |
| //! |
| void Mos_Specific_ResetResourceAllocationIndex ( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource) |
| { |
| int32_t i; |
| MOS_UNUSED(pOsInterface); |
| |
| if( nullptr == pOsResource) |
| { |
| MOS_OS_ASSERTMESSAGE("pOsResource is NULL."); |
| return; |
| } |
| |
| for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| pOsResource->iAllocationIndex[i] = MOS_INVALID_ALLOC_INDEX; |
| } |
| } |
| |
| //! |
| //! \brief Get command buffer |
| //! \details Retrieves buffer to be used for rendering GPU commands |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [out] Pointer to Command Buffer control structure |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetCommandBuffer( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_COMMAND_BUFFER pCmdBuffer, |
| uint32_t dwFlags) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pCmdBuffer); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetCommandBuffer(pOsInterface->osStreamState, pCmdBuffer, dwFlags); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->GetCommandBuffer(pCmdBuffer, dwFlags)); |
| } |
| |
| PMOS_OS_CONTEXT pOsContext = nullptr; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext = nullptr; |
| uint32_t uiCommandBufferSize = 0; |
| |
| MOS_UNUSED(dwFlags); |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsInterface->pOsContext); |
| MOS_OS_CHK_NULL(pCmdBuffer); |
| |
| if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| |
| // Activate software context |
| pOsContext = pOsInterface->pOsContext; |
| pOsGpuContext = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| uiCommandBufferSize = pOsGpuContext->uiCommandBufferSize; |
| |
| if(pOsGpuContext->bCBFlushed == true) |
| { |
| if (pOsContext->pfnGetCommandBuffer(pOsContext, |
| pCmdBuffer, |
| uiCommandBufferSize)) |
| { |
| MOS_OS_CHK_STATUS(pOsContext->pfnInsertCmdBufferToPool(pOsContext, pCmdBuffer)); |
| pOsGpuContext->bCBFlushed = false; |
| eStatus = MOS_SecureMemcpy(pOsGpuContext->pCB, sizeof(MOS_COMMAND_BUFFER), pCmdBuffer, sizeof(MOS_COMMAND_BUFFER)); |
| MOS_OS_CHECK_CONDITION((eStatus != MOS_STATUS_SUCCESS), "Failed to copy command buffer", eStatus); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to activate command buffer."); |
| eStatus = MOS_STATUS_UNKNOWN; |
| goto finish; |
| } |
| } |
| |
| MOS_OS_CHK_STATUS(pOsInterface->pfnRegisterResource(pOsInterface, &(pOsGpuContext->pCB->OsResource), false, false)); |
| eStatus = MOS_SecureMemcpy(pCmdBuffer, sizeof(MOS_COMMAND_BUFFER), pOsGpuContext->pCB, sizeof(MOS_COMMAND_BUFFER)); |
| MOS_OS_CHECK_CONDITION((eStatus != MOS_STATUS_SUCCESS), "Failed to copy command buffer", eStatus); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Set indirect state size |
| //! \details Sets indirect state size to be used for rendering purposes |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param uint32_t uSize |
| //! [in] State size |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SetIndirectStateSize( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t uSize) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::SetupIndirectState(pOsInterface->osStreamState, uSize); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| MOS_OS_CHK_STATUS_RETURN(gpuContext->SetIndirectStateSize(uSize)); |
| } |
| |
| PMOS_CONTEXT pOsContext = nullptr; |
| MOS_STATUS eStatus; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| pOsContext = pOsInterface->pOsContext; |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| pOsContext->uIndirectStateSize = uSize; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Set indirect state size |
| //! \details Retrieves indirect state to be used for rendering purposes |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param uint32_t *puOffset |
| //! [out] Pointer to indirect buffer offset |
| //! \param uint32_t *puSize |
| //! [out] Pointer to indirect buffer size |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetIndirectState( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t *puOffset, |
| uint32_t *puSize) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(puOffset); |
| MOS_OS_CHK_NULL_RETURN(puSize); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| uint32_t offset = 0; |
| uint32_t size = 0; |
| auto eStatus = MosInterface::GetIndirectState(pOsInterface->osStreamState, nullptr, offset, size); |
| *puOffset = offset; |
| *puSize = size; |
| return eStatus; |
| } |
| |
| if (pOsInterface->CurrentGpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->GetIndirectState(puOffset, puSize)); |
| } |
| |
| PMOS_CONTEXT pOsContext = nullptr; |
| MOS_OS_GPU_CONTEXT OsGpuContext; |
| |
| pOsContext = pOsInterface->pOsContext; |
| if (pOsContext) |
| { |
| OsGpuContext = pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| |
| if (puOffset) |
| { |
| *puOffset = OsGpuContext.uiCommandBufferSize - pOsContext->uIndirectStateSize; |
| } |
| |
| if (puSize) |
| { |
| *puSize = pOsContext->uIndirectStateSize; |
| } |
| } |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get Resource Allocation Index |
| //! \details Get Resource Allocation Index |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_RESOURCE pResource |
| //! [in] Pointer to input OS resource |
| //! \return int32_t |
| //! return the allocation index |
| //! |
| int32_t Mos_Specific_GetResourceAllocationIndex( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pResource) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| if (pResource && pOsInterface) |
| { |
| |
| if (pOsInterface->CurrentGpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| return(pResource->iAllocationIndex[pOsInterface->CurrentGpuContextOrdinal]); |
| } |
| |
| return MOS_INVALID_ALLOC_INDEX; |
| |
| } |
| |
| //! |
| //! \brief Get Indirect State Pointer |
| //! \details Get Indirect State Pointer |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param uint8_t **pIndirectState |
| //! [out] Pointer to Indirect State Buffer |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetIndirectStatePointer( |
| PMOS_INTERFACE pOsInterface, |
| uint8_t **pIndirectState) |
| { |
| PMOS_OS_CONTEXT pOsContext = nullptr; |
| MOS_OS_GPU_CONTEXT OsGpuContext = {}; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pIndirectState); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| uint32_t offset = 0; |
| uint32_t size = 0; |
| return MosInterface::GetIndirectState(pOsInterface->osStreamState, pIndirectState, offset, size); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->GetIndirectStatePointer(pIndirectState)); |
| } |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| |
| pOsContext = (pOsInterface) ? pOsInterface->pOsContext : nullptr; |
| |
| if (pOsContext) |
| { |
| if (pOsInterface->CurrentGpuContextHandle == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| OsGpuContext = pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| |
| if (OsGpuContext.pCB && OsGpuContext.pCB->pCmdBase) |
| { |
| *pIndirectState = |
| (uint8_t*)OsGpuContext.pCB->pCmdBase + |
| OsGpuContext.uiCommandBufferSize - |
| pOsContext->uIndirectStateSize; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| } |
| } |
| |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Return command buffer space |
| //! \details Return unused command buffer space |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [out] Pointer to Command Buffer control structure |
| //! \return void |
| //! |
| void Mos_Specific_ReturnCommandBuffer( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_COMMAND_BUFFER pCmdBuffer, |
| uint32_t dwFlags) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| if (pOsInterface == nullptr || pCmdBuffer == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid parameters."); |
| return; |
| } |
| |
| // Need to ensure 4K extra padding for HW requirement. |
| if (pCmdBuffer && pCmdBuffer->iRemaining < EXTRA_PADDING_NEEDED) |
| { |
| MOS_OS_ASSERTMESSAGE("Need to ensure 4K extra padding for HW requirement."); |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| auto status = MosInterface::ReturnCommandBuffer(pOsInterface->osStreamState, pCmdBuffer, dwFlags); |
| if (MOS_FAILED(status)) |
| { |
| MOS_OS_ASSERTMESSAGE("ReturnCommandBuffer failed."); |
| } |
| return; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| |
| if (gpuContext) |
| { |
| gpuContext->ReturnCommandBuffer(pCmdBuffer, dwFlags); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Cannot get valid Gpu context!"); |
| } |
| |
| return; |
| } |
| |
| PMOS_OS_CONTEXT pOsContext = nullptr; |
| int32_t bResult; |
| |
| MOS_UNUSED(dwFlags); |
| |
| bResult = false; |
| |
| // Validate parameters |
| pOsContext = (pOsInterface) ? pOsInterface->pOsContext : nullptr; |
| if (pOsContext == nullptr || pCmdBuffer == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid parameters."); |
| goto finish; |
| } |
| |
| pOsContext->pfnReturnCommandBuffer(pOsContext,pOsInterface->CurrentGpuContextOrdinal, pCmdBuffer); |
| |
| finish: |
| return; |
| } |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_LINUX_BO * Mos_GetNopCommandBuffer_Linux( |
| PMOS_INTERFACE pOsInterface) |
| { |
| int j; |
| uint32_t *buf = nullptr; |
| MOS_LINUX_BO* bo = nullptr; |
| |
| j = 0; |
| |
| if(pOsInterface == nullptr || pOsInterface->pOsContext == nullptr) |
| { |
| return nullptr; |
| } |
| |
| bo = mos_bo_alloc(pOsInterface->pOsContext->bufmgr, "NOP_CMD_BO", 4096, 4096, MOS_MEMPOOL_SYSTEMMEMORY); |
| if(bo == nullptr) |
| { |
| return nullptr; |
| } |
| |
| mos_bo_map(bo, 1); |
| buf = (uint32_t*)bo->virt; |
| if(buf == nullptr) |
| { |
| mos_bo_unreference(bo); |
| return nullptr; |
| } |
| |
| buf[j++] = 0x05000000; // MI_BATCH_BUFFER_END |
| |
| mos_bo_unmap(bo); |
| |
| return bo; |
| } |
| |
| MOS_LINUX_BO * Mos_GetBadCommandBuffer_Linux( |
| PMOS_INTERFACE pOsInterface) |
| { |
| int j; |
| uint32_t *buf = nullptr; |
| MOS_LINUX_BO* bo = nullptr; |
| |
| j = 0; |
| |
| if(pOsInterface == nullptr || pOsInterface->pOsContext == nullptr) |
| { |
| return nullptr; |
| } |
| |
| bo = mos_bo_alloc(pOsInterface->pOsContext->bufmgr, "BAD_CMD_BO", 4096, 4096, MOS_MEMPOOL_SYSTEMMEMORY); |
| if(bo == nullptr) |
| { |
| return nullptr; |
| } |
| |
| mos_bo_map(bo, 1); |
| buf = (uint32_t*)bo->virt; |
| if(buf == nullptr) |
| { |
| mos_bo_unreference(bo); |
| return nullptr; |
| } |
| |
| /* Hanging batch buffer */ |
| // Semaphore setup: |
| // Set up GTT buffer, polling mode with |
| // comparison: address > op data (0xffffffff), |
| // which should never resolve since nothing |
| // is bigger than 0xffffffff. This semaphore |
| // should result in a hang that TDR will have |
| // to handle. |
| // |
| // 31:29 = 0 |
| // 28:23 = 0x1c |
| // ---> 31:24 = 0x0e, 23=0x0 |
| // 22:22 = 0x1 (GTT, must be secure batch) |
| // 21:16 = 0x0 |
| // ---> 23:20 = 0x4, 19:16=0x0 |
| // 15:15 = 0x1 (polling mode) |
| // 14:12 = 0x0: memory data > op data (set op data = 0xffffffff and we should never have a match... if the comparison is unsigned) |
| // ---> 15:12 = 0x8 |
| // 11:08 = 0x0 |
| // 07:00 = 0x2 |
| // ---> 07:04 = 0x0, 03:00 = 0x2 |
| // 31:0 = 0xffffffff |
| // |
| buf[j++] = 0x0e008002; |
| |
| // semaphore data |
| // |
| buf[j++] = 0xffffffff; |
| |
| // semaphore address |
| // |
| buf[j++] = 0x0; |
| buf[j++] = 0x0; |
| |
| buf[j++] = 0x0; /* MI_NOOP */ |
| buf[j++] = 0x05000000; // MI_BATCH_BUFFER_END |
| |
| mos_bo_unmap(bo); |
| |
| return bo; |
| } |
| #endif // _DEBUG || _RELEASE_INTERNAL |
| |
| uint32_t Mos_Specific_GetVcsExecFlag(PMOS_INTERFACE pOsInterface, |
| PMOS_COMMAND_BUFFER pCmdBuffer, |
| MOS_GPU_NODE GpuNode) |
| { |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pCmdBuffer); |
| uint32_t VcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1; |
| |
| if (MOS_VDBOX_NODE_INVALID == pCmdBuffer->iVdboxNodeIndex) |
| { |
| // That's those case when BB did not have any VDBOX# specific commands. |
| // Thus, we need to select VDBOX# here. Alternatively we can rely on KMD |
| // to make balancing for us, i.e. rely on Virtual Engine support. |
| pCmdBuffer->iVdboxNodeIndex = pOsInterface->pfnGetVdboxNodeId(pOsInterface, pCmdBuffer); |
| if (MOS_VDBOX_NODE_INVALID == pCmdBuffer->iVdboxNodeIndex) |
| { |
| pCmdBuffer->iVdboxNodeIndex = (GpuNode == MOS_GPU_NODE_VIDEO)? |
| MOS_VDBOX_NODE_1: MOS_VDBOX_NODE_2; |
| } |
| } |
| |
| if (MOS_VDBOX_NODE_1 == pCmdBuffer->iVdboxNodeIndex) |
| { |
| VcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1; |
| } |
| else if (MOS_VDBOX_NODE_2 == pCmdBuffer->iVdboxNodeIndex) |
| { |
| VcsExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING2; |
| } |
| |
| return VcsExecFlag; |
| } |
| |
| //! |
| //! \brief Submit command buffer |
| //! \details Submit the command buffer |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [in] Pointer to Command Buffer control structure |
| //! \param int32_t bNullRendering |
| //! [in] boolean null rendering |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SubmitCommandBuffer( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_COMMAND_BUFFER pCmdBuffer, |
| int32_t bNullRendering) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pCmdBuffer); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::SubmitCommandBuffer(pOsInterface->osStreamState, pCmdBuffer, bNullRendering); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED |
| GpuCmdResInfoDump::GetInstance(pOsInterface->pOsContext)->Dump(pOsInterface); |
| GpuCmdResInfoDump::GetInstance(pOsInterface->pOsContext)->ClearCmdResPtrs(pOsInterface); |
| #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED |
| |
| return (gpuContext->SubmitCommandBuffer(pOsInterface, pCmdBuffer, bNullRendering)); |
| } |
| |
| PMOS_CONTEXT pOsContext; |
| PMOS_RESOURCE pResource; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext; |
| MOS_GPU_CONTEXT GpuContext; |
| MOS_GPU_NODE GpuNode; |
| uint32_t PatchIndex, CmdBufferSize; |
| MOS_STATUS eStatus; |
| PPATCHLOCATIONLIST pPatchList,pCurrentPatch; |
| MOS_LINUX_BO *alloc_bo, *cmd_bo; |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_LINUX_BO *bad_cmd_bo; |
| MOS_LINUX_BO *nop_cmd_bo; |
| uint32_t dwComponentTag; |
| uint32_t dwCallType; |
| #endif // (_DEBUG || _RELEASE_INTERNAL) |
| uint32_t dwBatchBufferEndCmd; |
| uint32_t cpCmdProps; |
| int32_t PerfData; |
| uint32_t ExecFlag; |
| drm_clip_rect_t *cliprects; |
| int32_t num_cliprects; |
| int32_t DR4, ret; |
| uint64_t boOffset; |
| |
| boOffset = 0; |
| eStatus = MOS_STATUS_SUCCESS; |
| ret = 0; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsInterface->osCpInterface); |
| |
| pOsContext = pOsInterface->pOsContext; |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| GpuContext = pOsInterface->CurrentGpuContextOrdinal; |
| GpuNode = OSKMGetGpuNode(GpuContext); |
| ExecFlag = GpuNode; |
| |
| MOS_OS_CHK_NULL(pOsContext->OsGpuContext); |
| pOsGpuContext = &pOsContext->OsGpuContext[GpuContext]; |
| MOS_OS_CHK_NULL(pOsGpuContext); |
| |
| pPatchList = pOsGpuContext->pPatchLocationList; |
| MOS_OS_CHK_NULL(pPatchList); |
| |
| // Allocate command buffer from video memory |
| CmdBufferSize = (pCmdBuffer->pCmdPtr - pCmdBuffer->pCmdBase)*4;// pCmdBuffer->OsResource.iPitch; // ??? Not 100% sure about this ... |
| |
| // Command buffer object DRM pointer |
| pOsGpuContext->bCBFlushed = true; |
| cmd_bo = pCmdBuffer->OsResource.bo; |
| |
| // Now, the patching will be done, based on the patch list. |
| for (PatchIndex = 0; PatchIndex < pOsGpuContext->uiCurrentNumPatchLocations; PatchIndex++) |
| { |
| pCurrentPatch = &pPatchList[PatchIndex]; |
| MOS_OS_CHK_NULL(pCurrentPatch); |
| |
| // This is the resource for which patching will be done |
| pResource = (PMOS_RESOURCE)pOsGpuContext->pAllocationList[pCurrentPatch->AllocationIndex].hAllocation; |
| MOS_OS_CHK_NULL(pResource); |
| |
| // For now, we'll assume the system memory's DRM bo pointer |
| // is NULL. If nullptr is detected, then the resource has been |
| // placed inside the command buffer's indirect state area. |
| // We'll simply set alloc_bo to the command buffer's bo pointer. |
| MOS_OS_ASSERT(pResource->bo); |
| |
| alloc_bo = (pResource->bo) ? pResource->bo : cmd_bo; |
| |
| MOS_OS_CHK_STATUS(pOsInterface->osCpInterface->PermeatePatchForHM( |
| cmd_bo->virt, |
| pCurrentPatch, |
| pResource)); |
| |
| boOffset = alloc_bo->offset64; |
| if (alloc_bo != cmd_bo) |
| { |
| auto item_ctx = pOsContext->contextOffsetList.begin(); |
| for (; item_ctx != pOsContext->contextOffsetList.end(); item_ctx++) |
| { |
| if (item_ctx->intel_context == pOsContext->intel_context && item_ctx->target_bo == alloc_bo) |
| { |
| boOffset = item_ctx->offset64; |
| break; |
| } |
| } |
| } |
| if (pOsContext->bUse64BitRelocs) |
| { |
| *((uint64_t*)((uint8_t*)cmd_bo->virt + pCurrentPatch->PatchOffset)) = |
| boOffset + pCurrentPatch->AllocationOffset; |
| } |
| else |
| { |
| *((uint32_t*)((uint8_t*)cmd_bo->virt + pCurrentPatch->PatchOffset)) = |
| boOffset + pCurrentPatch->AllocationOffset; |
| } |
| |
| if(mos_gem_bo_is_softpin(alloc_bo)) |
| { |
| if (alloc_bo != cmd_bo) |
| { |
| ret = mos_bo_add_softpin_target(cmd_bo, alloc_bo, pCurrentPatch->uiWriteOperation); |
| } |
| } |
| else |
| { |
| // This call will patch the command buffer with the offsets of the indirect state region of the command buffer |
| ret = mos_bo_emit_reloc2( |
| cmd_bo, // Command buffer |
| pCurrentPatch->PatchOffset, // Offset in the command buffer |
| alloc_bo, // Allocation object for which the patch will be made. |
| pCurrentPatch->AllocationOffset, // Offset to the indirect state |
| I915_GEM_DOMAIN_RENDER, // Read domain |
| (pCurrentPatch->uiWriteOperation) ? I915_GEM_DOMAIN_RENDER : 0x0, // Write domain |
| boOffset); |
| } |
| |
| if (ret != 0) |
| { |
| MOS_OS_ASSERTMESSAGE("Error patching alloc_bo = 0x%x, cmd_bo = 0x%x.", |
| (uintptr_t)alloc_bo,(uintptr_t)cmd_bo); |
| eStatus = MOS_STATUS_UNKNOWN; |
| goto finish; |
| } |
| } |
| |
| //Add Batch buffer End Command |
| dwBatchBufferEndCmd = MI_BATCHBUFFER_END; |
| if (MOS_FAILED(Mos_AddCommand( |
| pCmdBuffer, |
| &dwBatchBufferEndCmd, |
| sizeof(uint32_t)))) |
| { |
| MOS_OS_ASSERTMESSAGE("Inserting BB_END failed!"); |
| eStatus = MOS_STATUS_UNKNOWN; |
| goto finish; |
| } |
| |
| // Now, we can unmap the video command buffer, since we don't need CPU access anymore. |
| mos_bo_unmap(cmd_bo); |
| |
| if(pOsContext->pPerfData != nullptr) |
| { |
| PerfData = *(int32_t *)(pOsContext->pPerfData); |
| } |
| else |
| { |
| PerfData = 0; |
| } |
| |
| cliprects = nullptr; |
| num_cliprects = 0; |
| DR4 = pOsContext->uEnablePerfTag ? PerfData : 0; |
| |
| //Since CB2 command is not supported, remove it and set cliprects to nullprt as default. |
| if (GpuNode != I915_EXEC_RENDER) |
| { |
| if (pOsContext->bKMDHasVCS2) |
| { |
| if (pOsContext->bPerCmdBufferBalancing && pOsInterface->pfnGetVdboxNodeId) |
| { |
| ExecFlag = Mos_Specific_GetVcsExecFlag(pOsInterface, pCmdBuffer, GpuNode); |
| } |
| else if (GpuNode == MOS_GPU_NODE_VIDEO) |
| { |
| ExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1; |
| } |
| else if (GpuNode == MOS_GPU_NODE_VIDEO2) |
| { |
| ExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING2; |
| } |
| } |
| else |
| { |
| ExecFlag = I915_EXEC_BSD | I915_EXEC_BSD_RING1; |
| } |
| } |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| // trigger GPU HANG if bTriggerCodecHang is set |
| bad_cmd_bo = nullptr; |
| |
| //dwComponentTag 3: decode,5: vpp,6: encode |
| //dwCallType 8: PAK(CODECHAL_ENCODE_PERFTAG_CALL_PAK_ENGINE) |
| // 34:PREENC |
| // 5: VPP |
| dwComponentTag = (PerfData & 0xF000) >> 12; |
| dwCallType = (PerfData & 0xFC) >> 2; |
| |
| if(pOsInterface->bTriggerCodecHang && |
| (dwComponentTag == 3 || (dwComponentTag == 6 && dwCallType == 8) || |
| (dwComponentTag == 6 && dwCallType == 34) || |
| (dwComponentTag == 5 && dwCallType == 5)) |
| ) |
| { |
| bad_cmd_bo = Mos_GetBadCommandBuffer_Linux(pOsInterface); |
| if(bad_cmd_bo) |
| { |
| ret = mos_bo_mrb_exec(bad_cmd_bo, |
| 4096, |
| nullptr, |
| 0, |
| 0, |
| ExecFlag); |
| } |
| { |
| MOS_OS_ASSERTMESSAGE("Mos_GetBadCommandBuffer_Linux failed!"); |
| } |
| } |
| else if (pOsInterface->bTriggerVPHang == true) |
| { |
| bad_cmd_bo = Mos_GetBadCommandBuffer_Linux(pOsInterface); |
| |
| if (bad_cmd_bo) |
| { |
| ret = mos_bo_mrb_exec(bad_cmd_bo, |
| 4096, |
| nullptr, |
| 0, |
| 0, |
| ExecFlag); |
| } |
| { |
| MOS_OS_ASSERTMESSAGE("Mos_GetBadCommandBuffer_Linux failed!"); |
| } |
| |
| pOsInterface->bTriggerVPHang = false; |
| } |
| |
| nop_cmd_bo = nullptr; |
| if (bNullRendering == true) |
| { |
| nop_cmd_bo = Mos_GetNopCommandBuffer_Linux(pOsInterface); |
| |
| if(nop_cmd_bo) |
| { |
| ret = mos_bo_mrb_exec(nop_cmd_bo, |
| 4096, |
| nullptr, |
| 0, |
| 0, |
| ExecFlag); |
| } |
| { |
| MOS_OS_ASSERTMESSAGE("Mos_GetNopCommandBuffer_Linux failed!"); |
| } |
| } |
| |
| #endif //(_DEBUG || _RELEASE_INTERNAL) |
| |
| if (GpuNode != I915_EXEC_RENDER && |
| pOsInterface->osCpInterface->IsTearDownHappen()) |
| { |
| // to skip PAK command when CP tear down happen to avoid of GPU hang |
| // conditonal batch buffer start PoC is in progress |
| } |
| else if (bNullRendering == false) |
| { |
| |
| ret = mos_gem_bo_context_exec2(cmd_bo, |
| pOsGpuContext->uiCommandBufferSize, |
| pOsContext->intel_context, |
| cliprects, |
| num_cliprects, |
| DR4, |
| ExecFlag, |
| nullptr); |
| if (ret != 0) { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| } |
| |
| if (eStatus != MOS_STATUS_SUCCESS) |
| { |
| MOS_OS_ASSERTMESSAGE("Command buffer submission failed!"); |
| } |
| |
| #if MOS_COMMAND_BUFFER_DUMP_SUPPORTED |
| if (pOsInterface->bDumpCommandBuffer) |
| { |
| mos_bo_map(cmd_bo, 0); |
| pOsInterface->pfnDumpCommandBuffer(pOsInterface, pCmdBuffer); |
| mos_bo_unmap(cmd_bo); |
| } |
| #endif // MOS_COMMAND_BUFFER_DUMP_SUPPORTED |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if(bad_cmd_bo) |
| { |
| mos_bo_wait_rendering(bad_cmd_bo); |
| mos_bo_unreference(bad_cmd_bo); |
| } |
| if(nop_cmd_bo) |
| { |
| mos_bo_unreference(nop_cmd_bo); |
| } |
| #endif //(_DEBUG || _RELEASE_INTERNAL) |
| |
| //clear command buffer relocations to fix memory leak issue |
| mos_gem_bo_clear_relocs(cmd_bo, 0); |
| |
| // Reset resource allocation |
| pOsGpuContext->uiNumAllocations = 0; |
| MOS_ZeroMemory(pOsGpuContext->pAllocationList, sizeof(ALLOCATION_LIST) * pOsGpuContext->uiMaxNumAllocations); |
| pOsGpuContext->uiCurrentNumPatchLocations = 0; |
| MOS_ZeroMemory(pOsGpuContext->pPatchLocationList, sizeof(PATCHLOCATIONLIST) * pOsGpuContext->uiMaxPatchLocationsize); |
| pOsGpuContext->uiResCount = 0; |
| |
| MOS_ZeroMemory(pOsGpuContext->pbWriteMode, sizeof(int32_t) * pOsGpuContext->uiMaxNumAllocations); |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Wait and release command buffer |
| //! \details Wait and release command buffer |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [in] Pointer to Command Buffer control structure |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_WaitAndReleaseCmdBuffer( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_COMMAND_BUFFER pCmdBuffer) |
| { |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pCmdBuffer); |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto cmd_bo = pCmdBuffer->OsResource.bo; |
| MOS_OS_CHK_NULL_RETURN(cmd_bo); |
| |
| // only wait rendering here, release will covered by gpucontext |
| mos_bo_wait_rendering(cmd_bo); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| PMOS_CONTEXT pOsContext; |
| MOS_STATUS eStatus; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pCmdBuffer); |
| |
| pOsContext = pOsInterface->pOsContext; |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| MOS_OS_CHK_STATUS(pOsContext->pfnWaitAndReleaseCmdBuffer(pOsContext, pCmdBuffer->iCmdIndex)); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Get resource gfx address |
| //! \details Get resource gfx address |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param PMOS_RESOURCE pResource |
| //! [in] Pointer to resource |
| //! \return uint64_t |
| //! Return resource gfx address |
| //! |
| uint64_t Mos_Specific_GetResourceGfxAddress( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pResource) |
| { |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pResource); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetResourceGfxAddress(pOsInterface->osStreamState, pResource); |
| } |
| |
| if (!mos_gem_bo_is_softpin(pResource->bo)) |
| { |
| mos_bo_set_softpin(pResource->bo); |
| } |
| return pResource->bo->offset64; |
| } |
| |
| //! |
| //! \brief Resizes the buffer to be used for rendering GPU commands |
| //! \details return true if succeeded - command buffer will be large enough to hold dwMaxSize |
| //! return false if failed or invalid parameters |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param uint32_t dwRequestedCommandBufferSize |
| //! [in] requested command buffer size |
| //! \param uint32_t dwRequestedPatchListSize |
| //! [in] requested patch list size |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_ResizeCommandBufferAndPatchList( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t dwRequestedCommandBufferSize, |
| uint32_t dwRequestedPatchListSize, |
| uint32_t dwFlags) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::ResizeCommandBufferAndPatchList(pOsInterface->osStreamState, 0, dwRequestedCommandBufferSize, dwRequestedPatchListSize, dwFlags); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->ResizeCommandBufferAndPatchList(dwRequestedCommandBufferSize, dwRequestedPatchListSize, dwFlags)); |
| } |
| |
| PMOS_CONTEXT pOsContext; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext; |
| PPATCHLOCATIONLIST pNewPatchList; |
| MOS_STATUS eStatus; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| //--------------------------------------- |
| MOS_UNUSED(dwFlags); |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| //--------------------------------------- |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| pOsContext = pOsInterface->pOsContext; |
| pOsGpuContext = &(pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]); |
| |
| // uiCommandBufferSize is used for allocate command buffer and submit command buffer, in this moment, command buffer has not allocated yet. |
| // Linux KMD requires command buffer size align to 8 bytes, or it will not execute the commands. |
| pOsGpuContext->uiCommandBufferSize = MOS_ALIGN_CEIL(dwRequestedCommandBufferSize, 8); |
| |
| if (dwRequestedPatchListSize > pOsGpuContext->uiMaxPatchLocationsize) |
| { |
| pNewPatchList = (PPATCHLOCATIONLIST)realloc( |
| pOsGpuContext->pPatchLocationList, |
| sizeof(PATCHLOCATIONLIST) * dwRequestedPatchListSize); |
| if (nullptr == pNewPatchList) |
| { |
| MOS_OS_ASSERTMESSAGE("pOsGpuContext->pPatchLocationList realloc failed."); |
| eStatus = MOS_STATUS_NO_SPACE; |
| goto finish; |
| } |
| |
| pOsGpuContext->pPatchLocationList = pNewPatchList; |
| |
| // now zero the extended portion |
| MOS_ZeroMemory( |
| (pOsGpuContext->pPatchLocationList + pOsGpuContext->uiMaxPatchLocationsize), |
| sizeof(PATCHLOCATIONLIST) * (dwRequestedPatchListSize - pOsGpuContext->uiMaxPatchLocationsize)); |
| pOsGpuContext->uiMaxPatchLocationsize = dwRequestedPatchListSize; |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Resizes the buffer to be used for rendering GPU commands |
| //! \details return true if succeeded - command buffer will be large enough to hold dwMaxSize |
| //! return false if failed or invalid parameters |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param uint32_t dwRequestedSize |
| //! [in] requested size |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_ResizeCommandBuffer( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t dwRequestedSize) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->ResizeCommandBuffer(dwRequestedSize)); |
| } |
| |
| PMOS_CONTEXT pOsContext; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext; |
| MOS_GPU_CONTEXT GpuContext; |
| MOS_STATUS eStatus; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsInterface->pOsContext); |
| |
| pOsContext = &pOsInterface->pOsContext[pOsInterface->CurrentGpuContextOrdinal]; |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| GpuContext = pOsInterface->CurrentGpuContextOrdinal; |
| |
| MOS_OS_CHK_NULL(pOsContext->OsGpuContext); |
| pOsGpuContext = &pOsContext->OsGpuContext[GpuContext]; |
| MOS_OS_CHK_NULL(pOsGpuContext); |
| |
| pOsGpuContext->uiCommandBufferSize = dwRequestedSize; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Create GPU context |
| //! \details Create GPU context |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \param MOS_GPU_NODE GpuNode |
| //! [in] GPU Node |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_CreateGpuContext( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT mosGpuCxt, |
| MOS_GPU_NODE GpuNode, |
| PMOS_GPUCTX_CREATOPTIONS createOption) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (mosGpuCxt == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr); |
| |
| auto pOsContextSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| MOS_OS_CHK_NULL_RETURN(pOsContextSpecific); |
| |
| auto gpuContextMgr = pOsContextSpecific->GetGpuContextMgr(); |
| if (!pOsInterface->apoMosEnabled) |
| { |
| MOS_OS_CHK_NULL_RETURN(gpuContextMgr); |
| } |
| |
| auto cmdBufMgr = pOsContextSpecific->GetCmdBufMgr(); |
| if (!pOsInterface->apoMosEnabled) |
| { |
| MOS_OS_CHK_NULL_RETURN(cmdBufMgr); |
| } |
| |
| MOS_OS_CHK_NULL_RETURN(createOption); |
| if (GpuNode == MOS_GPU_NODE_3D && createOption->SSEUValue != 0) |
| { |
| struct drm_i915_gem_context_param_sseu sseu; |
| MOS_ZeroMemory(&sseu, sizeof(sseu)); |
| sseu.engine.engine_class = I915_ENGINE_CLASS_RENDER; |
| sseu.engine.engine_instance = 0; |
| |
| if (mos_get_context_param_sseu(pOsInterface->pOsContext->intel_context, &sseu)) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to get sseu configuration."); |
| return MOS_STATUS_UNKNOWN; |
| }; |
| |
| if (mos_hweight8(sseu.subslice_mask) > createOption->packed.SubSliceCount) |
| { |
| sseu.subslice_mask = mos_switch_off_n_bits(sseu.subslice_mask, |
| mos_hweight8(sseu.subslice_mask)-createOption->packed.SubSliceCount); |
| } |
| |
| if (mos_set_context_param_sseu(pOsInterface->pOsContext->intel_context, sseu)) |
| { |
| MOS_OS_ASSERTMESSAGE("Failed to set sseu configuration."); |
| return MOS_STATUS_UNKNOWN; |
| }; |
| } |
| |
| createOption->gpuNode = GpuNode; |
| if (pOsInterface->apoMosEnabled) |
| { |
| // Update ctxBasedScheduling from legacy OsInterface |
| pOsInterface->osStreamState->ctxBasedScheduling = pOsInterface->ctxBasedScheduling; |
| if (pOsContextSpecific->GetGpuContextHandle(mosGpuCxt) == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| auto osDeviceContext = pOsInterface->osStreamState->osDeviceContext; |
| MOS_OS_CHK_NULL_RETURN(osDeviceContext); |
| auto gpuContextMgr = osDeviceContext->GetGpuContextMgr(); |
| MOS_OS_CHK_NULL_RETURN(gpuContextMgr); |
| auto cmdBufMgr = osDeviceContext->GetCmdBufferMgr(); |
| MOS_OS_CHK_NULL_RETURN(cmdBufMgr); |
| |
| auto gpuContext = gpuContextMgr->CreateGpuContext(GpuNode, cmdBufMgr); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| auto gpuContextSpecific = static_cast<GpuContextSpecificNext *>(gpuContext); |
| MOS_OS_CHK_NULL_RETURN(gpuContextSpecific); |
| |
| MOS_OS_CHK_STATUS_RETURN(gpuContextSpecific->Init(gpuContextMgr->GetOsContext(), pOsInterface->osStreamState, createOption)); |
| gpuContextSpecific->SetGpuContext(mosGpuCxt); |
| |
| pOsContextSpecific->SetGpuContextHandle(mosGpuCxt, gpuContextSpecific->GetGpuContextHandle()); |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| if (pOsContextSpecific->GetGpuContextHandle(mosGpuCxt) == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| auto gpuContext = gpuContextMgr->CreateGpuContext(GpuNode, cmdBufMgr, mosGpuCxt); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| auto gpuContextSpecific = static_cast<GpuContextSpecific *>(gpuContext); |
| MOS_OS_CHK_NULL_RETURN(gpuContextSpecific); |
| |
| MOS_OS_CHK_STATUS_RETURN(gpuContextSpecific->Init(gpuContextMgr->GetOsContext(), pOsInterface, GpuNode, createOption)); |
| |
| pOsContextSpecific->SetGpuContextHandle(mosGpuCxt, gpuContextSpecific->GetGpuContextHandle()); |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(mosGpuCxt); |
| MOS_UNUSED(GpuNode); |
| MOS_UNUSED(createOption); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| GPU_CONTEXT_HANDLE |
| Mos_Specific_CreateGpuComputeContext(MOS_INTERFACE *osInterface, |
| MOS_GPU_CONTEXT contextName, |
| MOS_GPUCTX_CREATOPTIONS *createOption) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| MOS_OS_CHK_NULL_RETURN(osInterface); |
| |
| if (MOS_GPU_CONTEXT_CM_COMPUTE != contextName |
| && MOS_GPU_CONTEXT_COMPUTE != contextName) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter contextName."); |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| |
| if (osInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| if (nullptr == createOption) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid pointer (nullptr)."); |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| |
| if (osInterface->apoMosEnabled) |
| { |
| if (nullptr == osInterface->osStreamState) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid pointer (nullptr)."); |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| |
| // Update ctxBasedScheduling from legacy OsInterface |
| osInterface->osStreamState->ctxBasedScheduling |
| = osInterface->ctxBasedScheduling; |
| |
| // Only wrapper will contain re-creation check based on stream Index and MOS_GPU_CONTEXT |
| createOption->gpuNode = MOS_GPU_NODE_COMPUTE; |
| GPU_CONTEXT_HANDLE context_handle = MOS_GPU_CONTEXT_INVALID_HANDLE; |
| MOS_STATUS status |
| = MosInterface::CreateGpuContext(osInterface->osStreamState, |
| *createOption, context_handle); |
| if (MOS_FAILED(status)) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| |
| auto os_device_context = osInterface->osStreamState->osDeviceContext; |
| auto gpu_context_mgr = os_device_context->GetGpuContextMgr(); |
| if (nullptr == gpu_context_mgr) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| GpuContextNext *context_next |
| = gpu_context_mgr->GetGpuContext(context_handle); |
| auto context_specific_next |
| = static_cast<GpuContextSpecificNext*>(context_next); |
| if (nullptr == context_specific_next) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| context_specific_next->SetGpuContext(contextName); |
| return context_handle; |
| } |
| else |
| { |
| auto os_context_specific |
| = static_cast<OsContextSpecific*>(osInterface->osContextPtr); |
| if (nullptr == os_context_specific) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| auto gpu_context_mgr = os_context_specific->GetGpuContextMgr(); |
| if (nullptr == gpu_context_mgr) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| auto cmd_buffer_mgr = os_context_specific->GetCmdBufMgr(); |
| if (nullptr == cmd_buffer_mgr) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| |
| GpuContext *gpu_context |
| = gpu_context_mgr->CreateGpuContext(MOS_GPU_NODE_COMPUTE, |
| cmd_buffer_mgr, |
| contextName); |
| auto *context_specific = static_cast<GpuContextSpecific*>(gpu_context); |
| if (nullptr == context_specific) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| MOS_STATUS status |
| = context_specific->Init(gpu_context_mgr->GetOsContext(), |
| osInterface, MOS_GPU_NODE_COMPUTE, |
| createOption); |
| if (MOS_STATUS_SUCCESS != status) |
| { |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| return context_specific->GetGpuContextHandle(); |
| } |
| } |
| return MOS_GPU_CONTEXT_INVALID_HANDLE; |
| } |
| |
| //! |
| //! \brief Destroy GPU context |
| //! \details Destroy GPU context |
| //! [in] Pointer to OS interface structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_DestroyGpuContext( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT mosGpuCxt) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (mosGpuCxt == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| MOS_OS_CHK_NULL_RETURN(pOsInterface->osContextPtr); |
| |
| OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr); |
| MOS_OS_CHK_NULL_RETURN(pOsContextSpecific); |
| |
| GPU_CONTEXT_HANDLE gpuContextHandle = pOsContextSpecific->GetGpuContextHandle(mosGpuCxt); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::DestroyGpuContext(pOsInterface->osStreamState, gpuContextHandle); |
| } |
| |
| GpuContextMgr *gpuContextMgr = pOsContextSpecific->GetGpuContextMgr(); |
| MOS_OS_CHK_NULL_RETURN(gpuContextMgr); |
| GpuContext *gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| gpuContextMgr->DestroyGpuContext(gpuContext); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(mosGpuCxt); |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Destroy Compute GPU context |
| //! \details Destroy Compute GPU context |
| //! [in] Pointer to OS interface structure |
| //! \param GPU_CONTEXT_HANDLE gpuContextHandle |
| //! [in] GPU Context handle |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_DestroyGpuComputeContext( |
| PMOS_INTERFACE osInterface, |
| GPU_CONTEXT_HANDLE gpuContextHandle) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(osInterface); |
| if(MOS_GPU_CONTEXT_INVALID_HANDLE == gpuContextHandle) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid compute gpu context handle."); |
| return MOS_STATUS_INVALID_HANDLE; |
| } |
| if (!osInterface->modularizedGpuCtxEnabled || Mos_Solo_IsEnabled(nullptr)) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(osInterface->osContextPtr); |
| MOS_OS_CHK_NULL_RETURN(pOsContextSpecific); |
| |
| GPU_CONTEXT_HANDLE iGpuContextHandle = pOsContextSpecific->GetGpuContextHandle(MOS_GPU_CONTEXT_CM_COMPUTE); |
| if(iGpuContextHandle == gpuContextHandle) |
| { |
| MOS_OS_ASSERTMESSAGE("It will be destroyed in osInterface destroy."); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| iGpuContextHandle = pOsContextSpecific->GetGpuContextHandle(MOS_GPU_CONTEXT_COMPUTE); |
| if(iGpuContextHandle == gpuContextHandle) |
| { |
| MOS_OS_ASSERTMESSAGE("It will be destroyed in osInterface destroy."); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| if (osInterface->apoMosEnabled) |
| { |
| auto gpuContext = MosInterface::GetGpuContext(osInterface->osStreamState, gpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| MOS_GPU_CONTEXT gpuContextName = gpuContext->GetCpuContextID(); |
| if(gpuContextName != MOS_GPU_CONTEXT_CM_COMPUTE && gpuContextName != MOS_GPU_CONTEXT_COMPUTE) |
| { |
| MOS_OS_ASSERTMESSAGE("It is not compute gpu context and it will be destroyed in osInterface destroy."); |
| return MOS_STATUS_SUCCESS; |
| } |
| return MosInterface::DestroyGpuContext(osInterface->osStreamState, gpuContextHandle); |
| } |
| |
| GpuContextMgr *gpuContextMgr = pOsContextSpecific->GetGpuContextMgr(); |
| MOS_OS_CHK_NULL_RETURN(gpuContextMgr); |
| GpuContext *gpuContext = gpuContextMgr->GetGpuContext(gpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| MOS_GPU_CONTEXT gpuContextName = gpuContext->GetCpuContextID(); |
| if(gpuContextName != MOS_GPU_CONTEXT_CM_COMPUTE && gpuContextName != MOS_GPU_CONTEXT_COMPUTE) |
| { |
| MOS_OS_ASSERTMESSAGE("It is not compute gpu context and it will be destroyed in osInterface destroy."); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| gpuContextMgr->DestroyGpuContext(gpuContext); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Sets the perf tag |
| //! \details Sets the perf tag |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \param uint32_t PerfTag |
| //! [in] Perf tag |
| //! \return void |
| //! |
| void Mos_Specific_SetPerfTag( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t PerfTag) |
| { |
| uint32_t ComponentTag; |
| |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface->osStreamState); |
| pOsInterface->osStreamState->component = pOsInterface->Component; |
| return MosInterface::SetPerfTag(pOsInterface->osStreamState, PerfTag); |
| } |
| |
| PMOS_CONTEXT pOsContext =(PMOS_CONTEXT)pOsInterface->pOsContext; |
| |
| if(pOsContext) |
| { |
| switch (pOsInterface->Component) |
| { |
| case COMPONENT_VPreP: |
| case COMPONENT_VPCommon: |
| ComponentTag = PERFTAG_VPREP; |
| break; |
| |
| case COMPONENT_LibVA: |
| ComponentTag = PERFTAG_LIBVA; |
| break; |
| |
| case COMPONENT_CM: |
| ComponentTag = PERFTAG_CM; |
| break; |
| |
| case COMPONENT_Decode: |
| ComponentTag = PERFTAG_DECODE; |
| break; |
| |
| case COMPONENT_Encode: |
| ComponentTag = PERFTAG_ENCODE; |
| break; |
| |
| default: |
| ComponentTag = 0xF000 & pOsContext->GetDmaBufID(pOsContext); |
| break; |
| } |
| |
| pOsContext->SetDmaBufID(pOsContext, ComponentTag | (PerfTag&0x0fff)); |
| } |
| |
| } |
| |
| //! |
| //! \brief Resets the perf tag |
| //! \details Resets the perf tag |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \return void |
| //! |
| void Mos_Specific_ResetPerfBufferID( |
| PMOS_INTERFACE pOsInterface) |
| { |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::ResetPerfBufferID(pOsInterface->osStreamState); |
| } |
| |
| PMOS_CONTEXT pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext; |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext); |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext->pPerfData); |
| pOsContext->pPerfData->bufferID = 0; |
| return; |
| } |
| |
| //! |
| //! \brief Increment the perf tag for buffer ID |
| //! \details Increment the perf tag for buffer ID |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \return void |
| //! |
| void Mos_Specific_IncPerfBufferID( |
| PMOS_INTERFACE pOsInterface) |
| { |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::IncPerfBufferID(pOsInterface->osStreamState); |
| } |
| |
| PMOS_CONTEXT pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext; |
| |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext); |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext->pPerfData); |
| |
| pOsContext->pPerfData->bufferID++; |
| return; |
| } |
| |
| //! |
| //! \brief Increment the perf tag for Frame ID |
| //! \details Increment the perf tag for frame ID |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \return void |
| //! |
| void Mos_Specific_IncPerfFrameID( |
| PMOS_INTERFACE pOsInterface) |
| { |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::IncPerfFrameID(pOsInterface->osStreamState); |
| } |
| |
| PMOS_CONTEXT pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext; |
| |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext); |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsContext->pPerfData); |
| |
| pOsContext->pPerfData->frameID++; |
| |
| } |
| |
| //! |
| //! \brief Gets the perf tag |
| //! \details Gets the perf tag |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS interface structure |
| //! \return uint32_t |
| //! Return perf tag |
| //! |
| uint32_t Mos_Specific_GetPerfTag( |
| PMOS_INTERFACE pOsInterface) |
| { |
| uint32_t perfTag; |
| |
| if (pOsInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("pOsInterface invalid nullptr"); |
| return 0; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetPerfTag(pOsInterface->osStreamState); |
| } |
| |
| PMOS_CONTEXT osContext = (PMOS_CONTEXT)pOsInterface->pOsContext; |
| |
| if (osContext == nullptr) |
| { |
| return 0; |
| } |
| |
| perfTag = *(uint32_t *)(osContext->pPerfData); |
| return perfTag; |
| } |
| |
| //! |
| //! \brief Set Hybrid Kernel ID |
| //! \details Set Hybrid Kernel ID |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param uint32_t KernelID |
| //! [in] Hybrid Decoder Kernel ID |
| //! \return void |
| //! |
| void Mos_Specific_SetPerfHybridKernelID( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t KernelID) |
| { |
| PMOS_CONTEXT pOsContext; |
| |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::SetPerfHybridKernelID(pOsInterface->osStreamState, KernelID); |
| } |
| |
| MOS_OS_CHK_NULL_NO_STATUS_RETURN(pOsInterface->pOsContext); |
| |
| pOsContext = (PMOS_CONTEXT)pOsInterface->pOsContext; |
| pOsContext->SetPerfHybridKernelID(pOsContext,KernelID); |
| } |
| |
| //! |
| //! \brief Check if Perf Tag is already set |
| //! \details Check if Perf Tag is already set |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \return int32_t |
| //! |
| int32_t Mos_Specific_IsPerfTagSet( |
| PMOS_INTERFACE pOsInterface) |
| { |
| uint32_t ComponentTag; |
| int32_t bRet = false; |
| PMOS_CONTEXT pOsContext; |
| |
| if(pOsInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("pOsInterface invalid nullptr"); |
| return bRet; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::IsPerfTagSet(pOsInterface->osStreamState); |
| } |
| |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| |
| pOsContext = (pOsInterface) ? (PMOS_CONTEXT)pOsInterface->pOsContext : nullptr; |
| bRet = false; |
| |
| if (pOsContext) |
| { |
| ComponentTag = 0xF000 & pOsContext->GetDmaBufID(pOsContext); |
| |
| switch (ComponentTag) |
| { |
| case PERFTAG_ENCODE: |
| case PERFTAG_DECODE: |
| bRet = true; |
| break; |
| |
| default: |
| bRet = false; |
| break; |
| } |
| } |
| |
| return bRet; |
| } |
| |
| //! |
| //! \brief Convet from OS to Mos format |
| //! \details need to refactor this function after libva ddi interface done, or after OS format defined |
| //! for Linux/Android |
| //! \param MOS_OS_FORMAT format |
| //! [in] OS surface format |
| //! \return MOS_FORMAT |
| //! Return Mos format |
| //! |
| MOS_FORMAT Mos_Specific_FmtOsToMos( |
| MOS_OS_FORMAT format) |
| { |
| switch (static_cast<int>(format)) |
| { |
| case DDI_FORMAT_A8B8G8R8 : return Format_A8R8G8B8; |
| case DDI_FORMAT_X8B8G8R8 : return Format_X8R8G8B8; |
| case DDI_FORMAT_R32F : return Format_R32F; |
| case DDI_FORMAT_A8R8G8B8 : return Format_A8R8G8B8; |
| case DDI_FORMAT_X8R8G8B8 : return Format_X8R8G8B8; |
| case DDI_FORMAT_R5G6B5 : return Format_R5G6B5; |
| case DDI_FORMAT_YUY2 : return Format_YUY2; |
| case DDI_FORMAT_P8 : return Format_P8; |
| case DDI_FORMAT_A8P8 : return Format_A8P8; |
| case DDI_FORMAT_A8 : return Format_A8; |
| case DDI_FORMAT_L8 : return Format_L8; |
| case DDI_FORMAT_L16 : return Format_L16; |
| case DDI_FORMAT_A4L4 : return Format_A4L4; |
| case DDI_FORMAT_A8L8 : return Format_A8L8; |
| case DDI_FORMAT_V8U8 : return Format_V8U8; |
| case DDI_FORMAT_A16B16G16R16 : return Format_A16B16G16R16; |
| case DDI_FORMAT_R32G32B32A32F: return Format_R32G32B32A32F; |
| case FOURCC_YVYU : return Format_YVYU; |
| case FOURCC_UYVY : return Format_UYVY; |
| case FOURCC_VYUY : return Format_VYUY; |
| case FOURCC_AYUV : return Format_AYUV; |
| case FOURCC_NV12 : return Format_NV12; |
| case FOURCC_NV21 : return Format_NV21; |
| case FOURCC_NV11 : return Format_NV11; |
| case FOURCC_P208 : return Format_P208; |
| case FOURCC_IMC1 : return Format_IMC1; |
| case FOURCC_IMC2 : return Format_IMC2; |
| case FOURCC_IMC3 : return Format_IMC3; |
| case FOURCC_IMC4 : return Format_IMC4; |
| case FOURCC_I420 : return Format_I420; |
| case FOURCC_IYUV : return Format_IYUV; |
| case FOURCC_YV12 : return Format_YV12; |
| case FOURCC_YVU9 : return Format_YVU9; |
| case FOURCC_AI44 : return Format_AI44; |
| case FOURCC_IA44 : return Format_IA44; |
| case FOURCC_400P : return Format_400P; |
| case FOURCC_411P : return Format_411P; |
| case FOURCC_411R : return Format_411R; |
| case FOURCC_422H : return Format_422H; |
| case FOURCC_422V : return Format_422V; |
| case FOURCC_444P : return Format_444P; |
| case FOURCC_RGBP : return Format_RGBP; |
| case FOURCC_BGRP : return Format_BGRP; |
| case FOURCC_P010 : return Format_P010; |
| case FOURCC_P016 : return Format_P016; |
| case FOURCC_Y216 : return Format_Y216; |
| case FOURCC_Y416 : return Format_Y416; |
| case FOURCC_Y210 : return Format_Y210; |
| case FOURCC_Y410 : return Format_Y410; |
| default : return Format_Invalid; |
| } |
| } |
| |
| //! |
| //! \brief Convet from MOS OS to OS format |
| //! \details need to refactor this function after libva ddi interface done, or after OS format defined |
| //! for Linux/Android |
| //! \param MOS_FORMAT format |
| //! [in] MOS OS surface format |
| //! \return MOS_OS_FORMAT |
| //! Return OS format |
| //! |
| MOS_OS_FORMAT Mos_Specific_FmtMosToOs( |
| MOS_FORMAT format) |
| { |
| switch (format) |
| { |
| case Format_A8R8G8B8 : return (MOS_OS_FORMAT)DDI_FORMAT_A8R8G8B8; |
| case Format_X8R8G8B8 : return (MOS_OS_FORMAT)DDI_FORMAT_X8R8G8B8; |
| case Format_A8B8G8R8 : return (MOS_OS_FORMAT)DDI_FORMAT_A8B8G8R8; |
| case Format_R32U : return (MOS_OS_FORMAT)DDI_FORMAT_R32F; |
| case Format_R32F : return (MOS_OS_FORMAT)DDI_FORMAT_R32F; |
| case Format_R5G6B5 : return (MOS_OS_FORMAT)DDI_FORMAT_R5G6B5; |
| case Format_YUY2 : return (MOS_OS_FORMAT)DDI_FORMAT_YUY2; |
| case Format_P8 : return (MOS_OS_FORMAT)DDI_FORMAT_P8; |
| case Format_A8P8 : return (MOS_OS_FORMAT)DDI_FORMAT_A8P8; |
| case Format_A8 : return (MOS_OS_FORMAT)DDI_FORMAT_A8; |
| case Format_L8 : return (MOS_OS_FORMAT)DDI_FORMAT_L8; |
| case Format_L16 : return (MOS_OS_FORMAT)DDI_FORMAT_L16; |
| case Format_A4L4 : return (MOS_OS_FORMAT)DDI_FORMAT_A4L4; |
| case Format_A8L8 : return (MOS_OS_FORMAT)DDI_FORMAT_A8L8; |
| case Format_V8U8 : return (MOS_OS_FORMAT)DDI_FORMAT_V8U8; |
| case Format_YVYU : return (MOS_OS_FORMAT)FOURCC_YVYU; |
| case Format_UYVY : return (MOS_OS_FORMAT)FOURCC_UYVY; |
| case Format_VYUY : return (MOS_OS_FORMAT)FOURCC_VYUY; |
| case Format_AYUV : return (MOS_OS_FORMAT)FOURCC_AYUV; |
| case Format_NV12 : return (MOS_OS_FORMAT)FOURCC_NV12; |
| case Format_NV21 : return (MOS_OS_FORMAT)FOURCC_NV21; |
| case Format_NV11 : return (MOS_OS_FORMAT)FOURCC_NV11; |
| case Format_P208 : return (MOS_OS_FORMAT)FOURCC_P208; |
| case Format_IMC1 : return (MOS_OS_FORMAT)FOURCC_IMC1; |
| case Format_IMC2 : return (MOS_OS_FORMAT)FOURCC_IMC2; |
| case Format_IMC3 : return (MOS_OS_FORMAT)FOURCC_IMC3; |
| case Format_IMC4 : return (MOS_OS_FORMAT)FOURCC_IMC4; |
| case Format_I420 : return (MOS_OS_FORMAT)FOURCC_I420; |
| case Format_IYUV : return (MOS_OS_FORMAT)FOURCC_IYUV; |
| case Format_YV12 : return (MOS_OS_FORMAT)FOURCC_YV12; |
| case Format_YVU9 : return (MOS_OS_FORMAT)FOURCC_YVU9; |
| case Format_AI44 : return (MOS_OS_FORMAT)FOURCC_AI44; |
| case Format_IA44 : return (MOS_OS_FORMAT)FOURCC_IA44; |
| case Format_400P : return (MOS_OS_FORMAT)FOURCC_400P; |
| case Format_411P : return (MOS_OS_FORMAT)FOURCC_411P; |
| case Format_411R : return (MOS_OS_FORMAT)FOURCC_411R; |
| case Format_422H : return (MOS_OS_FORMAT)FOURCC_422H; |
| case Format_422V : return (MOS_OS_FORMAT)FOURCC_422V; |
| case Format_444P : return (MOS_OS_FORMAT)FOURCC_444P; |
| case Format_RGBP : return (MOS_OS_FORMAT)FOURCC_RGBP; |
| case Format_BGRP : return (MOS_OS_FORMAT)FOURCC_BGRP; |
| case Format_STMM : return (MOS_OS_FORMAT)DDI_FORMAT_P8; |
| case Format_P010 : return (MOS_OS_FORMAT)FOURCC_P010; |
| case Format_P016 : return (MOS_OS_FORMAT)FOURCC_P016; |
| case Format_Y216 : return (MOS_OS_FORMAT)FOURCC_Y216; |
| case Format_Y416 : return (MOS_OS_FORMAT)FOURCC_Y416; |
| case Format_A16B16G16R16 : return (MOS_OS_FORMAT)DDI_FORMAT_A16B16G16R16; |
| case Format_Y210 : return (MOS_OS_FORMAT)FOURCC_Y216; |
| case Format_Y410 : return (MOS_OS_FORMAT)FOURCC_Y410; |
| case Format_R32G32B32A32F: return (MOS_OS_FORMAT)DDI_FORMAT_R32G32B32A32F; |
| default : return (MOS_OS_FORMAT)DDI_FORMAT_UNKNOWN; |
| } |
| } |
| |
| //! |
| //! \brief Check for GPU context valid |
| //! \details Always returns MOS_STATUS_SUCCESS on Linux. |
| // This interface is implemented for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to Os interface structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] Gpu Context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_IsGpuContextValid( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(GpuContext); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Unified OS Resources sync |
| //! \details Tag based synchronization at the resource level |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS Resource |
| //! \param MOS_GPU_CONTEXT requestorGPUCtx |
| //! [in] GPU Context |
| //! \param int32_t bWriteOperation |
| //! [in] true if write operation |
| //! \return void |
| //! |
| void Mos_Specific_SyncOnResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| MOS_GPU_CONTEXT requestorGPUCtx, |
| int32_t bWriteOperation) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pOsResource); |
| MOS_UNUSED(requestorGPUCtx); |
| MOS_UNUSED(bWriteOperation); |
| } |
| |
| //! |
| //! \brief Synchronize GPU context |
| //! \details Synchronize GPU context |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param MOS_GPU_CONTEXT busyGPUCtx |
| //! [in] Busy context id being requested to sync with |
| //! \param MOS_GPU_CONTEXT requestorGPUCtx |
| //! [in] Requestor context id |
| //! \return void |
| //! |
| void Mos_Specific_SyncGpuContext( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT busyGPUCtx, |
| MOS_GPU_CONTEXT requestorGPUCtx) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(busyGPUCtx); |
| MOS_UNUSED(requestorGPUCtx); |
| } |
| |
| //! |
| //! \brief Synchronize 3d GPU context |
| //! \details Synchronize 3d GPU context |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param PMOS_SYNC_PARAMS pSyncParams |
| //! [in] Sync parameters |
| //! \return void |
| //! |
| void Mos_Specific_SyncWith3DContext( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_SYNC_PARAMS pSyncParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pSyncParams); |
| } |
| |
| //! |
| //! \brief Checks for HW enabled |
| //! \details Checks for HW enabled |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to Os interface structure |
| //! \return int32_t |
| //! Returns true id HW enabled if CP mode |
| //! |
| int32_t Mos_Specific_IsNullHWEnabled( |
| PMOS_INTERFACE pOsInterface) |
| { |
| MOS_UNUSED(pOsInterface); |
| return false; |
| } |
| |
| //! |
| //! \brief Get GPU status buffer |
| //! \details Gets the status buffer for the resource |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [out] Pointer to OS Resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetGpuStatusBufferResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE &pOsResource) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetGpuStatusBufferResource(pOsInterface->osStreamState, pOsResource, pOsInterface->osStreamState->currentGpuContextHandle); |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| auto resource = gpuContext->GetStatusBufferResource(); |
| MOS_OS_CHK_NULL_RETURN(resource); |
| |
| pOsResource = gpuContext->GetStatusBufferMosResource(); |
| MOS_OS_CHK_NULL_RETURN(pOsResource); |
| MOS_ZeroMemory(pOsResource, sizeof(MOS_RESOURCE)); |
| |
| MOS_OS_CHK_STATUS_RETURN(resource->ConvertToMosResource(pOsResource)); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| PMOS_CONTEXT pOsContext; |
| |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| |
| pOsContext = pOsInterface->pOsContext; |
| |
| pOsResource = pOsContext->pGPUStatusBuffer; |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get GPU status tag offset |
| //! \details Gets the status tag offset |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return uint32_t |
| //! Returns the tag offset |
| //! |
| uint32_t Mos_Specific_GetGpuStatusTagOffset( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| uint32_t offset = 0; |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| // always 0 in apo |
| return 0; |
| } |
| // A gobal status buffer for all GPU contexts is no longer used when modulized GPU context enabled, |
| // replace with separate buffer corresponding to each GPU context and the offset will be 0 |
| if (!pOsInterface->modularizedGpuCtxEnabled || Mos_Solo_IsEnabled(nullptr)) |
| { |
| offset = sizeof(MOS_GPU_STATUS_DATA) * GpuContext; |
| } |
| |
| return offset; |
| } |
| |
| //! |
| //! \brief Get GPU status tag |
| //! \details Gets the status tag |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return uint32_t |
| //! Returns the tag |
| //! |
| uint32_t Mos_Specific_GetGpuStatusTag( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT mosGpuCtx) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsInterface); |
| |
| if (mosGpuCtx == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return -1; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| if (pOsInterface->osContextPtr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid input parameters!"); |
| return 0; |
| } |
| |
| auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| |
| auto handle = osCxtSpecific->GetGpuContextHandle(mosGpuCtx); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetGpuStatusTag(pOsInterface->osStreamState, handle); |
| } |
| |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, handle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return gpuContext->GetGpuStatusTag(); |
| } |
| |
| PMOS_CONTEXT pOsContext; |
| |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| //------------------------------------ |
| |
| pOsContext = pOsInterface->pOsContext; |
| |
| return pOsContext->pfnGetGpuCtxBufferTag(pOsContext, mosGpuCtx); |
| } |
| |
| //! |
| //! \brief Increment GPU status tag |
| //! \details Increment the status tag |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return void |
| //! |
| void Mos_Specific_IncrementGpuStatusTag( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT mosGpuCtx) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsInterface); |
| |
| if (mosGpuCtx == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| if (pOsInterface->osContextPtr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("invalid input parameters!"); |
| return; |
| } |
| |
| auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| |
| auto handle = osCxtSpecific->GetGpuContextHandle(mosGpuCtx); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| MosInterface::IncrementGpuStatusTag(pOsInterface->osStreamState, handle); |
| return; |
| } |
| |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, handle); |
| |
| if (gpuContext) |
| { |
| gpuContext->IncrementGpuStatusTag(); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("Cannot get valid Gpu context!"); |
| } |
| } |
| |
| PMOS_CONTEXT pOsContext; |
| |
| //------------------------------------ |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pOsInterface->pOsContext); |
| //------------------------------------ |
| |
| pOsContext = pOsInterface->pOsContext; |
| |
| pOsContext->pfnIncGpuCtxBufferTag(pOsContext, mosGpuCtx); |
| } |
| |
| //! |
| //! \brief Get GPU status Sync tag |
| //! \details This function will return the GPU status tag which is updated when corresponding |
| //! GPU packet is done. User can use this flag to check if some GPU packet is done. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return uint32_t |
| //! Returns the tag |
| //! |
| uint32_t Mos_Specific_GetGpuStatusSyncTag( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(GpuContext); |
| return 0; |
| } |
| |
| //! |
| //! \brief Sets the resource sync tag |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_SYNC_PARAMS pParams |
| //! [in] Pointer to sync params |
| //! \return void |
| //! |
| void Mos_Specific_SetResourceSyncTag( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_SYNC_PARAMS pParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pParams); |
| return ; |
| } |
| |
| //! |
| //! \brief Perform overlay sync |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_SYNC_PARAMS pParams |
| //! [in] Pointer to sync params |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_PerformOverlaySync( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_SYNC_PARAMS pParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pParams); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Signal OS Engine |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_SYNC_PARAMS pParams |
| //! [in] Pointer to sync params |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_EngineSignal( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_SYNC_PARAMS pParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pParams); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Wait on sync |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_SYNC_PARAMS pParams |
| //! [in] Pointer to sync params |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_EngineWait( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_SYNC_PARAMS pParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pParams); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Signal on resource |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_SYNC_PARAMS pParams |
| //! [in] Pointer to sync params |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_ResourceSignal( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_SYNC_PARAMS pParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pParams); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Wait on resource |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_SYNC_PARAMS pParams |
| //! [in] Pointer to sync params |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_ResourceWait( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_SYNC_PARAMS pParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pParams); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Create Sync Resource |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_CreateSyncResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pOsResource); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Destroy Sync resource |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_DestroySyncResource( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pOsResource); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Initializes the tags for Hybrid Decode multi-threading sync |
| //! \details Initializes the tags for Hybrid Decode multi-threading sync |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS resource |
| //! \param uint8_t ucRenderTargetIndex |
| //! [in] Index of render target in pSemHandleList for pOsResource |
| //! \param PMOS_SEMAPHORE *pCurFrmSem |
| //! [in] List of semaphore handles used for current frame sync |
| //! \param PMOS_SEMAPHORE *pRefFrmSem |
| //! [in] List of semaphore handles used for reference frame sync |
| //! \param PMOS_MUTEX *pFrmMutex |
| //! [in] List of mutex handles of frame lock mutex |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS Mos_Specific_InitializeMultiThreadingSyncTags( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| uint8_t ucRenderTargetIndex, |
| PMOS_SEMAPHORE *pCurFrmSem, |
| PMOS_SEMAPHORE *pRefFrmSem, |
| PMOS_MUTEX *pFrmMutex) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsResource); |
| MOS_OS_CHK_NULL(pCurFrmSem); |
| MOS_OS_CHK_NULL(pRefFrmSem); |
| |
| if(*pOsResource->ppReferenceFrameSemaphore == nullptr) |
| { |
| *pOsResource->ppReferenceFrameSemaphore = MOS_CreateSemaphore(1, 1); |
| } |
| |
| if(*pOsResource->ppCurrentFrameSemaphore == nullptr) |
| { |
| *pOsResource->ppCurrentFrameSemaphore = MOS_CreateSemaphore(1, 1); |
| } |
| |
| if((*pOsResource->ppReferenceFrameSemaphore != nullptr) && (*pOsResource->ppCurrentFrameSemaphore != nullptr)) |
| { |
| pCurFrmSem[ucRenderTargetIndex] = *pOsResource->ppCurrentFrameSemaphore; |
| pRefFrmSem[ucRenderTargetIndex] = *pOsResource->ppReferenceFrameSemaphore; |
| pFrmMutex[ucRenderTargetIndex] = nullptr; |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Wait current frame's semaphore for Hybrid Decode multi-threading sync |
| //! \details Wait current frame's semaphore for Hybrid Decode multi-threading sync |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS resource |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS Mos_Specific_MultiThreadingWaitCurrentFrame( |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsResource); |
| |
| MOS_OS_CHK_STATUS(MOS_WaitSemaphore(*pOsResource->ppCurrentFrameSemaphore, INFINITE)); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Post current frame's semaphore for Hybrid Decode multi-threading sync |
| //! \details Post current frame's semaphore for Hybrid Decode multi-threading sync |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS resource |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS Mos_Specific_MultiThreadingPostCurrentFrame( |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsResource); |
| |
| MOS_OS_CHK_STATUS(MOS_PostSemaphore(*pOsResource->ppCurrentFrameSemaphore, 1)); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Sets hybrid decoder running flag |
| //! \details Sets hybrid decoder running flag to indicate there is a hybrid decoder |
| //! is running |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param int32_t bFlag |
| //! [in] hybrid decoder (HEVC or VP9) running flag |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS Mos_Specific_SetHybridDecoderRunningFlag( |
| PMOS_INTERFACE pOsInterface, |
| int32_t bFlag) |
| { |
| PMOS_CONTEXT pOsContext; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsInterface->pOsContext); |
| |
| pOsContext = pOsInterface->pOsContext; |
| pOsContext->bHybridDecoderRunningFlag = bFlag; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Gets hybrid decoder running flag |
| //! \details Gets hybrid decoder running flag to decide if hybrid decoder is being used |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param int32_t bFlag |
| //! [in] hybrid decoder (HEVC or VP9) running flag |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS Mos_Specific_GetHybridDecoderRunningFlag( |
| PMOS_INTERFACE pOsInterface, |
| int32_t *pFlag) |
| { |
| PMOS_CONTEXT pOsContext; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_CHK_NULL(pFlag); |
| *pFlag = false; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsInterface->pOsContext); |
| |
| pOsContext = pOsInterface->pOsContext; |
| *pFlag = pOsContext->bHybridDecoderRunningFlag; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Multi thread resource sync method |
| //! \details Dummy implementation on Linux for compatibility. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS resource |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS Mos_Specific_MultiThreadResourceSync( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pOsResource); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Registers a complete notification event |
| //! \details Registers a complete notification event |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU Context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_RegisterBBCompleteNotifyEvent( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(GpuContext); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Waits on a complete notification event |
| //! \details Waits on a complete notification event |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param uint32_t uiTimeOut |
| //! [in] Time to wait |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS |
| //! |
| MOS_STATUS Mos_Specific_WaitForBBCompleteNotifyEvent( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext, |
| uint32_t uiTimeOut) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(GpuContext); |
| usleep(uiTimeOut); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_STATUS Mos_Specific_WaitAllCmdCompletion_Os( |
| PMOS_INTERFACE pOsInterface) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Determines if the resource should be CPU cacheable during allocation |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_ALLOC_GFXRES_PARAMS pAllocParams |
| //! [in] allocation parameters |
| //! \return int32_t |
| //! Return if resource should be CPU cacheable |
| //! |
| int32_t Mos_Specific_SetCpuCacheability( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_ALLOC_GFXRES_PARAMS pAllocParams) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(pAllocParams); |
| return false; |
| } |
| |
| //! |
| //! \brief Sets the flags to skip the sync on a particular resource |
| //! \details This is required to avoid updating resource tags/masks for a given resource |
| //! This way we dont end up putting unnecessary sync points by syncing on this particular resource |
| //! \param PMOS_ALLOC_GFXRES_PARAMS pAllocParams |
| //! [in] allocation parameters |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if success else failure reason |
| //! |
| MOS_STATUS Mos_Specific_SkipResourceSync( |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| //--------------------------------------- |
| MOS_OS_CHK_NULL(pOsResource); |
| //--------------------------------------- |
| |
| mos_bo_set_object_async(pOsResource->bo); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Gets the HW rendering flags |
| //! \details Gets the HW rendering flags |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return MOS_NULL_RENDERING_FLAGS |
| //! Returns the null rendering flags |
| //! |
| MOS_NULL_RENDERING_FLAGS Mos_Specific_GetNullHWRenderFlags( |
| PMOS_INTERFACE pOsInterface) |
| { |
| return pOsInterface->NullHWAccelerationEnable; |
| } |
| |
| //! |
| //! \brief Debug hook to note type of surface state or sampler state being |
| //! used. |
| //! \details Sets the Command buffer debug info |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param int32_t bSamplerState |
| //! [in] Sampler state |
| //! \param int32_t bSurfaceState |
| //! [in] Surface state |
| //! \param uint32_t dwStateIndex |
| //! [in] State index |
| //! \param uint32_t dwType |
| //! [in] dword type |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SetCmdBufferDebugInfo( |
| PMOS_INTERFACE pOsInterface, |
| int32_t bSamplerState, |
| int32_t bSurfaceState, |
| uint32_t dwStateIndex, |
| uint32_t dwType) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(bSamplerState); |
| MOS_UNUSED(bSurfaceState); |
| MOS_UNUSED(dwStateIndex); |
| MOS_UNUSED(dwType); |
| // stub function. implemented for simulation but not driver. |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Command buffer debug |
| //! \details Debug hook to get type of surface state or sampler state being |
| //! used. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! \param int32_t bSamplerState |
| //! \param int32_t bSurfaceState |
| //! \param uint32_t dwStateIndex |
| //! \return uint32_t |
| //! |
| uint32_t Mos_Specific_GetCmdBufferDebugInfo( |
| PMOS_INTERFACE pOsInterface, |
| int32_t bSamplerState, |
| int32_t bSurfaceState, |
| uint32_t dwStateIndex) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(bSamplerState); |
| MOS_UNUSED(bSurfaceState); |
| MOS_UNUSED(dwStateIndex); |
| // stub function. implemented for simulation but not driver. |
| return 0; |
| } |
| |
| //! |
| //! \brief Set PAK/MFX context for Encoder which can be used for Synchronization |
| //! \details On Linux, the synchronization is handled in KMD, no job in UMD |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| void Mos_Specific_SetEncodePakContext( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(GpuContext); |
| return; |
| } |
| |
| //! |
| //! \brief Set VME/ENC context for Encoder which can be used for Synchronization |
| //! \details On Linux, the synchronization is handled in KMD, no job in UMD |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param MOS_GPU_CONTEXT GpuContext |
| //! [in] GPU context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| void Mos_Specific_SetEncodeEncContext( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_CONTEXT GpuContext) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(GpuContext); |
| return; |
| } |
| |
| //! |
| //! \brief Verifys the patch list to be used for rendering GPU commands is large enough |
| //! \details |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param uint32_t dwRequestedSize |
| //! [in] patch list size to be verified |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_VerifyPatchListSize( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t dwRequestedSize) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| // No APO MOS interface support for this func, implement in wrapper |
| auto streamState = pOsInterface->osStreamState; |
| |
| MOS_OS_CHK_NULL_RETURN(streamState); |
| MOS_OS_CHK_NULL_RETURN(streamState->osDeviceContext); |
| |
| auto osDeviceContext = streamState->osDeviceContext; |
| |
| auto gpuContextMgr = osDeviceContext->GetGpuContextMgr(); |
| if (gpuContextMgr) |
| { |
| auto gpuCtx = gpuContextMgr->GetGpuContext(streamState->currentGpuContextHandle); |
| |
| auto gpuCtxSpecific = static_cast<GpuContextSpecificNext *>(gpuCtx); |
| MOS_OS_CHK_NULL_RETURN(gpuCtxSpecific); |
| return (gpuCtxSpecific->VerifyPatchListSize(dwRequestedSize)); |
| } |
| } |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return (gpuContext->VerifyPatchListSize(dwRequestedSize)); |
| } |
| |
| MOS_STATUS eStatus; |
| PMOS_OS_CONTEXT pOsContext; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext; |
| |
| MOS_OS_CHK_NULL(pOsInterface); |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| pOsContext = pOsInterface->pOsContext; |
| MOS_OS_CHK_NULL(pOsContext); |
| |
| pOsGpuContext = &(pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]); |
| if (dwRequestedSize > pOsGpuContext->uiMaxPatchLocationsize) |
| { |
| eStatus = MOS_STATUS_UNKNOWN; |
| } |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief reset command buffer space |
| //! \details resets the command buffer space |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param PMOS_COMMAND_BUFFER pCmdBuffer |
| //! [in] pointer to command buffer structure |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_ResetCommandBuffer( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_COMMAND_BUFFER pCmdBuffer) |
| { |
| PMOS_OS_CONTEXT pOsContext; |
| PMOS_OS_GPU_CONTEXT pOsGpuContext; |
| MOS_UNUSED(pCmdBuffer); |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pCmdBuffer); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::ResetCommandBuffer(pOsInterface->osStreamState, pCmdBuffer); |
| } |
| |
| if (pOsInterface->CurrentGpuContextOrdinal == MOS_GPU_CONTEXT_INVALID_HANDLE) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid input parameter GpuContext."); |
| return MOS_STATUS_INVALID_PARAMETER; |
| } |
| |
| if (pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_CHK_NULL_RETURN(gpuContext); |
| |
| return gpuContext->ResetCommandBuffer(); |
| } |
| |
| pOsContext = pOsInterface->pOsContext; |
| pOsGpuContext = &pOsContext->OsGpuContext[pOsInterface->CurrentGpuContextOrdinal]; |
| |
| pOsGpuContext->bCBFlushed = true; |
| |
| finish: |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Get the memory compression mode |
| //! \details Gets the memory compression mode from GMM |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] pointer to input OS resource |
| //! \param PMOS_MEMCOMP_STATE pResMmcMode |
| //! [out] the memory compression mode gotten from OS resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetMemoryCompressionMode( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| PMOS_MEMCOMP_STATE pResMmcMode) |
| { |
| PGMM_RESOURCE_INFO pGmmResourceInfo; |
| GMM_RESOURCE_FLAG flags; |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_CHK_NULL_RETURN(pOsResource); |
| MOS_OS_CHK_NULL_RETURN(pResMmcMode); |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| |
| MediaFeatureTable* skuTable = nullptr; |
| skuTable = pOsInterface->pfnGetSkuTable(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(skuTable); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetMemoryCompressionMode(pOsInterface->osStreamState, pOsResource, *pResMmcMode); |
| } |
| |
| // Get Gmm resource info |
| pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo; |
| MOS_OS_CHK_NULL_RETURN(pGmmResourceInfo); |
| |
| flags = pOsResource->pGmmResInfo->GetResFlags(); |
| |
| if (!flags.Gpu.MMC || !flags.Gpu.CCS) |
| { |
| *pResMmcMode = MOS_MEMCOMP_DISABLED; |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| if (flags.Info.MediaCompressed || flags.Info.RenderCompressed) |
| { |
| *pResMmcMode = flags.Info.RenderCompressed ? MOS_MEMCOMP_RC : MOS_MEMCOMP_MC; |
| } |
| else |
| { |
| switch (pGmmResourceInfo->GetMmcMode(0)) |
| { |
| case GMM_MMC_HORIZONTAL: |
| *pResMmcMode = MOS_MEMCOMP_HORIZONTAL; |
| break; |
| case GMM_MMC_VERTICAL: |
| *pResMmcMode = MOS_MEMCOMP_VERTICAL; |
| break; |
| case GMM_MMC_DISABLED: |
| default: |
| *pResMmcMode = MOS_MEMCOMP_DISABLED; |
| break; |
| } |
| } |
| |
| uint32_t MmcFormat = 0; |
| GMM_RESOURCE_FORMAT gmmResFmt; |
| |
| gmmResFmt = pGmmResourceInfo->GetResourceFormat(); |
| |
| if (*pResMmcMode == MOS_MEMCOMP_MC && |
| (!MEDIA_IS_SKU(skuTable, FtrFlatPhysCCS))) |
| { |
| MmcFormat = static_cast<uint32_t>(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetMediaSurfaceStateCompressionFormat(gmmResFmt)); |
| *pResMmcMode = (MmcFormat != 0) ? *pResMmcMode : MOS_MEMCOMP_DISABLED; |
| } |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Set the memory compression mode in GMM |
| //! \details Set the memory compression mode |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] pointer to input OS resource |
| //! \param MOS_MEMCOMP_STATE ResMmcMode |
| //! [in] the memory compression mode to be set into OS resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SetMemoryCompressionMode( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| MOS_MEMCOMP_STATE ResMmcMode) |
| { |
| PGMM_RESOURCE_INFO pGmmResourceInfo = nullptr; |
| GMM_RESOURCE_MMC_INFO GmmResMmcMode = GMM_MMC_DISABLED; |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_FUNCTION_ENTER; |
| MOS_OS_CHK_NULL(pOsResource); |
| MOS_OS_CHK_NULL(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::SetMemoryCompressionMode(pOsInterface->osStreamState, pOsResource, ResMmcMode); |
| } |
| |
| // Get Gmm resource info |
| pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo; |
| MOS_OS_CHK_NULL(pGmmResourceInfo); |
| |
| switch (ResMmcMode) |
| { |
| case MOS_MEMCOMP_HORIZONTAL: |
| GmmResMmcMode = GMM_MMC_HORIZONTAL; |
| break; |
| case MOS_MEMCOMP_VERTICAL: |
| GmmResMmcMode = GMM_MMC_VERTICAL; |
| break; |
| case MOS_MEMCOMP_DISABLED: |
| default: |
| GmmResMmcMode = GMM_MMC_DISABLED; |
| break; |
| } |
| |
| pGmmResourceInfo->SetMmcMode(GmmResMmcMode, 0); |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Set the memory compression hint in GMM on Linux or Gralloc on Android |
| //! \details Indicate if the surface is compressible |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] pointer to input OS resource |
| //! \param int32_t bHintOn |
| //! [in] the memory compression hint to be set |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_SetMemoryCompressionHint( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| int32_t bHintOn) |
| { |
| PGMM_RESOURCE_INFO pGmmResourceInfo = nullptr; |
| uint32_t uiArrayIndex = 0; |
| MOS_STATUS eStatus; |
| MOS_OS_FUNCTION_ENTER; |
| eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_CHK_NULL(pOsResource); |
| MOS_OS_CHK_NULL(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::SetMemoryCompressionHint(pOsInterface->osStreamState, pOsResource, bHintOn); |
| } |
| |
| // Get Gmm resource info |
| pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo; |
| MOS_OS_CHK_NULL(pGmmResourceInfo); |
| |
| pGmmResourceInfo->SetMmcHint(bHintOn ? GMM_MMC_HINT_ON : GMM_MMC_HINT_OFF, uiArrayIndex); |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Get the memory compression format |
| //! \details Gets the memory compression format from GMM |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] pointer to OS interface structure |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] pointer to input OS resource |
| //! \param uint32_t *pResMmcFormat |
| //! [out] the memory compression format gotten from GMM resource |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_GetMemoryCompressionFormat( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource, |
| uint32_t *pResMmcFormat) |
| { |
| |
| PGMM_RESOURCE_INFO pGmmResourceInfo; |
| MOS_STATUS eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_FUNCTION_ENTER; |
| MOS_OS_CHK_NULL(pOsResource); |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pResMmcFormat); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetMemoryCompressionFormat(pOsInterface->osStreamState, pOsResource, pResMmcFormat); |
| } |
| |
| // Get Gmm resource info |
| pGmmResourceInfo = (GMM_RESOURCE_INFO*)pOsResource->pGmmResInfo; |
| MOS_OS_CHK_NULL(pGmmResourceInfo); |
| |
| MOS_OS_CHK_NULL(pOsInterface->pfnGetGmmClientContext(pOsInterface)); |
| // Get compression format from GMM RESOURCE FORMAT |
| GMM_RESOURCE_FORMAT gmmResFmt; |
| gmmResFmt = pGmmResourceInfo->GetResourceFormat(); |
| MOS_MEMCOMP_STATE MmcMode; |
| uint32_t MmcFormat; |
| Mos_Specific_GetMemoryCompressionMode(pOsInterface, pOsResource, &MmcMode); |
| switch (MmcMode) |
| { |
| case MOS_MEMCOMP_MC: |
| MmcFormat = static_cast<uint32_t>(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetMediaSurfaceStateCompressionFormat(gmmResFmt)); |
| break; |
| case MOS_MEMCOMP_RC: |
| MmcFormat = static_cast<uint32_t>(pOsInterface->pfnGetGmmClientContext(pOsInterface)->GetSurfaceStateCompressionFormat(gmmResFmt)); |
| break; |
| default: |
| MmcFormat = 0; |
| } |
| |
| if (MmcFormat > 0x1F) |
| { |
| MOS_OS_ASSERTMESSAGE("Get a incorrect Compression format(%d) from GMM", MmcFormat); |
| } |
| else |
| { |
| *pResMmcFormat = MmcFormat; |
| MOS_OS_VERBOSEMESSAGE("GMM compression mode %d, compression format %d", MmcMode, MmcFormat); |
| } |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| return eStatus; |
| |
| } |
| |
| #ifdef ANDROID |
| //! |
| //! \brief Create GPU node association. |
| //! \details Create GPU node association. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param MOS_MEDIA_OPERATION MediaOperation |
| //! [in] Media operation |
| //! \param MOS_GPU_NODE *pVideoNodeOrdinal |
| //! [out] VCS node ordinal |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, otherwise error code |
| //! |
| MOS_STATUS Mos_Specific_CreateVideoNodeAssociation( |
| PMOS_INTERFACE pOsInterface, |
| int32_t bSetVideoNode, |
| MOS_GPU_NODE *pVideoNodeOrdinal) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(bSetVideoNode); |
| MOS_OS_ASSERT(pVideoNodeOrdinal); |
| |
| // return VDBox #1 for now. |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO; |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| //! |
| //! \brief Destroy GPU node association. |
| //! \details Destroy GPU node association. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param MOS_GPU_NODE VideoNodeOrdinal |
| //! [in] VCS node ordinal |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, otherwise error code |
| //! |
| MOS_STATUS Mos_Specific_DestroyVideoNodeAssociation( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_NODE VideoNodeOrdinal) |
| { |
| MOS_UNUSED(pOsInterface); |
| MOS_UNUSED(VideoNodeOrdinal); |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| #else |
| |
| //! |
| //! \brief Create GPU node association. |
| //! \details Create GPU node association. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param MOS_MEDIA_OPERATION MediaOperation |
| //! [in] Media operation |
| //! \param MOS_GPU_NODE *pVideoNodeOrdinal |
| //! [out] VCS node ordinal |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, otherwise error code |
| //! |
| MOS_STATUS Mos_Specific_CreateVideoNodeAssociation( |
| PMOS_INTERFACE pOsInterface, |
| int32_t bSetVideoNode, |
| MOS_GPU_NODE *pVideoNodeOrdinal) |
| { |
| PMOS_OS_CONTEXT pOsContext; |
| PVDBOX_WORKLOAD pVDBoxWorkLoad = nullptr; |
| MOS_STATUS eStatus = MOS_STATUS_SUCCESS; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pVideoNodeOrdinal); |
| |
| pOsContext = pOsInterface->pOsContext; |
| |
| if (false == pOsContext->bKMDHasVCS2) |
| { |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO; |
| goto finish; |
| } |
| |
| // If node selection is forced or we have only one VDBox, turn balancing off. |
| // After that check debug flags. |
| if (pOsInterface->bEnableVdboxBalancing) |
| { |
| pOsContext->bPerCmdBufferBalancing = !bSetVideoNode && pOsContext->bKMDHasVCS2 && pOsInterface->pfnGetVdboxNodeId; |
| } |
| else |
| { |
| pOsContext->bPerCmdBufferBalancing = 0; |
| } |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if (pOsInterface->eForceVdbox == MOS_FORCE_VDBOX_1) |
| { |
| bSetVideoNode = true; |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO; |
| pOsContext->bPerCmdBufferBalancing = 0; |
| } |
| else if (pOsInterface->eForceVdbox == MOS_FORCE_VDBOX_2) |
| { |
| bSetVideoNode = true; |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO2; |
| pOsContext->bPerCmdBufferBalancing = 0; |
| } |
| #endif // _DEBUG || _RELEASE_INTERNAL |
| |
| if (pOsContext->semid == MOS_LINUX_IPC_INVALID_ID) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid semid in OsContext."); |
| eStatus = MOS_STATUS_UNKNOWN; |
| goto finish; |
| } |
| |
| LockSemaphore(pOsContext->semid); |
| |
| pVDBoxWorkLoad = (PVDBOX_WORKLOAD)pOsContext->pShm; |
| MOS_OS_ASSERT(pVDBoxWorkLoad); |
| |
| if (bSetVideoNode) |
| { |
| if (*pVideoNodeOrdinal == MOS_GPU_NODE_VIDEO) |
| { |
| pVDBoxWorkLoad->uiVDBoxCount[0]++; |
| } |
| else if (*pVideoNodeOrdinal == MOS_GPU_NODE_VIDEO2) |
| { |
| pVDBoxWorkLoad->uiVDBoxCount[1]++; |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("VDBoxWorkLoad not set."); |
| } |
| } |
| else |
| { |
| if (pVDBoxWorkLoad->uiVDBoxCount[0] < pVDBoxWorkLoad->uiVDBoxCount[1]) |
| { |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO; |
| pVDBoxWorkLoad->uiVDBoxCount[0]++; |
| } |
| else if (pVDBoxWorkLoad->uiVDBoxCount[0] == pVDBoxWorkLoad->uiVDBoxCount[1]) |
| { |
| // this ping-pong method improves much performance for multi-session HD to HD xcode |
| if (pVDBoxWorkLoad->uiRingIndex == 0) |
| { |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO; |
| pVDBoxWorkLoad->uiVDBoxCount[0]++; |
| pVDBoxWorkLoad->uiRingIndex = 1; |
| } |
| else |
| { |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO2; |
| pVDBoxWorkLoad->uiVDBoxCount[1]++; |
| pVDBoxWorkLoad->uiRingIndex = 0; |
| } |
| } |
| else |
| { |
| *pVideoNodeOrdinal = MOS_GPU_NODE_VIDEO2; |
| pVDBoxWorkLoad->uiVDBoxCount[1]++; |
| } |
| } |
| |
| UnLockSemaphore(pOsContext->semid); |
| |
| finish: |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Destroy GPU node association. |
| //! \details Destroy GPU node association. |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param MOS_GPU_NODE VideoNodeOrdinal |
| //! [in] VCS node ordinal |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if success, otherwise error code |
| //! |
| MOS_STATUS Mos_Specific_DestroyVideoNodeAssociation( |
| PMOS_INTERFACE pOsInterface, |
| MOS_GPU_NODE VideoNodeOrdinal) |
| { |
| PMOS_OS_CONTEXT pOsContext = nullptr; |
| PVDBOX_WORKLOAD pVDBoxWorkLoad = nullptr; |
| |
| MOS_OS_FUNCTION_ENTER; |
| MOS_OS_CHK_NULL_RETURN(pOsInterface); |
| MOS_OS_CHK_NULL_RETURN(pOsInterface->pOsContext); |
| pOsContext = pOsInterface->pOsContext; |
| |
| // not do workload balancing in UMD just return; |
| if (pOsContext->bKMDHasVCS2 == false) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| if (pOsContext->semid == MOS_LINUX_IPC_INVALID_ID) |
| { |
| MOS_OS_ASSERTMESSAGE("Invalid semid in OsContext."); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| LockSemaphore(pOsContext->semid); |
| |
| pVDBoxWorkLoad = (PVDBOX_WORKLOAD)pOsContext->pShm; |
| MOS_OS_ASSERT(pVDBoxWorkLoad); |
| |
| if (VideoNodeOrdinal == MOS_GPU_NODE_VIDEO) |
| { |
| pVDBoxWorkLoad->uiVDBoxCount[0]--; |
| } |
| else |
| { |
| pVDBoxWorkLoad->uiVDBoxCount[1]--; |
| } |
| |
| UnLockSemaphore(pOsContext->semid); |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| #endif |
| |
| MOS_VDBOX_NODE_IND Mos_Specific_GetVdboxNodeId( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_COMMAND_BUFFER pCmdBuffer) |
| { |
| MOS_VDBOX_NODE_IND idx = MOS_VDBOX_NODE_INVALID; |
| |
| MOS_OS_CHK_NULL_NO_STATUS(pCmdBuffer); |
| MOS_OS_CHK_NULL_NO_STATUS(pOsInterface); |
| MOS_OS_CHK_NULL_NO_STATUS(pOsInterface->pOsContext); |
| |
| // If we have assigned vdbox index for the given cmdbuf, return it immediately |
| if (MOS_VDBOX_NODE_INVALID != pCmdBuffer->iVdboxNodeIndex) { |
| idx = pCmdBuffer->iVdboxNodeIndex; |
| return idx; |
| } |
| |
| finish: |
| return idx; |
| } |
| |
| //! |
| //! \brief Get the memory object |
| //! \details Get the memory object for cache policy |
| //! \param MOS_HW_RESOURCE_DEF MosUsage |
| //! [in] HW resource |
| //! [in] Gmm client context |
| //! \return MEMORY_OBJECT_CONTROL_STATE |
| //! Return the memory object |
| //! |
| MEMORY_OBJECT_CONTROL_STATE Mos_Specific_CachePolicyGetMemoryObject( |
| MOS_HW_RESOURCE_DEF MosUsage, |
| GMM_CLIENT_CONTEXT *pGmmClientContext) |
| { |
| // Force convert to stream handle for wrapper |
| return MosInterface::GetCachePolicyMemoryObject((MOS_STREAM_HANDLE)pGmmClientContext, MosUsage); |
| } |
| |
| //! |
| //! \brief Get the L1 config |
| //! \details Get the L1 config for cache policy |
| //! \param MOS_HW_RESOURCE_DEF MosUsage |
| //! [in] HW resource |
| //! [in] Gmm client context |
| //! \return uint8_t |
| //! L1_CACHE_CONTROL |
| //! |
| uint8_t Mos_Specific_CachePolicyGetL1Config( |
| MOS_HW_RESOURCE_DEF MosUsage, |
| GMM_CLIENT_CONTEXT *pGmmClientContext) |
| { |
| return 0; |
| } |
| |
| |
| //*----------------------------------------------------------------------------- |
| //| Purpose : Loads library |
| //| Returns : Instance to handle |
| //*----------------------------------------------------------------------------- |
| //! |
| //! \brief |
| //! \details |
| //! \param const char *pFileName |
| //! \return HINSTANCE |
| //! |
| MOS_STATUS Mos_Specific_LoadLibrary( |
| PMOS_INTERFACE pOsInterface, |
| PCCHAR pFileName, |
| void **ppvModule) |
| { |
| char *error; |
| MOS_UNUSED(pOsInterface); |
| //--------------------------------- |
| MOS_OS_ASSERT(pFileName); |
| //--------------------------------- |
| |
| return MosInterface::MosLoadLibrary(nullptr, pFileName, ppvModule); |
| } |
| |
| //*----------------------------------------------------------------------------- |
| //| Purpose : Frees library |
| //| Returns : Result of the operation |
| //*----------------------------------------------------------------------------- |
| //! |
| //! \brief |
| //! \details |
| //! \param HINSTANCE hInstance |
| //! \return MOS_STATUS |
| //! |
| MOS_STATUS Mos_Specific_FreeLibrary( |
| void *hInstance) |
| { |
| int32_t bStatus; |
| |
| //--------------------------------- |
| MOS_OS_ASSERT(hInstance); |
| //--------------------------------- |
| |
| return MosInterface::MosFreeLibrary(hInstance); |
| } |
| |
| //! |
| //! \brief Determines if the GPU Hung |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \return int32_t |
| //! Return if the GPU Hung |
| //! |
| int32_t Mos_Specific_IsGPUHung( |
| PMOS_INTERFACE pOsInterface) |
| { |
| uint32_t dwResetCount = 0; |
| uint32_t dwActiveBatch = 0; |
| uint32_t dwPendingBatch = 0; |
| int32_t bResult = false; |
| int32_t ret = 0; |
| |
| if (pOsInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Mos_Specific_IsGPUHung: pOsInterface == NULL"); |
| return false; |
| } |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::IsGPUHung(pOsInterface->osStreamState); |
| } |
| |
| dwResetCount = dwActiveBatch = dwPendingBatch = 0; |
| |
| ret = mos_get_reset_stats(pOsInterface->pOsContext->intel_context, &dwResetCount, |
| &dwActiveBatch, &dwPendingBatch); |
| if (ret) |
| { |
| MOS_OS_NORMALMESSAGE("mos_get_reset_stats return error(%d)\n", ret); |
| goto finish; |
| } |
| |
| if (dwResetCount != pOsInterface->dwGPUResetCount || |
| dwActiveBatch != pOsInterface->dwGPUActiveBatch || |
| dwPendingBatch != pOsInterface->dwGPUPendingBatch) |
| { |
| pOsInterface->dwGPUResetCount = dwResetCount; |
| pOsInterface->dwGPUActiveBatch = dwActiveBatch; |
| pOsInterface->dwGPUPendingBatch = dwPendingBatch; |
| bResult = true; |
| } |
| |
| finish: |
| return bResult; |
| } |
| |
| uint64_t Mos_Specific_GetAuxTableBaseAddr( |
| PMOS_INTERFACE osInterface) |
| { |
| if (osInterface == nullptr || osInterface->osContextPtr == nullptr) |
| { |
| MOS_OS_NORMALMESSAGE("Invalid osInterface"); |
| return 0; |
| } |
| auto osCtx = static_cast<OsContextSpecific *>(osInterface->osContextPtr); |
| AuxTableMgr *auxTableMgr = osCtx->GetAuxTableMgr(); |
| |
| return auxTableMgr ? auxTableMgr->GetAuxTableBase() : 0; |
| } |
| |
| //! |
| //! \brief Get gpu context priority from KMD |
| //! \param [in] pOsInterface |
| //! Pointer to OS interface |
| //! \param [out] pPriority |
| //! the priority of the current context. |
| //! |
| void Mos_Specific_GetGpuPriority( |
| PMOS_INTERFACE pOsInterface, |
| int32_t* pPriority) |
| { |
| MOS_OS_ASSERT(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::GetGpuPriority(pOsInterface->osStreamState, pPriority); |
| } |
| |
| if (pOsInterface->osContextPtr) |
| { |
| auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| osCxtSpecific->GetGpuPriority(pPriority); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("OS context is nullptr."); |
| } |
| } |
| |
| //! |
| //! \brief Set gpu priority to KMD |
| //! \param [in] pOsInterface |
| //! Pointer to OS interface |
| //! \param [in] priority |
| //! the priority set to current context. |
| //! |
| void Mos_Specific_SetGpuPriority( |
| PMOS_INTERFACE pOsInterface, |
| int32_t priority) |
| { |
| MOS_OS_ASSERT(pOsInterface); |
| |
| if (pOsInterface->apoMosEnabled) |
| { |
| return MosInterface::SetGpuPriority(pOsInterface->osStreamState, priority); |
| } |
| |
| if (pOsInterface->osContextPtr) |
| { |
| auto osCxtSpecific = static_cast<OsContextSpecific*>(pOsInterface->osContextPtr); |
| osCxtSpecific->SetGpuPriority(priority); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("OS context is nullptr."); |
| } |
| } |
| |
| //! |
| //! \brief Set slice count to shared memory and KMD |
| //! \param [in] pOsInterface |
| //! Pointer to OS interface |
| //! \param [in,out] pSliceCount |
| //! Pointer to the slice count. Input the slice count for current |
| //! context, output the ruling slice count shared by all contexts. |
| //! |
| void Mos_Specific_SetSliceCount( |
| PMOS_INTERFACE pOsInterface, |
| uint32_t *pSliceCount) |
| { |
| MOS_OS_ASSERT(pOsInterface); |
| MOS_OS_ASSERT(pSliceCount); |
| |
| if (pOsInterface->osContextPtr) |
| { |
| pOsInterface->osContextPtr->SetSliceCount(pSliceCount); |
| } |
| else |
| { |
| MOS_OS_ASSERTMESSAGE("OS context is nullptr."); |
| } |
| } |
| |
| //! |
| //! \brief |
| //! \details |
| //! \param const char *pFileName |
| //! \return HINSTANCE |
| //! |
| void Mos_Specific_LogData( |
| char *pData) |
| { |
| MOS_UNUSED(pData); |
| return; |
| } |
| |
| void Mos_Specific_NotifyStreamIndexSharing( |
| PMOS_INTERFACE pOsInterface) |
| { |
| MOS_UNUSED(pOsInterface); |
| } |
| |
| MOS_STATUS Mos_Specific_CheckVirtualEngineSupported( |
| PMOS_INTERFACE pOsResource) |
| { |
| auto skuTable = pOsResource->pfnGetSkuTable(pOsResource); |
| MOS_OS_CHK_NULL_RETURN(skuTable); |
| if (MEDIA_IS_SKU(skuTable, FtrContextBasedScheduling)) |
| { |
| pOsResource->bSupportVirtualEngine = true; |
| } |
| else |
| { |
| pOsResource->bSupportVirtualEngine = false; |
| } |
| |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| static MOS_STATUS Mos_Specific_InitInterface_Ve( |
| PMOS_INTERFACE osInterface) |
| { |
| PLATFORM Platform; |
| MOS_STATUS eStatus; |
| MOS_USER_FEATURE_VALUE_DATA userFeatureData; |
| MOS_STATUS eStatusUserFeature; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| eStatusUserFeature = MOS_STATUS_SUCCESS; |
| |
| // Get platform information |
| memset(&Platform, 0, sizeof(PLATFORM)); |
| if (!Mos_Solo_IsEnabled(nullptr)) |
| { |
| osInterface->pfnGetPlatform(osInterface, &Platform); |
| } |
| |
| if (GFX_IS_GEN_11_OR_LATER(Platform) || Mos_Solo_IsEnabled(nullptr)) |
| { |
| //keep this as false until VE is enabled by all media components |
| osInterface->bSupportVirtualEngine = false; |
| osInterface->bUseHwSemaForResSyncInVE = false; |
| osInterface->pVEInterf = nullptr; |
| osInterface->VEEnable = false; |
| |
| auto skuTable = osInterface->pfnGetSkuTable(osInterface); |
| MOS_OS_CHK_NULL_RETURN(skuTable); |
| if (MEDIA_IS_SKU(skuTable, FtrGucSubmission)) |
| { |
| osInterface->bGucSubmission = true; |
| } |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| //Read Scalable/Legacy Decode mode on Gen11+ |
| //1:by default for scalable decode mode |
| //0:for legacy decode mode |
| MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); |
| eStatusUserFeature = MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_ENABLE_HCP_SCALABILITY_DECODE_ID, |
| &userFeatureData, |
| nullptr); |
| osInterface->bHcpDecScalabilityMode = userFeatureData.u32Data ? MOS_SCALABILITY_ENABLE_MODE_DEFAULT : MOS_SCALABILITY_ENABLE_MODE_FALSE; |
| if(osInterface->bHcpDecScalabilityMode |
| && (eStatusUserFeature == MOS_STATUS_SUCCESS)) |
| { |
| //user's value to enable scalability |
| osInterface->bHcpDecScalabilityMode = MOS_SCALABILITY_ENABLE_MODE_USER_FORCE; |
| } |
| |
| osInterface->frameSplit = false; |
| MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_ENABLE_LINUX_FRAME_SPLIT_ID, |
| &userFeatureData, |
| nullptr); |
| osInterface->frameSplit = (uint32_t)userFeatureData.i32Data; |
| |
| MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_ENABLE_GUC_SUBMISSION_ID, |
| &userFeatureData, |
| nullptr); |
| osInterface->bGucSubmission = osInterface->bGucSubmission && ((uint32_t)userFeatureData.i32Data); |
| |
| // read the "Force VEBOX" user feature key |
| // 0: not force |
| MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_FORCE_VEBOX_ID, |
| &userFeatureData, |
| nullptr); |
| osInterface->eForceVebox = (MOS_FORCE_VEBOX)userFeatureData.u32Data; |
| |
| //KMD Virtual Engine DebugOverride |
| // 0: not Override |
| MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_ENABLE_VE_DEBUG_OVERRIDE_ID, |
| &userFeatureData, |
| nullptr); |
| osInterface->bEnableDbgOvrdInVE = userFeatureData.u32Data ? true : false; |
| #endif |
| |
| // UMD Vebox Virtual Engine Scalability Mode |
| // 0: disable. can set to 1 only when KMD VE is enabled. |
| MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); |
| eStatusUserFeature = MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_ENABLE_VEBOX_SCALABILITY_MODE_ID, |
| &userFeatureData, |
| nullptr); |
| osInterface->bVeboxScalabilityMode = userFeatureData.u32Data ? MOS_SCALABILITY_ENABLE_MODE_DEFAULT : MOS_SCALABILITY_ENABLE_MODE_FALSE; |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| if(osInterface->bVeboxScalabilityMode |
| && (eStatusUserFeature == MOS_STATUS_SUCCESS)) |
| { |
| //user's value to enable scalability |
| osInterface->bVeboxScalabilityMode = MOS_SCALABILITY_ENABLE_MODE_USER_FORCE; |
| |
| if (osInterface->eForceVebox == MOS_FORCE_VEBOX_NONE) |
| { |
| osInterface->eForceVebox = MOS_FORCE_VEBOX_1_2; |
| } |
| } |
| else if ((!osInterface->bVeboxScalabilityMode) |
| && (eStatusUserFeature == MOS_STATUS_SUCCESS)) |
| { |
| osInterface->eForceVebox = MOS_FORCE_VEBOX_NONE; |
| } |
| |
| // read the "Force VEBOX" user feature key |
| // 0: not force |
| MOS_ZeroMemory(&userFeatureData, sizeof(userFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| NULL, |
| __MEDIA_USER_FEATURE_VALUE_FORCE_VEBOX_ID, |
| &userFeatureData, |
| nullptr); |
| osInterface->eForceVebox = (MOS_FORCE_VEBOX)userFeatureData.u32Data; |
| #endif |
| } |
| |
| return eStatus; |
| } |
| |
| //! \brief Unified OS Initializes OS Linux Interface |
| //! \details Linux OS Interface initilization |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] Pointer to OS Interface |
| //! \param PMOS_CONTEXT pOsDriverContext |
| //! [in] Pointer to Driver context |
| //! \return MOS_STATUS |
| //! Return MOS_STATUS_SUCCESS if successful, otherwise failed |
| //! |
| MOS_STATUS Mos_Specific_InitInterface( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_CONTEXT pOsDriverContext) |
| { |
| PMOS_OS_CONTEXT pOsContext = nullptr; |
| PMOS_USER_FEATURE_INTERFACE pOsUserFeatureInterface = nullptr; |
| MOS_STATUS eStatus; |
| MediaFeatureTable *pSkuTable = nullptr; |
| MOS_USER_FEATURE_VALUE_DATA UserFeatureData; |
| uint32_t dwResetCount = 0; |
| int32_t ret = 0; |
| bool modularizedGpuCtxEnabled = false; |
| char *pMediaWatchdog = nullptr; |
| long int watchdog = 0; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| eStatus = MOS_STATUS_UNKNOWN; |
| MOS_OS_CHK_NULL(pOsInterface); |
| MOS_OS_CHK_NULL(pOsDriverContext); |
| pOsContext = nullptr; |
| pOsUserFeatureInterface = (PMOS_USER_FEATURE_INTERFACE)&pOsInterface->UserFeatureInterface; |
| MOS_OS_CHK_NULL(pOsUserFeatureInterface); |
| |
| MOS_OS_NORMALMESSAGE("mm:Mos_Specific_InitInterface called."); |
| |
| pOsInterface->modularizedGpuCtxEnabled = true; |
| pOsInterface->veDefaultEnable = true; |
| pOsInterface->phasedSubmission = true; |
| |
| pOsInterface->apoMosEnabled = pOsDriverContext->m_apoMosEnabled; |
| if (pOsInterface->apoMosEnabled) |
| { |
| pOsInterface->streamStateIniter = true; |
| MOS_OS_CHK_STATUS(MosInterface::CreateOsStreamState( |
| &pOsInterface->osStreamState, |
| (MOS_DEVICE_HANDLE)pOsDriverContext->m_osDeviceContext, |
| (MOS_INTERFACE_HANDLE)pOsInterface, |
| pOsInterface->Component, |
| pOsDriverContext)); |
| |
| // Set interface functions for legacy HAL |
| pOsContext = (PMOS_OS_CONTEXT)pOsInterface->osStreamState->perStreamParameters; |
| MOS_OS_CHK_NULL_RETURN(pOsContext); |
| |
| pOsContext->GetGPUTag = Linux_GetGPUTag; |
| } |
| else |
| { |
| // Create Linux OS Context |
| pOsContext = (PMOS_OS_CONTEXT)MOS_AllocAndZeroMemory(sizeof(MOS_OS_CONTEXT)); |
| MOS_OS_CHK_NULL_RETURN(pOsContext); |
| |
| if (GMM_SUCCESS != OpenGmm(&pOsContext->GmmFuncs)) |
| { |
| MOS_OS_ASSERTMESSAGE("Unable to open gmm"); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| } |
| |
| if (pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(nullptr)) |
| { |
| OsContext *osContextPtr = OsContext::GetOsContextObject(); |
| if (osContextPtr == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("Unable to get the active OS context."); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| |
| pOsInterface->osContextPtr = osContextPtr; |
| |
| if (pOsInterface->osContextPtr->GetOsContextValid() == false) |
| { |
| eStatus = pOsInterface->osContextPtr->Init(pOsDriverContext); |
| if (MOS_STATUS_SUCCESS != eStatus) |
| { |
| MOS_OS_ASSERTMESSAGE("Unable to initialize MODS context."); |
| eStatus = MOS_STATUS_INVALID_PARAMETER; |
| goto finish; |
| } |
| } |
| |
| //ApoMos do it in CreateOsStreamState |
| if (!pOsInterface->apoMosEnabled) |
| { |
| OsContextSpecific *pOsContextSpecific = static_cast<OsContextSpecific *>(pOsInterface->osContextPtr); |
| pOsContext->intel_context = pOsContextSpecific->GetDrmContext(); |
| pOsContext->pGmmClientContext = pOsContext->GmmFuncs.pfnCreateClientContext((GMM_CLIENT)GMM_LIBVA_LINUX); |
| } |
| } |
| else |
| { |
| pOsContext->pGmmClientContext = pOsContext->GmmFuncs.pfnCreateClientContext((GMM_CLIENT)GMM_LIBVA_LINUX); |
| } |
| |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| #if MOS_MEDIASOLO_SUPPORTED |
| if (pOsInterface->bSoloInUse) |
| { |
| UserFeatureData.i32Data = pOsInterface->bSimIsActive; |
| UserFeatureData.i32DataFlag = MOS_USER_FEATURE_VALUE_DATA_FLAG_CUSTOM_DEFAULT_VALUE_TYPE; |
| } |
| #endif |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_SIM_ENABLE_ID, |
| &UserFeatureData, |
| nullptr); |
| #endif |
| pOsInterface->bSimIsActive = (int32_t)UserFeatureData.i32Data; |
| if (!pOsInterface->apoMosEnabled) |
| { |
| pOsContext->bSimIsActive = pOsInterface->bSimIsActive; |
| } |
| |
| // Initialize |
| if (!pOsInterface->apoMosEnabled) |
| { |
| modularizedGpuCtxEnabled = pOsInterface->modularizedGpuCtxEnabled && !Mos_Solo_IsEnabled(pOsContext); |
| eStatus = Linux_InitContext(pOsContext, pOsDriverContext, pOsInterface->modulizedMosEnabled && !Mos_Solo_IsEnabled(pOsContext), modularizedGpuCtxEnabled); |
| if( MOS_STATUS_SUCCESS != eStatus ) |
| { |
| MOS_OS_ASSERTMESSAGE("Unable to initialize context."); |
| goto finish; |
| } |
| |
| pOsContext->bFreeContext = true; |
| |
| //Added by Ben for video memory allocation |
| pOsContext->bufmgr = pOsDriverContext->bufmgr; |
| mos_bufmgr_gem_enable_reuse(pOsDriverContext->bufmgr); |
| } |
| |
| pOsInterface->pOsContext = pOsContext; |
| |
| pOsInterface->bUsesPatchList = true; |
| pOsInterface->bUsesGfxAddress = false; |
| pOsInterface->bNoParsingAssistanceInKmd = true; |
| pOsInterface->bUsesCmdBufHeaderInResize = false; |
| pOsInterface->bUsesCmdBufHeader = false; |
| pOsInterface->dwNumNalUnitBytesIncluded = MOS_NAL_UNIT_LENGTH - MOS_NAL_UNIT_STARTCODE_LENGTH; |
| |
| pOsInterface->bInlineCodecStatusUpdate = true; |
| pOsInterface->bAllowExtraPatchToSameLoc = false; |
| |
| // Initialize OS interface functions |
| pOsInterface->pfnSetGpuContext = Mos_Specific_SetGpuContext; |
| pOsInterface->pfnSetGpuContextFromHandle = Mos_Specific_SetGpuContextFromHandle; |
| pOsInterface->pfnGetGpuContext = Mos_Specific_GetGpuContext; |
| pOsInterface->pfnSetEncodePakContext = Mos_Specific_SetEncodePakContext; |
| pOsInterface->pfnSetEncodeEncContext = Mos_Specific_SetEncodeEncContext; |
| pOsInterface->pfnGetGmmClientContext = Mos_Specific_GetGmmClientContext; |
| |
| pOsInterface->pfnGetPlatform = Mos_Specific_GetPlatform; |
| pOsInterface->pfnDestroy = Mos_Specific_Destroy; |
| pOsInterface->pfnGetSkuTable = Mos_Specific_GetSkuTable; |
| pOsInterface->pfnGetWaTable = Mos_Specific_GetWaTable; |
| pOsInterface->pfnGetGtSystemInfo = Mos_Specific_GetGtSystemInfo; |
| pOsInterface->pfnGetMediaEngineInfo = Mos_Specific_GetMediaEngineInfo; |
| pOsInterface->pfnResetOsStates = Mos_Specific_ResetOsStates; |
| pOsInterface->pfnAllocateResource = Mos_Specific_AllocateResource; |
| pOsInterface->pfnGetResourceInfo = Mos_Specific_GetResourceInfo; |
| pOsInterface->pfnFreeResource = Mos_Specific_FreeResource; |
| pOsInterface->pfnFreeResourceWithFlag = Mos_Specific_FreeResourceWithFlag; |
| pOsInterface->pfnLockSyncRequest = Mos_Specific_LockSyncRequest; |
| pOsInterface->pfnLockResource = Mos_Specific_LockResource; |
| pOsInterface->pfnUnlockResource = Mos_Specific_UnlockResource; |
| pOsInterface->pfnDecompResource = Mos_Specific_DecompResource; |
| pOsInterface->pfnDoubleBufferCopyResource = Mos_Specific_DoubleBufferCopyResource; |
| pOsInterface->pfnMediaCopyResource2D = Mos_Specific_MediaCopyResource2D; |
| pOsInterface->pfnGetMosContext = Mos_Specific_GetMosContext; |
| pOsInterface->pfnUpdateResourceUsageType = Mos_Specific_UpdateResourceUsageType; |
| pOsInterface->pfnRegisterResource = Mos_Specific_RegisterResource; |
| pOsInterface->pfnResetResourceAllocationIndex = Mos_Specific_ResetResourceAllocationIndex; |
| pOsInterface->pfnGetResourceAllocationIndex = Mos_Specific_GetResourceAllocationIndex; |
| pOsInterface->pfnGetResourceGfxAddress = Mos_Specific_GetResourceGfxAddress; |
| pOsInterface->pfnGetCommandBuffer = Mos_Specific_GetCommandBuffer; |
| pOsInterface->pfnResetCommandBuffer = Mos_Specific_ResetCommandBuffer; |
| pOsInterface->pfnReturnCommandBuffer = Mos_Specific_ReturnCommandBuffer; |
| pOsInterface->pfnSubmitCommandBuffer = Mos_Specific_SubmitCommandBuffer; |
| pOsInterface->pfnWaitAndReleaseCmdBuffer = Mos_Specific_WaitAndReleaseCmdBuffer; |
| pOsInterface->pfnVerifyCommandBufferSize = Mos_Specific_VerifyCommandBufferSize; |
| pOsInterface->pfnResizeCommandBufferAndPatchList = Mos_Specific_ResizeCommandBufferAndPatchList; |
| pOsInterface->pfnFmt_OsToMos = Mos_Specific_FmtOsToMos; |
| pOsInterface->pfnFmt_MosToOs = Mos_Specific_FmtMosToOs; |
| pOsInterface->pfnFmt_MosToGmm = Mos_Specific_ConvertMosFmtToGmmFmt; |
| pOsInterface->pfnSetPerfTag = Mos_Specific_SetPerfTag; |
| pOsInterface->pfnResetPerfBufferID = Mos_Specific_ResetPerfBufferID; |
| pOsInterface->pfnIncPerfFrameID = Mos_Specific_IncPerfFrameID; |
| pOsInterface->pfnIncPerfBufferID = Mos_Specific_IncPerfBufferID; |
| pOsInterface->pfnGetPerfTag = Mos_Specific_GetPerfTag; |
| pOsInterface->pfnSetPerfHybridKernelID = Mos_Specific_SetPerfHybridKernelID; |
| pOsInterface->pfnIsPerfTagSet = Mos_Specific_IsPerfTagSet; |
| pOsInterface->pfnSetIndirectStateSize = Mos_Specific_SetIndirectStateSize; |
| pOsInterface->pfnGetIndirectState = Mos_Specific_GetIndirectState; |
| pOsInterface->pfnGetIndirectStatePointer = Mos_Specific_GetIndirectStatePointer; |
| pOsInterface->pfnSetPatchEntry = Mos_Specific_SetPatchEntry; |
| |
| pOsInterface->pfnLoadLibrary = Mos_Specific_LoadLibrary; |
| pOsInterface->pfnFreeLibrary = Mos_Specific_FreeLibrary; |
| pOsInterface->pfnLogData = Mos_Specific_LogData; |
| pOsInterface->pfnCheckVirtualEngineSupported = Mos_Specific_CheckVirtualEngineSupported; |
| |
| //GPU context and synchronization functions |
| pOsInterface->pfnCreateGpuContext = Mos_Specific_CreateGpuContext; |
| pOsInterface->pfnCreateGpuComputeContext = Mos_Specific_CreateGpuComputeContext; |
| pOsInterface->pfnDestroyGpuContext = Mos_Specific_DestroyGpuContext; |
| pOsInterface->pfnDestroyGpuComputeContext = Mos_Specific_DestroyGpuComputeContext; |
| pOsInterface->pfnIsGpuContextValid = Mos_Specific_IsGpuContextValid; |
| pOsInterface->pfnSyncOnResource = Mos_Specific_SyncOnResource; |
| pOsInterface->pfnSyncGpuContext = Mos_Specific_SyncGpuContext; |
| pOsInterface->pfnSyncWith3DContext = Mos_Specific_SyncWith3DContext; |
| pOsInterface->pfnGetGpuStatusBufferResource = Mos_Specific_GetGpuStatusBufferResource; |
| pOsInterface->pfnGetGpuStatusTagOffset = Mos_Specific_GetGpuStatusTagOffset; |
| pOsInterface->pfnGetGpuStatusTag = Mos_Specific_GetGpuStatusTag; |
| pOsInterface->pfnIncrementGpuStatusTag = Mos_Specific_IncrementGpuStatusTag; |
| pOsInterface->pfnGetGpuStatusSyncTag = Mos_Specific_GetGpuStatusSyncTag; |
| pOsInterface->pfnSetResourceSyncTag = Mos_Specific_SetResourceSyncTag; |
| pOsInterface->pfnPerformOverlaySync = Mos_Specific_PerformOverlaySync; |
| pOsInterface->pfnEngineSignal = Mos_Specific_EngineSignal; |
| pOsInterface->pfnEngineWait = Mos_Specific_EngineWait; |
| pOsInterface->pfnWaitAllCmdCompletion = Mos_Specific_WaitAllCmdCompletion_Os; |
| pOsInterface->pfnResourceSignal = Mos_Specific_ResourceSignal; |
| pOsInterface->pfnResourceWait = Mos_Specific_ResourceWait; |
| pOsInterface->pfnCreateSyncResource = Mos_Specific_CreateSyncResource; |
| pOsInterface->pfnDestroySyncResource = Mos_Specific_DestroySyncResource; |
| pOsInterface->pfnInitializeMultiThreadingSyncTags = Mos_Specific_InitializeMultiThreadingSyncTags; |
| pOsInterface->pfnMultiThreadingWaitCurrentFrame = Mos_Specific_MultiThreadingWaitCurrentFrame; |
| pOsInterface->pfnMultiThreadingPostCurrentFrame = Mos_Specific_MultiThreadingPostCurrentFrame; |
| pOsInterface->pfnSetHybridDecoderRunningFlag = Mos_Specific_SetHybridDecoderRunningFlag; |
| pOsInterface->pfnGetHybridDecoderRunningFlag = Mos_Specific_GetHybridDecoderRunningFlag; |
| pOsInterface->pfnMultiThreadResourceSync = Mos_Specific_MultiThreadResourceSync; |
| |
| pOsInterface->pfnCachePolicyGetMemoryObject = Mos_Specific_CachePolicyGetMemoryObject; |
| pOsInterface->pfnVerifyPatchListSize = Mos_Specific_VerifyPatchListSize; |
| pOsInterface->pfnGetMemoryCompressionMode = Mos_Specific_GetMemoryCompressionMode; |
| pOsInterface->pfnSetMemoryCompressionMode = Mos_Specific_SetMemoryCompressionMode; |
| pOsInterface->pfnSetMemoryCompressionHint = Mos_Specific_SetMemoryCompressionHint; |
| pOsInterface->pfnGetMemoryCompressionFormat = Mos_Specific_GetMemoryCompressionFormat; |
| pOsInterface->pfnCreateVideoNodeAssociation = Mos_Specific_CreateVideoNodeAssociation; |
| pOsInterface->pfnDestroyVideoNodeAssociation = Mos_Specific_DestroyVideoNodeAssociation; |
| pOsInterface->pfnGetVdboxNodeId = Mos_Specific_GetVdboxNodeId; |
| |
| pOsInterface->pfnGetNullHWRenderFlags = Mos_Specific_GetNullHWRenderFlags; |
| pOsInterface->pfnSetCmdBufferDebugInfo = Mos_Specific_SetCmdBufferDebugInfo; |
| pOsInterface->pfnGetCmdBufferDebugInfo = Mos_Specific_GetCmdBufferDebugInfo; |
| |
| pOsInterface->pfnRegisterBBCompleteNotifyEvent = Mos_Specific_RegisterBBCompleteNotifyEvent; |
| pOsInterface->pfnWaitForBBCompleteNotifyEvent = Mos_Specific_WaitForBBCompleteNotifyEvent; |
| pOsInterface->pfnCachePolicyGetMemoryObject = Mos_Specific_CachePolicyGetMemoryObject; |
| pOsInterface->pfnCachePolicyGetL1Config = Mos_Specific_CachePolicyGetL1Config; |
| pOsInterface->pfnSetCpuCacheability = Mos_Specific_SetCpuCacheability; |
| pOsInterface->pfnSkipResourceSync = Mos_Specific_SkipResourceSync; |
| pOsInterface->pfnIsGPUHung = Mos_Specific_IsGPUHung; |
| pOsInterface->pfnGetAuxTableBaseAddr = Mos_Specific_GetAuxTableBaseAddr; |
| pOsInterface->pfnSetSliceCount = Mos_Specific_SetSliceCount; |
| pOsInterface->pfnGetResourceIndex = Mos_Specific_GetResourceIndex; |
| pOsInterface->pfnSetSliceCount = Mos_Specific_SetSliceCount; |
| pOsInterface->pfnGetGpuPriority = Mos_Specific_GetGpuPriority; |
| pOsInterface->pfnSetGpuPriority = Mos_Specific_SetGpuPriority; |
| pOsInterface->pfnIsSetMarkerEnabled = Mos_Specific_IsSetMarkerEnabled; |
| pOsInterface->pfnGetMarkerResource = Mos_Specific_GetMarkerResource; |
| pOsInterface->pfnNotifyStreamIndexSharing = Mos_Specific_NotifyStreamIndexSharing; |
| |
| pOsInterface->pfnSetGpuContextHandle = Mos_Specific_SetGpuContextHandle; |
| pOsInterface->pfnGetGpuContextMgr = Mos_Specific_GetGpuContextMgr; |
| pOsInterface->pfnGetGpuContextbyHandle = Mos_Specific_GetGpuContextbyHandle; |
| |
| pOsUserFeatureInterface->bIsNotificationSupported = false; |
| pOsUserFeatureInterface->pOsInterface = pOsInterface; |
| |
| pOsUserFeatureInterface->pfnEnableNotification = MosUtilities::MosUserFeatureEnableNotification; |
| pOsUserFeatureInterface->pfnDisableNotification = MosUtilities::MosUserFeatureDisableNotification; |
| pOsUserFeatureInterface->pfnParsePath = MosUtilities::MosUserFeatureParsePath; |
| |
| // Init reset count for the context |
| ret = mos_get_reset_stats(pOsInterface->pOsContext->intel_context, &dwResetCount, nullptr, nullptr); |
| if (ret) |
| { |
| MOS_OS_NORMALMESSAGE("mos_get_reset_stats return error(%d)\n", ret); |
| dwResetCount = 0; |
| } |
| pOsInterface->dwGPUResetCount = dwResetCount; |
| pOsInterface->dwGPUActiveBatch = 0; |
| pOsInterface->dwGPUPendingBatch = 0; |
| |
| // disable it on Linux |
| pOsInterface->bMediaReset = false; |
| pOsInterface->umdMediaResetEnable = false; |
| |
| pMediaWatchdog = getenv("INTEL_MEDIA_RESET_WATCHDOG"); |
| if (pMediaWatchdog != nullptr) |
| { |
| watchdog = strtol(pMediaWatchdog, nullptr, 0); |
| if (watchdog == 1) |
| { |
| pOsInterface->bMediaReset = true; |
| pOsInterface->umdMediaResetEnable = true; |
| } |
| } |
| |
| // initialize MOS_CP interface |
| pOsInterface->osCpInterface = Create_MosCpInterface(pOsInterface); |
| if (pOsInterface->osCpInterface == nullptr) |
| { |
| MOS_OS_ASSERTMESSAGE("fail to create osCpInterface."); |
| return MOS_STATUS_UNKNOWN; |
| } |
| |
| // Check SKU table to detect if simulation environment (HAS) is enabled |
| pSkuTable = pOsInterface->pfnGetSkuTable(pOsInterface); |
| MOS_OS_CHK_NULL(pSkuTable); |
| |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| // read the "Force VDBOX" user feature key |
| // 0: not force |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_FORCE_VDBOX_ID, |
| &UserFeatureData, |
| nullptr); |
| pOsInterface->eForceVdbox = UserFeatureData.u32Data; |
| |
| // Force TileYf/Ys |
| // 0: Tile Y 1: Tile Yf 2 Tile Ys |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_FORCE_YFYS_ID, |
| &UserFeatureData, |
| nullptr); |
| pOsInterface->dwForceTileYfYs = (uint32_t)UserFeatureData.i32Data; |
| |
| // Null HW Driver |
| // 0: Disable |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| MOS_USER_FEATURE_INVALID_KEY_ASSERT(MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_NULL_HW_ACCELERATION_ENABLE_ID, |
| &UserFeatureData, |
| nullptr)); |
| pOsInterface->NullHWAccelerationEnable.Value = UserFeatureData.u32Data; |
| #endif // (_DEBUG || _RELEASE_INTERNAL) |
| |
| #if MOS_MEDIASOLO_SUPPORTED |
| Mos_Solo_Initialize(pOsInterface); |
| #endif // MOS_MEDIASOLO_SUPPORTED |
| if (!pOsInterface->apoMosEnabled) |
| { |
| // read the "Disable KMD Watchdog" user feature key |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_DISABLE_KMD_WATCHDOG_ID, |
| &UserFeatureData, |
| nullptr); |
| pOsContext->bDisableKmdWatchdog = (UserFeatureData.i32Data) ? true : false; |
| |
| // read "Linux PerformanceTag Enable" user feature key |
| MOS_ZeroMemory(&UserFeatureData, sizeof(UserFeatureData)); |
| MOS_UserFeature_ReadValue_ID( |
| nullptr, |
| __MEDIA_USER_FEATURE_VALUE_LINUX_PERFORMANCETAG_ENABLE_ID, |
| &UserFeatureData, |
| nullptr); |
| pOsContext->uEnablePerfTag = UserFeatureData.i32Data; |
| } |
| eStatus = Mos_Specific_InitInterface_Ve(pOsInterface); |
| if(eStatus != MOS_STATUS_SUCCESS) |
| { |
| goto finish; |
| } |
| |
| eStatus = MOS_STATUS_SUCCESS; |
| |
| finish: |
| if( MOS_STATUS_SUCCESS != eStatus && nullptr != pOsContext ) |
| { |
| MOS_FreeMemAndSetNull(pOsContext); |
| } |
| return eStatus; |
| } |
| |
| //! |
| //! \brief Check if OS resource is nullptr |
| //! \details Check if OS resource is nullptr |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS Resource |
| //! \return int32_t |
| //! Return true if nullptr, otherwise false |
| //! |
| int32_t Mos_ResourceIsNull( |
| PMOS_RESOURCE pOsResource) |
| { |
| //--------------------- |
| if( nullptr == pOsResource ) |
| { |
| MOS_OS_ASSERTMESSAGE("found pOsResource nullptr\n"); |
| return true; |
| } |
| //--------------------- |
| |
| return ((pOsResource->bo == nullptr) |
| #if (_DEBUG || _RELEASE_INTERNAL) |
| && ((pOsResource->pData == nullptr) ) |
| #endif // (_DEBUG || _RELEASE_INTERNAL) |
| ); |
| |
| } |
| |
| //! |
| //! \brief OS reset resource |
| //! \details Resets the OS resource |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS Resource |
| //! \return void |
| //! Return NONE |
| //! |
| void Mos_ResetResource( |
| PMOS_RESOURCE pOsResource) |
| { |
| int32_t i; |
| |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsResource); |
| |
| MOS_ZeroMemory(pOsResource, sizeof(MOS_RESOURCE)); |
| pOsResource->Format = Format_None; |
| for (i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| pOsResource->iAllocationIndex[i] = MOS_INVALID_ALLOC_INDEX; |
| } |
| } |
| |
| //! |
| //! \brief Convert to MOS tile type |
| //! \details Convert from Linux to MOS tile type |
| //! \param uint32_t type |
| //! [in] tile type |
| //! \return MOS_TILE_TYPE |
| //! Return MOS tile type |
| //! |
| MOS_TILE_TYPE LinuxToMosTileType(uint32_t type) |
| { |
| switch (type) { |
| case I915_TILING_NONE: |
| return MOS_TILE_LINEAR; |
| case I915_TILING_X: |
| return MOS_TILE_X; |
| case I915_TILING_Y: |
| return MOS_TILE_Y; |
| default: |
| return MOS_TILE_INVALID; |
| } |
| }; |
| |
| //! |
| //! \brief Get resource index |
| //! \details Get resource index of MOS_RESOURCE |
| //! \param PMOS_RESOURCE osResource |
| //! [in] Pointer to OS resource |
| //! \return uint32_t |
| //! Resource index |
| //! |
| uint32_t Mos_Specific_GetResourceIndex( |
| PMOS_RESOURCE osResource) |
| { |
| return 0; |
| } |
| |
| uint32_t Mos_Specific_GetResourcePitch( |
| PMOS_RESOURCE pOsResource) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsResource); |
| |
| return pOsResource->iPitch; |
| } |
| |
| void Mos_Specific_SetResourceWidth( |
| PMOS_RESOURCE pOsResource, |
| uint32_t dwWidth) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsResource); |
| |
| pOsResource->iWidth = dwWidth; |
| } |
| |
| void Mos_Specific_SetResourceFormat( |
| PMOS_RESOURCE pOsResource, |
| MOS_FORMAT mosFormat) |
| { |
| MOS_OS_FUNCTION_ENTER; |
| |
| MOS_OS_ASSERT(pOsResource); |
| |
| pOsResource->Format = mosFormat; |
| } |
| |
| //! |
| //! \brief Get SetMarker enabled flag |
| //! \details Get SetMarker enabled flag from OsInterface |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \return bool |
| //! SetMarker enabled flag |
| //! |
| bool Mos_Specific_IsSetMarkerEnabled( |
| PMOS_INTERFACE pOsInterface) |
| { |
| return false; |
| } |
| |
| //! |
| //! \brief Get SetMarker resource address |
| //! \details Get SetMarker resource address from OsInterface |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \return PMOS_RESOURCE |
| //! SetMarker resource address |
| //! |
| PMOS_RESOURCE Mos_Specific_GetMarkerResource( |
| PMOS_INTERFACE pOsInterface) |
| { |
| return 0; |
| } |
| |
| //! |
| //! \brief Get TimeStamp frequency base |
| //! \details Get TimeStamp frequency base from OsInterface |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \return uint32_t |
| //! time stamp frequency base |
| //! |
| uint32_t Mos_Specific_GetTsFrequency(PMOS_INTERFACE osInterface) |
| { |
| #if defined(__linux__) |
| int32_t freq = 0; |
| drm_i915_getparam_t gp; |
| MOS_ZeroMemory(&gp, sizeof(gp)); |
| gp.param = I915_PARAM_CS_TIMESTAMP_FREQUENCY; |
| gp.value = &freq; |
| int ret = drmIoctl(osInterface->pOsContext->fd, DRM_IOCTL_I915_GETPARAM, &gp); |
| if(ret == 0) |
| { |
| return freq; |
| } |
| else |
| { |
| // fail to query it from KMD |
| return 0; |
| } |
| #else |
| fprintf(stderr, "%s:%d Mos_Specific_GetTsFrequency not implemented\n", __FILE__, __LINE__); |
| return 0; |
| #endif |
| } |
| |
| //! |
| //! \brief Checks whether the requested resource is releasable |
| //! \param PMOS_INTERFACE pOsInterface |
| //! [in] OS Interface |
| //! \param PMOS_RESOURCE pOsResource |
| //! [in] Pointer to OS Resource |
| //! \return MOS_STATUS |
| //! MOS_STATUS_SUCCESS if requested can be released, otherwise MOS_STATUS_UNKNOWN |
| //! |
| MOS_STATUS Mos_Specific_IsResourceReleasable( |
| PMOS_INTERFACE pOsInterface, |
| PMOS_RESOURCE pOsResource) |
| { |
| return MOS_STATUS_SUCCESS; |
| } |
| |
| MOS_USER_FEATURE_KEY_PATH_INFO *Mos_GetDeviceUfPathInfo( |
| PMOS_CONTEXT mosContext) |
| { |
| MOS_UNUSED(mosContext); |
| //NOT IMPLEMENTED |
| return nullptr; |
| } |
| |
| #if MOS_COMMAND_RESINFO_DUMP_SUPPORTED |
| struct GpuCmdResInfoDump::GpuCmdResInfo |
| { |
| int32_t iWidth; |
| int32_t iHeight; |
| int32_t iSize; |
| int32_t iPitch; |
| int32_t iDepth; |
| MOS_FORMAT Format; |
| int32_t iCount; |
| int32_t iAllocationIndex[MOS_GPU_CONTEXT_MAX]; |
| uint32_t dwGfxAddress; |
| const char *bufname; |
| uint32_t isTiled; |
| MOS_TILE_TYPE TileType; |
| uint32_t bMapped; |
| uint32_t name; |
| uint64_t user_provided_va; |
| bool bConvertedFromDDIResource; |
| }; |
| |
| void GpuCmdResInfoDump::StoreCmdResPtr(PMOS_INTERFACE pOsInterface, const void *pRes) const |
| { |
| if (!m_dumpEnabled) |
| { |
| return; |
| } |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_ASSERT(gpuContext != nullptr); |
| |
| auto pResTmp1 = (const MOS_RESOURCE *)(pRes); |
| auto pResTmp2 = (GpuCmdResInfo *)MOS_AllocMemory(sizeof(GpuCmdResInfo)); |
| |
| pResTmp2->iWidth = pResTmp1->iWidth; |
| pResTmp2->iHeight = pResTmp1->iHeight; |
| pResTmp2->iSize = pResTmp1->iSize; |
| pResTmp2->iPitch = pResTmp1->iPitch; |
| pResTmp2->iDepth = pResTmp1->iDepth; |
| pResTmp2->Format = pResTmp1->Format; |
| pResTmp2->iCount = pResTmp1->iCount; |
| for (auto i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| pResTmp2->iAllocationIndex[i] = pResTmp1->iAllocationIndex[i]; |
| } |
| pResTmp2->dwGfxAddress = pResTmp1->dwGfxAddress; |
| pResTmp2->bufname = pResTmp1->bufname; |
| pResTmp2->isTiled = pResTmp1->isTiled; |
| pResTmp2->TileType = pResTmp1->TileType; |
| pResTmp2->bMapped = pResTmp1->bMapped; |
| pResTmp2->name = pResTmp1->name; |
| pResTmp2->user_provided_va = pResTmp1->user_provided_va; |
| pResTmp2->bConvertedFromDDIResource = pResTmp1->bConvertedFromDDIResource; |
| |
| gpuContext->PushCmdResPtr((const void *)pResTmp2); |
| } |
| |
| void GpuCmdResInfoDump::ClearCmdResPtrs(PMOS_INTERFACE pOsInterface) const |
| { |
| if (!m_dumpEnabled) |
| { |
| return; |
| } |
| |
| auto gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_ASSERT(gpuContext != nullptr); |
| |
| auto &cmdResInfoPtrs = gpuContext->GetCmdResPtrs(); |
| |
| for (auto e : cmdResInfoPtrs) |
| { |
| MOS_FreeMemory((void *)e); |
| } |
| |
| gpuContext->ClearCmdResPtrs(); |
| } |
| |
| void GpuCmdResInfoDump::Dump(const void *cmdResInfoPtr, std::ofstream &outputFile) const |
| { |
| using std::endl; |
| |
| auto pRes = (const GpuCmdResInfo *)(cmdResInfoPtr); |
| |
| outputFile << "Gpu Resource Pointer : " << pRes << endl; |
| outputFile << "iWidth : " << pRes->iWidth << endl; |
| outputFile << "iHeight : " << pRes->iHeight << endl; |
| outputFile << "iSize : " << pRes->iSize << endl; |
| outputFile << "iPitch : " << pRes->iPitch << endl; |
| outputFile << "iDepth : " << pRes->iDepth << endl; |
| outputFile << "Format : " << (int32_t)pRes->Format << endl; |
| outputFile << "iCount : " << pRes->iCount << endl; |
| outputFile << "iAllocationIndex : "; |
| for (auto i = 0; i < MOS_GPU_CONTEXT_MAX; i++) |
| { |
| outputFile << pRes->iAllocationIndex[i] << " "; |
| } |
| outputFile << endl; |
| outputFile << "dwGfxAddress : " << pRes->dwGfxAddress << endl; |
| outputFile << "bufname : " << pRes->bufname << endl; |
| outputFile << "isTiled : " << pRes->isTiled << endl; |
| outputFile << "TileType : " << GetTileType(pRes->TileType) << endl; |
| outputFile << "bMapped : " << pRes->bMapped << endl; |
| outputFile << "name : " << pRes->name << endl; |
| outputFile << "user_provided_va : " << pRes->user_provided_va << endl; |
| outputFile << "bConvertedFromDDIResource : " << pRes->bConvertedFromDDIResource << endl; |
| outputFile << endl; |
| } |
| |
| const std::vector<const void *> &GpuCmdResInfoDump::GetCmdResPtrs(PMOS_INTERFACE pOsInterface) const |
| { |
| const auto *gpuContext = Linux_GetGpuContext(pOsInterface, pOsInterface->CurrentGpuContextHandle); |
| MOS_OS_ASSERT(gpuContext != nullptr); |
| |
| return gpuContext->GetCmdResPtrs(); |
| } |
| #endif // MOS_COMMAND_RESINFO_DUMP_SUPPORTED |