| /* |
| * 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 |
| |
| #if !defined(__Fuchsia__) |
| 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; |
| } |
| #endif |
| |
| 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; |
| } |
| |
| #if !defined(__Fuchsia__) |
| 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 |
| #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 !defined(__Fuchsia__) |
| if (pOsContext->bKMDHasVCS2) |
| { |
| DestroyIPC(pOsContext); |
| } |
| #endif |
| #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 !defined(__Fuchsia__) |
| if (pContext->bKMDHasVCS2) |
| { |
| eStatus = CreateIPC(pContext); |
| MOS_CHK_STATUS_SAFE(eStatus); |
| } |
| #endif |
| #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; |
| |